Scene isn't rendering - probably matrix issues?

Okay, well. First of all, this is the first time I’ve tried using vertex buffers with shaders, and for whatever reason, nothing is showing up when I set it to render the object.

Here’s my render() function:


float mvMat[16] = {	1, 0, 0, 0,
					0, 1, 0, 0,
					0, 0, 1, 0,
					0, 0, 50, 1	};
//mvMat is supposed to be an identity matrix translated 50 units forward

float projMat[16];

void Render(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (vbo != 0 && ibo != 0)
	{
		float mvpMat[16];

		m3dMatrixMultiply44(mvpMat, mvMat, projMat);

		glUseProgram(progFlatColor);
		glUniform4f(uniformColor, 1.0, 0.0, 1.0, 1.0);
		glUniformMatrix4fv(uniformMVP, 1, 0, mvpMat);

		// Draw the main object
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 20, (const GLvoid*)0);
	
		glDrawElements(GL_TRIANGLES, activeHeader.numTris, GL_UNSIGNED_SHORT, 0);
	

		// Draw the wireframe

		// Draw normals

		// Draw PhysX shapes

		// Draw bounding box/sphere

		printf("ERROR: %i
", glGetError());
	}

	SwapBuffers(g_hDC);
}

projMat is set up like so:

float fov = 70.0f;
			float aspect = (rcClient.right/iRenderHeight);
			float znear = 1.0f;
			float zfar = 100.0f;

			const float h = 1.0f/tan(fov*PI_OVER_360);
			float neg_depth = znear-zfar;
			projMat[0] = h / aspect;
			projMat[1] = 0;
			projMat[2] = 0;
			projMat[3] = 0;

			projMat[4] = 0;
			projMat[5] = h;
			projMat[6] = 0;
			projMat[7] = 0;

			projMat[8] = 0;
			projMat[9] = 0;
		    projMat[10] = (zfar + znear)/neg_depth;
			projMat[11] = -1;

			projMat[12] = 0;
			projMat[13] = 0;
			projMat[14] = 2.0f*(znear*zfar)/neg_depth;
			projMat[15] = 0;

And my SetupShaders() function looks like this:

unsigned long progFlatColor, progFlatTexture, progLitColor, progLitTexture;
int uniformColor, uniformMVP = -1;

bool DebugShader(unsigned int shader);
bool DebugProgram(unsigned int program);

const char VertSrcFlatColor[] = 
"\
//Flat Shader - Vertex
\
//Displays unshaded shapes using a uniform color
\
#version 120
\

\
uniform mat4 MVP;
\

\
attribute vec4 position;
\

\
void main(void)
\
{
\
gl_Position = (position * MVP);
\
}
\
\0";

const char FragSrcFlatColor[] =
"\
//Flat Shader - Fragment
\

\
uniform vec4 color;
\

\
void main(void)
\
{
\
gl_FragColor = color;
\
}
\
\0";

enum ShaderMode
{
	SM_NONE = 0,
	SM_CORE,
	SM_ARB
};

void SetupShaders(void)
{
	//printf("INFO: vert shader: 
%s", VertSrcFlatColor);
	//printf("INFO: frag shader: 
%s", FragSrcFlatColor);

	ShaderMode sm = SM_NONE;

	if (glewIsSupported("GL_VERSION_2_0"))
	{
		printf("INFO: Shaders supported natively in GL version 2.0 or higher.
");
		sm = SM_CORE;
	}
	else if (GLEW_ARB_vertex_shader && GLEW_ARB_vertex_shader)
	{
		printf("INFO: Shaders supported via extensions.
");
		sm = SM_ARB;
	}
	else
	{
		printf("ERROR: Shaders aren't supported.
");
		sm = SM_NONE;
	}

	unsigned long vertShader, fragShader;
	
	const char* vv = VertSrcFlatColor;
	const char* ff = FragSrcFlatColor;

	switch (sm)
	{
	case SM_CORE:
		vertShader = glCreateShader(GL_VERTEX_SHADER);
		glShaderSource(vertShader, 1, &vv, NULL);
		glCompileShader(vertShader);
		if (!DebugShader(vertShader))
		{
			glDeleteShader(vertShader);
			return;
		}

		fragShader = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(fragShader, 1, &ff, NULL);
		glCompileShader(fragShader);
		if (!DebugShader(fragShader))
		{
			glDeleteShader(vertShader);
			glDeleteShader(fragShader);
			return;
		}

		progFlatColor = glCreateProgram();
		glAttachShader(progFlatColor, vertShader);
		glAttachShader(progFlatColor, fragShader);

		glBindAttribLocation(progFlatColor, 0, "position");

		glLinkProgram(progFlatColor);
		glUseProgram(progFlatColor);
		if (!DebugProgram(progFlatColor))
		{
			glDetachShader(progFlatColor, vertShader);
			glDeleteShader(vertShader);
			glDetachShader(progFlatColor, fragShader);
			glDeleteShader(fragShader);
			glDeleteProgram(progFlatColor);
			return;
		}

		uniformColor = glGetUniformLocation(progFlatColor, "color");
		uniformMVP = glGetUniformLocation(progFlatColor, "MVP");

		if (uniformColor == -1 || uniformMVP == -1)
			printf("ERROR: Could not find uniform locations.
");

		glDeleteShader(vertShader);
		glDeleteShader(fragShader);
		break;

	case SM_ARB:
		vertShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
		glShaderSourceARB(vertShader, 1, &vv, NULL);
		glCompileShaderARB(vertShader);
		fragShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
		glShaderSourceARB(fragShader, 1, &ff, NULL);
		glCompileShaderARB(fragShader);

		progFlatColor = glCreateProgramObjectARB();
		glAttachObjectARB(progFlatColor, vertShader);
		glAttachObjectARB(progFlatColor, fragShader);
		glLinkProgramARB(progFlatColor);
		glUseProgramObjectARB(progFlatColor);
		break;

	default:
		return;
		break;
	}

	printf("INFO: Shaders successfully initialized.
");
}

I’m about 99% sure that the buffers are getting filled properly - I printf’d the entire array of vertices, and they look correct.

Bump?

I could really use some help here, I really have no idea what I’m doing wrong. Am I handling matrices all wrong? Or am I doing it right, and the problem is elsewhere?

This line:

gl_Position = (position * MVP);

should most likely be:

gl_Position = (MVP * position);

Also, you should probably be using activeHeader.numTris * 3 in your glDrawElements call, since that argument is the number of vertices, not the number of triangles.

I changed it as you suggested, but still nothing…

Your projection matrix is wrong. Change it to this and see if it helps.


void GetPerspective(float fov, float asp, float zMin, float zMax, float* projMat) 
{

float yMax = zMin * tanf(fov*float(M_PI) / 360.0f);
float yMin = -yMax;
float xMin = yMin * asp;
float xMax = -xMin; 

projMat[0] = (2.0f * zMin) / (xMax - xMin);
projMat[1] = 0;
projMat[2] = (xMax + xMin) / (xMax - xMin);
projMat[3] = 0;

projMat[4] = 0;
projMat[5] = (2.0f * zMin) / (yMax - yMin);
projMat[6] = (yMax + yMin) / (yMax - yMin);
projMat[7] = 0;

projMat[8] = 0;
projMat[9] = 0;
projMat[10] = -((zMax + zMin) / (zMax - zMin));
projMat[11] = -1;

projMat[12] = 0;
projMat[13] = 0;
projMat[14] = -((2.0f * (zMax*zMin))/(zMax - zMin));
projMat[15] = 0;
}

Still nothing =(

Still nothing =(

What geometry are u pushing into the vbo? I mean the positions. Are u sure that they are within the near far clip range (1-100) that u have given. Try changing the near clip to 0.1?
And I also dont see any viewing transformation, perhaps add in a translation of vec(0,0,-3) to move the camera three units on z axis.

Still nothing =(

You did not answer me i asked

What geometry are u pushing into the vbo? I mean the positions. Are u sure that they are within the near far clip range (1-100) that u have given?

Can u show us what geometry u have?

Sorry about that, I triple posted because of lag (Don’t ask me how lol)

Anyways, my viewing transform is this:


float mvMat[16] = {	1, 0, 0, 0,
			0, 1, 0, 0,
			0, 0, 1, 0,
			0, 0, 50, 1	};
// It might look backwards, but I transposed it to column-major.
// Yes, I've tried it with -50 instead of 50, with each change.

When I print out the vertex positions from the .3ds file I read in, it shows:


0: x = -10, y = -10, z = 15
1: x = 10,  y = -10, z = 15
2: x = 10,  y = 10,  z = 15
3: x = -10, y = 10,  z = 15
4: x = -10, y = -10, z = -15
5: x = 10,  y = -10, z = -15
6: x = 10,  y = 10,  z = -15
7: x = -10, y = 10,  z = -15

My near and far planes are set to 1 and 100 respectively, and I’m (trying to) translate it 50 units forward.

EDIT: I’m sending the geometry to the buffer as an interleaved array, also consisting of vertex normals (float[3]), and texture coordinates (float[2]). My “vertex” struct looks like:


struct vertex
{
   float x, y, z, nx, ny, nz, u, v;
};

The data I send into the vertex buffer is a “vertex[8]”, or more specifically, a “void*”, malloc’d and memcpy’d with data from my .3ds loader. here’s the portion of the code that uploads the data to the buffers:


activeVertData = malloc(sizeof(verts));
if (!activeVertData)
	printf("ERROR: Failed to allocate memory for activeVertData.  Required bytes: %i
", sizeof(verts));

memcpy(activeVertData, verts, sizeof(verts));


activeTriData = malloc(sizeof(faces));
if (!activeTriData)
	printf("ERROR: Failed to allocate memory for activeTriData.  Required bytes: %i
", sizeof(faces));

memcpy(activeTriData, faces, sizeof(faces));

free(verts);
free(faces);

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(activeVertData), activeVertData, GL_STATIC_DRAW);

glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(activeTriData), activeTriData, GL_STATIC_DRAW);

sizeof(activeVertData)

“activeVertData” is a pointer. Its size is four bytes. Same goes for “activeTriData”.

The sizeof operator cannot be used to detect the size of dynamically allocated blocks of memory (stuff you get with malloc or new[]). You must keep track of this yourself, or store you data in a std::vector which will keep track of it for you.

Okay, I changed it so that it now uses (size = numVerts * sizeof(vertex)) instead. Still nothing. I think I’m getting closer, though…

Bump, I’m really stumped here T_T

Could u try to render in immediate mode i.e.


glBegin(GL_TRIANGLES);
   for(int i=0;i<indices.size();i++) {
      int index = i*3;
      glVertex3fv(vertices[indices[index] ]);
      glVertex3fv(vertices[indices[index+1] ]);
      glVertex3fv(vertices[indices[index+2] ]);
   }
glEnd();

Huh. Surprisingly, still nothing. Here’s my new Render() function:

glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glTranslatef(0.0, 0.0, -50.0);
		glBegin(GL_TRIANGLES);
		glColor3f(1.0, 0.0, 1.0);
		for (int i = 0; i < activeHeader.numTris; i++)
		{
			glVertex3f(activeVertData[activeTriData[i].a].x, activeVertData[activeTriData[i].a].y, activeVertData[activeTriData[i].a].z);
			glVertex3f(activeVertData[activeTriData[i].b].x, activeVertData[activeTriData[i].b].y, activeVertData[activeTriData[i].b].z);
			glVertex3f(activeVertData[activeTriData[i].c].x, activeVertData[activeTriData[i].c].y, activeVertData[activeTriData[i].c].z);
		}
		glEnd();

The projection matrix is set by gluPerspective in the WM_SIZE message. Perhaps memcpy failed, or something…?

OOOOkay, this is weird. For the heck of I tested out:

glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glTranslatef(0.0, 0.0, 50.0);
		glBegin(GL_TRIANGLES);
			glColor3f(1.0, 0.0, 1.0);
			glVertex3f(-1, -1, 0);
			glVertex3f(0, 1, 0);
			glVertex3f(1, -1, 0);
		glEnd();

and STILL NOTHING. Ultimately, the only thing that really WORKS, is glClearColor. What the heck am I doing wrong?

  1. What are u setting the near and far clip planes to? Are u sure the values are fine.
  2. Could u post your render function may be u r doing something wrong elsewhere in the function?

The Near and Far planes are being set to 1 and 100 respectively. Entire Render() function (minus commented code):

#include "Main.h"

const float identityMat[16] = {	1, 0, 0, 0,
								0, 1, 0, 0,
								0, 0, 1, 0,
								0, 0, 0, 1	};

float mvMat[16] = {	1, 0, 0, 0,
					0, 1, 0, 0,
					0, 0, 1, 0,
					0, 0, 50, 1	};

float projMat[16];

void Render(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


		// Immediate mode test
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glTranslatef(0.0, 0.0, 50.0);
		glBegin(GL_TRIANGLES);
			glColor3f(1.0, 0.0, 1.0);
			glVertex3f(-1, -1, 0);
			glVertex3f(0, 1, 0);
			glVertex3f(1, -1, 0);
		glEnd();
	

	SwapBuffers(g_hDC);
}

(The matrix definitions at the top don’t need to be there as I’m not using them now, but they’re not hurting anyone, so I didn’t comment them out)

And, for completion, the WM_SIZE message in my WndProc:

RECT rcStatus, rcClient;
			HWND hStatus = GetDlgItem(hWnd, MAIN_STATUS);
			SendMessage(hStatus, WM_SIZE, 0, 0);
			GetWindowRect(hStatus, &rcStatus);
			int iStatusHeight = rcStatus.bottom - rcStatus.top;

			GetClientRect(hWnd, &rcClient);
			int iRenderHeight = rcClient.bottom - iStatusHeight;

			glViewport (rcClient.left, rcClient.top, rcClient.right, iRenderHeight);

			glMatrixMode(GL_PROJECTION);
			glLoadIdentity();
			gluPerspective(90, (float)rcClient.right/(float)iRenderHeight, 1, 100);

(There’s a status bar at the bottom, plus I intend to put more child windows, which I don’t want GL rendering under)

Change this


glTranslatef(0.0, 0.0, 50.0);

to this


glTranslatef(0.0, 0.0, -50.0);