Jump to content
  • Advertisement
Sign in to follow this  
tmason

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

This topic is 1492 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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]

 

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!