Texture Loading "Per Triangle" versus all of the Triangles Called with glDrawElements

Started by
11 comments, last by L. Spiro 9 years, 10 months ago

Hello,

I have this weird problem that I assume is really simple to fix but I can't figure it out. Basically my textures are being loaded per "triangle" when I use them in OpenGL.

Thank you in advance for any assistance you can provide.

Here is how I am loading them into OpenGL:


glGenTextures(1, &TextureObject_ID);   // section being edited by CKoeber to pull in material files
		glActiveTexture(GL_TEXTURE0 + 1);
		glBindTexture(GL_TEXTURE_2D, TextureObject_ID);
		GLsizei iFormat = BytesPerPixel == 24 ? GL_BGR : BytesPerPixel == 8 ? GL_LUMINANCE : 0;
		GLsizei iInternalFormat = BytesPerPixel == 24 ? GL_RGB : GL_DEPTH_COMPONENT;
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
		             WidthOfTexture, HeightOfTexture, 0, iFormat,
		             GL_UNSIGNED_BYTE, bytesDataPointer);
		glGenerateMipmap(GL_TEXTURE_2D);
		FreeImage_Unload(loadedImage);
		glGenSamplers(1, &TextureSamplerObject_ID);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		setFiltering(TEXTURE_FILTER_MAG_BILINEAR, TEXTURE_FILTER_MIN_BILINEAR_MIPMAP);
		HasMipsBeenGenerated = true;
		glActiveTexture(GL_TEXTURE0 + 0);
		glBindTexture(GL_TEXTURE_2D, NULL);

I am sending my UV coordinates to OpenGL like so:


		glBufferSubData(GL_ARRAY_BUFFER, UVOffset, UVBufferSize, UVs);
		glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(2);

I am buffering my vertices and normals in similar fashion as I am drawing fine.

Also,

Here is the relevant section in the graphics card:


/*

In Fragment Shader...

*/

uniform sampler2D MainTextureSampler; 
in vec2 TextureCoordinates;
out vec4 finalColor;

void Main() {

    vec4 MaterialTextureColor = texture2D(MainTextureSampler, TextureCoordinates);
    finalColor = MaterialTextureColor;

}

Below is an example image:

Texture_Per_Triangle.png

Advertisement

This looks pretty much like broken tex coordinates for this triangle.

Do you generate the texture coordinates yourself or are you loading them from a model?

If you generate them your self, check that corresponding vertices in each triangle have the same texture coordinates assigned.

If the vertexbuffer of this quad looks like this [V1/V2/V3/V1/V3/V4]

make sure the buffer for the texture coordinates is layouted the same way [T1/T2/T3/T1/T3/T4]

This looks pretty much like broken tex coordinates for this triangle.

Do you generate the texture coordinates yourself or are you loading them from a model?

If you generate them your self, check that corresponding vertices in each triangle have the same texture coordinates assigned.

If the vertexbuffer of this quad looks like this [V1/V2/V3/V1/V3/V4]

make sure the buffer for the texture coordinates is layouted the same way [T1/T2/T3/T1/T3/T4]

Thanks,

I am loading the UVs from a file. I was wondering how to generate them myself but I want to use them from the file if I can.

If I have to, how would I generate them?

Thank you for your time.

Then maybe it would help to post the code where you are loading the file (what format?) and you draw call to open gl.

It's just a hunch, but if you have back face culling disabled and use the wrong winding order of faces, it might just generate this effect.

maybe playing a little around with glFrontFace() and glCullFace() will help.

If I have to, how would I generate them?

Don't even think about that then biggrin.png

Then maybe it would help to post the code where you are loading the file (what format?) and you draw call to open gl.


Here is the way I am loading the texture (using FreeImage and JPEG files):


FIBITMAP *loadedImage = NULL;
		FREE_IMAGE_FORMAT CurrentFormat = FIF_UNKNOWN;
		CurrentFormat = FreeImage_GetFileType(MaterialFile.c_str(), 0);

		if (CurrentFormat == FIF_UNKNOWN) {
			FREE_IMAGE_FORMAT CurrentFormat = FreeImage_GetFIFFromFilename(MaterialFile.c_str());
		}

		if (CurrentFormat == FIF_UNKNOWN) {
			return false;
		}

		if (FreeImage_FIFSupportsReading(CurrentFormat)) {
			loadedImage = FreeImage_Load(CurrentFormat, MaterialFile.c_str());
		}

		if (!loadedImage) {
			return false;
		}

		BYTE* bytesDataPointer = FreeImage_GetBits(loadedImage);
		WidthOfTexture = FreeImage_GetWidth(loadedImage);
		HeightOfTexture = FreeImage_GetHeight(loadedImage);
		BytesPerPixel = FreeImage_GetBPP(loadedImage);

		if (WidthOfTexture == 0 || HeightOfTexture == 0 || BytesPerPixel == 0) {
			return false;
		}

		glGenTextures(1, &TextureObject_ID);   // section being edited by CKoeber to pull in material files
		glActiveTexture(GL_TEXTURE0 + 1);
		glBindTexture(GL_TEXTURE_2D, TextureObject_ID);
		GLsizei iFormat = BytesPerPixel == 24 ? GL_BGR : BytesPerPixel == 8 ? GL_LUMINANCE : 0;
		GLsizei iInternalFormat = BytesPerPixel == 24 ? GL_RGB : GL_DEPTH_COMPONENT;
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
		             WidthOfTexture, HeightOfTexture, 0, iFormat,
		             GL_UNSIGNED_BYTE, bytesDataPointer);
		glGenerateMipmap(GL_TEXTURE_2D);
		FreeImage_Unload(loadedImage);
		glGenSamplers(1, &TextureSamplerObject_ID);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		setFiltering(TEXTURE_FILTER_MAG_BILINEAR, TEXTURE_FILTER_MIN_BILINEAR_MIPMAP);
		HasMipsBeenGenerated = true;
		glActiveTexture(GL_TEXTURE0 + 0);
		glBindTexture(GL_TEXTURE_2D, NULL);
And here is the way I am drawing the OpenGL quad with materials:


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
glUseProgram(g_StandardShaderProgram_ID);

glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glEnable(GL_TEXTURE_2D);
glUniform1i(GetEnableWireframeID(), 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

for (GLuint i = 0; i < CurrentMeshCache.size(); i++) {

/*

Inside my object that has my mesh/quad/material data...

/*

glBindVertexArray(Pointer_VAO);

for (int i = 0; i < ModelMatrixInstances.size(); i++) {
	glm::mat4 ModelViewMatrix = CurrentOpenGLController->GetViewMatrix() * ModelMatrixInstances[i];
	glm::mat3 NormalMatrix = glm::transpose(glm::inverse(glm::mat3(ModelViewMatrix)));
	glm::mat4 ModelViewProjectionMatrix = CurrentOpenGLController->GetProjectionViewMatrix() * ModelMatrixInstances[i];
	glBindBuffer(GL_ARRAY_BUFFER, MVP_VBO);
	glBufferSubData(GL_ARRAY_BUFFER, (i * (sizeof(glm::mat4))), sizeof(glm::mat4), glm::value_ptr(ModelViewProjectionMatrix));
	glBindBuffer(GL_ARRAY_BUFFER, NormalMatrix_VBO);
	glBufferSubData(GL_ARRAY_BUFFER, (i * (sizeof(glm::mat3))), sizeof(glm::mat3), glm::value_ptr(NormalMatrix));
}

glUniform4fv(CurrentOpenGLController->GetMaterialColorID(), 1, Materials[0].ObjectColor);
glUniform4fv(CurrentOpenGLController->GetAmbientMeshColorID(), 1, Materials[0].AmbientColor);
glUniform4fv(CurrentOpenGLController->GetEmmissiveMeshColorID(), 1, Materials[0].EmissiveColor);
glUniform4fv(CurrentOpenGLController->GetSpecularMeshColorID(), 1, Materials[0].SpecularColor);
glUniform4fv(CurrentOpenGLController->GetDiffuseMeshColorID(), 1, Materials[0].DiffuseColor);
glUniform1fv(CurrentOpenGLController->GetMeshShininessID(), 1, &Materials[0].Shininess);

if (Materials[0].HasMaterialFile == true) {
	GLfloat ObjectHasMaterial = 1.0f;
	glUniform1fv(CurrentOpenGLController->GetObjectHasMaterialFileID(), 1, &ObjectHasMaterial);
	glUniform1i(CurrentOpenGLController->GetMainTextureID(), 1);
	Materials[0].bindTexture(1);
}
else {
	GLfloat ObjectDoesNotHaveMaterial = 0.0f;
	glUniform1fv(CurrentOpenGLController->GetObjectHasMaterialFileID(), 1, &ObjectDoesNotHaveMaterial);
	glBindTexture(GL_TEXTURE_2D, NULL);
}

glDrawElementsInstanced(GL_TRIANGLES, TotalVertexCount,
	GL_UNSIGNED_INT, NULL, NumberOfChildItems + 1);

if (Materials[0].HasMaterialFile == true) {
	glActiveTexture(GL_TEXTURE0 + NULL);
	glBindTexture(GL_TEXTURE_2D, NULL);
}

/*

Now out of my object...

*/
}

glBindVertexArray(0);

It's just a hunch, but if you have back face culling disabled and use the wrong winding order of faces, it might just generate this effect.
maybe playing a little around with glFrontFace() and glCullFace() will help.


Tried this; same results. Thank you for the suggestion though.

If I have to, how would I generate them?


Don't even think about that then biggrin.png


Darn, it's OK, I can learn smile.png

Darn, it's OK, I can learn

Naa, thats not what I mean. This would just be a hack and not a solution to your problem in the first place.

I am sorry, I think I was not clear enough, but with file I didn't mean the image but the geometry you are loading. I think you have to look for the error in how you set up your vertex/normal/texcoord/index buffers.

Have you ever tried to render a simpler scene (just one quad maybe?) to make it easier to narrow down the error?

Do you really want to draw glDrawElementsInstanced ()??? this would mean that you would render the same geometry over and over again and you need an instance buffer with appropriate glVertexAttribDivisor() set (have a look at instanced rendering then: http://en.wikipedia.org/wiki/Geometry_instancing)

Second I noticed, that you call glDrawElements* with TotalVertexCount I dont know what this variable contains but you should call this function with the number of indices not vertices.

From what type of file are you loading the model data?
Some file formats are obnoxious and use 1-based indices or have other quirks when indexing into UV/normal/vertex pools.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

From what type of file are you loading the model data?
Some file formats are obnoxious and use 1-based indices or have other quirks when indexing into UV/normal/vertex pools.


L. Spiro


I am loading the data from an FBX file.

Specifically, I am using Autodesk's FBX SDK.

This topic is closed to new replies.

Advertisement