Scene isn't rendering - probably matrix issues?

Progress!! Finally!!! Okay, so this:


glVertex3f(-10, -10, 0);
glVertex3f(0, 10, 0);
glVertex3f(10, -10, 0);

Gives me a magenta triangle. This:


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);
			
}

Gives me nothing whatsoever.

EDIT: Okay, I got the mesh to load. It shows a magenta cube (which is all the mesh was) on the screen. However, when I switch back to using the buffers, nothing shows up again…

OK i m glad it worked.
Hmm now could u show the vbo setup and how the data is being input?

Just to note, this worked:


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);
			
		}

It’s my fault for saying it didn’t, I forgot to actually load the mesh lol. Anyhow. Here’s my CURRENT render():


#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, -30,
			0, 0, 0, 1	};

float projMat[16];

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

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

		m3dMatrixMultiply44(mvMat, mvMat, identityMat);
		m3dMatrixMultiply44(mvpMat, projMat, identityMat);

		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, NULL);
	
		glDrawElements(GL_TRIANGLES, activeHeader.numTris * 3, GL_UNSIGNED_SHORT, 0);
		
	}

	SwapBuffers(g_hDC);
}

As a note, I’ve tried that modelview matrix both as-is and transposed, and no good either way. Here’s my WM_SIZE message:



			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);

			
			float fov = 90.0f;
			float aspect = ((float)rcClient.right/(float)iRenderHeight);
			float zMin = 1.0f;
			float zMax = 100.0f;

			float yMax = zMin * tanf(fov*PI_OVER_360);
			float yMin = -yMax;
			float xMin = yMin * aspect;
			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;

EDIT: I’m just gonna post my entire Load3DS function here:

#include "Main.h"

GLuint vbo, ibo = 0;

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

struct Normal
{
	float x, y, z;
};

struct Face
{
	unsigned short a, b, c;
};

void Load3DS(char* filename)
{
	printf("
INFO: Opening %s as a .3ds model.

", filename);

	unsigned long i;
	FILE *file;
	unsigned short chunkID;
	unsigned long chunkLength;
	unsigned char Char;
	unsigned short qty;
	unsigned short faceFlags;
	unsigned long fileLength;
	char name[21] = {0};

	unsigned short numVerts, numFaces;
	Vertex* verts;
	Face* faces;

	file = fopen(filename, "rb");
	if (!file)
	{
		printf("ERROR: Failed to open %s.
", filename);
		return;
	}

	fseek(file, 0, SEEK_END);
	fileLength = ftell(file);
	fseek(file, 0, SEEK_SET);

	while (ftell(file) < fileLength)
	{
		fread(&chunkID, 2, 1, file);
		fread(&chunkLength, 4, 1, file);

		switch (chunkID)
		{
		case 0x4d4d: // Main chunk
			break;

		case 0x3d3d: // 3d editor chunk
			break;

		case 0x4000: // Contains the name of the object
			i = 0;
			do
			{
				fread(&Char, 1, 1, file);
				name[i] = Char;
				i++;
			} while (Char != '\0' && i < 20);
			printf("INFO: read object '%s'.
", name);
			break;

		case 0x4100: // Another empty parent node...
			break;

		case 0x4110: // Vertices! yay!
			fread(&numVerts, 2, 1, file);
			printf("INFO: Found %i vertices.
", numVerts);
			verts = (Vertex*)malloc(sizeof(Vertex) * numVerts);
			if (!verts)
			{
				printf("ERROR: Failed to allocate memory for vertices.
");
				if (faces)
					free(faces);
				return;
			}
			for (i = 0; i < numVerts; i++)
			{
				fread(&verts[i].x, 4, 1, file);
				fread(&verts[i].y, 4, 1, file);
				fread(&verts[i].z, 4, 1, file);
			}
			break;

		case 0x4120: // Faces
			fread(&numFaces, 2, 1, file);
			printf("INFO: found %i faces.
", numFaces);
			faces = (Face*)malloc(sizeof(Face) * numFaces);
			if (!faces)
			{
				printf("ERROR: Failed to allocate memory for faces.
");
				if (verts)
					free(verts);
				return;
			}
			for (i = 0; i < numFaces; i++)
			{
				fread(&faces[i].a, 2, 1, file);
				fread(&faces[i].b, 2, 1, file);
				fread(&faces[i].c, 2, 1, file);
				fread(&faceFlags, 2, 1, file);
			}
			break;

		case 0x4140:
			fread(&qty, 2, 1, file);
			printf("INFO: found %i texture coordinates.
", qty);
			for (i = 0; i < qty; i++)
			{
				fread(&verts[i].u, 4, 1, file);
				fread(&verts[i].v, 4, 1, file);
			}
			break;

		default:
			fseek(file, chunkLength - 6, SEEK_CUR);
			break;
		}
	}
	fclose(file);

	//////////////////////////////
	// Calculate vertex normals //
	//////////////////////////////
	for (i = 0; i < numFaces; i++)
	{
		Normal tempNorm;

		// Calculate the surface normal
		Normal U;
		U.x = (verts[faces[i].b].x - verts[faces[i].a].x);
		U.y = (verts[faces[i].b].y - verts[faces[i].a].y);
		U.z = (verts[faces[i].b].z - verts[faces[i].a].z);

		Normal V;
		V.x = (verts[faces[i].c].x - verts[faces[i].a].x);
		V.y = (verts[faces[i].c].y - verts[faces[i].a].y);
		V.z = (verts[faces[i].c].z - verts[faces[i].a].z);

		tempNorm.x = (U.y * V.z) - (U.z * V.y);
		tempNorm.y = (U.z * V.x) - (U.x * V.z);
		tempNorm.z = (U.x * V.y) - (U.y * V.x);

		// Add the surface normal to every connected vertex
		verts[faces[i].a].nx += tempNorm.x;
		verts[faces[i].a].ny += tempNorm.y;
		verts[faces[i].a].nz += tempNorm.z;

		verts[faces[i].b].nx += tempNorm.x;
		verts[faces[i].b].ny += tempNorm.y;
		verts[faces[i].b].nz += tempNorm.z;

		verts[faces[i].b].nx += tempNorm.x;
		verts[faces[i].b].ny += tempNorm.y;
		verts[faces[i].b].nz += tempNorm.z;
	}

	for (i = 0; i < numVerts; i++)
	{
		// Normalize vertex normals
		float length = sqrt((verts[i].nx*verts[i].nx) + (verts[i].ny*verts[i].ny) + (verts[i].nz*verts[i].nz));

		verts[i].nx /= length;
		verts[i].ny /= length;
		verts[i].nz /= length;
	}

	// Print vertex info
	
	for (i = 0; i < numVerts; i++)
	{
		printf("INFO: Vertex #%i: x: %f, y: %f, z: %f,
 nx: %f, ny: %f, nz: %f,
 u: %f, v: %f
",
			i, verts[i].x, verts[i].y, verts[i].z,
			verts[i].nx, verts[i].ny, verts[i].nz,
			verts[i].u, verts[i].v	);
	}
	

	activeFilename = filename;
	activeHeader.magic[1] = 'A';
	activeHeader.magic[2] = 'M';
	activeHeader.magic[3] = 'L';
	activeHeader.magic[4] = ' ';
	activeHeader.versionNumber = 1;
	activeHeader.numVerts = numVerts;
	activeHeader.numTris = numFaces;
	activeHeader.vertFormat = VF_PNT;
	activeHeader.triFormat = TF_16;

	//// Copy vertices to the array and upload them to the buffer
	long size = activeHeader.numVerts * activeHeader.vertFormat;

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

	memcpy(activeVertData, verts, size);

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

	//// Do the same with the triangles
	size = activeHeader.numTris * activeHeader.triFormat;

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

	memcpy(activeTriData, faces, size);

	free(verts);
	free(faces);

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

	// Check for errors
	if (vbo == 0 || ibo == 0)
	{
		printf("ERROR: Failed to create vertex/index buffers.
");
	}

	return;
}

Your get the size using

long size = activeHeader.numVerts * activeHeader.vertFormat;

Does activeHeader.vertFormat contain the total number of elements per vertex?
Usually, i would give the second parameters as


sizeof(float)*numElementsPerVertex*total_vertices

so in your case it should be


sizeof(float)*3*total_vertices;

the same thing goes for indices where sizeof float will be replace by either sizeof(GLushort) or GLuint depending on the type u have given.

Another thing, you need to enable the vertex attribute too like this,


glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, NULL);

The second last parameter is the stride the value of which depends on how the interleaving is done so for your case since you are putting the normals and uvs together with positions, it should be


GLsizei stride = sizeof(GLfloat)*(3+3+2);

since 3 floats for positions+3 floats for normal and 2 floats for uv coordinates.
See if this helps.

vertFormat and triFormat are defined as sizeof’s of the vert_PNT and triangle_16 structs, respectively, so numVerts * vertFormat should give the exact size in bytes of the vertex array. “glBufferData(GL_ARRAY_BUFFER, size, activeVertData, GL_STATIC_DRAW)” uploads the vertex data, or is supposed to…

Wait, I thought stride was the number of bytes between vertices, not the size of the vertex struct entirely…?

EDIT: I added “glEnableVertexAttribArray(0);”, and I now get a purple… shape on the screen. It’s definately not a cube, however. I’m guessing it’s not seeing the indices properly now…?

NO since u r interleaving the normals and uvs it should give the offset to the next vertex.

Okay, yay, I can see a magenta square! Progress has been made! :smiley:

Thank you so much!!

Great. I am glad it worked out ok.