Jump to content
  • Advertisement
babaliaris

OpenGL Textures, some work and some doesn't???

Recommended Posts

Hello again :) 

Recently I was trying to apply 6 different textures in a cube and I noticed that some textures would not apply correctly, but if i change the texture image with another it works just fine. I can't really understand what's going on. I will also attach the image files. So does this might have to do anything with coding or its just the image fault???

This is a high quality texture 2048x2048 brick1.jpg, which does the following:

yyAqqpT.png

 

And this is another texture 512x512 container.jpg which is getting applied correctly with the exact same texture coordinates as the prev one:

3YwvDhp.png

 

Vertex Shader

#version 330 core

layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;


out vec2 TexCoord;

void main()
{
	gl_Position = proj * view * model * vec4(aPos, 1.0);

	TexCoord = aTexCoord;
}

 

Fragment Shader

#version 330 core

out vec4 Color;
in vec2 TexCoord;

uniform sampler2D diffuse;

void main()
{
	Color = texture(diffuse, TexCoord);
}

 

Texture Loader

Texture::Texture(std::string path, bool trans, int unit)
{

	//Reverse the pixels.
	stbi_set_flip_vertically_on_load(1);

	//Try to load the image.
	unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 0);

	//Image loaded successfully.
	if (data)
	{

		//Generate the texture and bind it.
		GLCall(glGenTextures(1, &m_id));
		GLCall(glActiveTexture(GL_TEXTURE0 + unit));
		GLCall(glBindTexture(GL_TEXTURE_2D, m_id));

		//Not Transparent texture.
		if (!trans)
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data));
		}

		//Transparent texture.
		else
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
		}

		//Generate mipmaps.
		GLCall(glGenerateMipmap(GL_TEXTURE_2D));

		//Texture Filters.
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
		GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
	}


	//Loading Failed.
	else
		throw EngineError("The was an error loading image: " + path);


	//Free the image data.
	stbi_image_free(data);
}


Texture::~Texture()
{
}

void Texture::Bind(int unit)
{
	GLCall(glActiveTexture(GL_TEXTURE0 + unit));
	GLCall(glBindTexture(GL_TEXTURE_2D, m_id));
}

Rendering Code:

Renderer::Renderer()
{
	float vertices[] = {
		// positions          // normals           // texture coords
		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
		 0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f,
		 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
		 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
		-0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f,
		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,

		-0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
		 0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 0.0f,
		 0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
		 0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
		-0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 1.0f,
		-0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,

		-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
		-0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
		-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
		-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
		-0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
		-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,

		 0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
		 0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
		 0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
		 0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
		 0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
		 0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,

		-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
		 0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 1.0f,
		 0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
		 0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
		-0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f,
		-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,

		-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f,
		 0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f,
		 0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
		 0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
		-0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f,
		-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f
	};

	//Create the Vertex Array.
	m_vao = new Vao();

	//Create the Vertex Buffer.
	m_vbo = new Vbo(vertices, sizeof(vertices));

	//Create the attributes.
	m_attributes = new VertexAttributes();
	m_attributes->Push(3);
	m_attributes->Push(3);
	m_attributes->Push(2);
	m_attributes->Commit(m_vbo);
}







Renderer::~Renderer()
{
	delete m_vao;
	delete m_vbo;
	delete m_attributes;
}






void Renderer::DrawArrays(Cube *cube)
{

	//Render the cube.
	cube->Render();

	unsigned int tex = 0;

	for (unsigned int i = 0; i < 36; i += 6)
	{

		if (tex < cube->m_textures.size())
			cube->m_textures[tex]->Bind();

		GLCall(glDrawArrays(GL_TRIANGLES, i, 6));

		tex++;
	}
}

 

brick1.jpg

container.jpg

Share this post


Link to post
Share on other sites
Advertisement

Since no one's replied yet, I'll go ahead and reply (even though I don't have an answer for you).

I skimmed the code, but didn't see anything obvious (if there's an error, maybe someone else will spot it).

If you haven't solved it yet, here are some things you could try:

- Simplify things by only rendering a single quad without indices (e.g. glDrawArrays()). If that fixes it, that'll be a hint as to where the problem is.

- Try a 512x512 version of the brick texture to see if the problem is size-related.

- Try it with both images exported from the same image editing program to (possibly) eliminate any vagaries related to image format, etc.

I can't tell from the picture, but is there a quad on the side being successfully rendered with the brick texture? If so, that should be a hint.

Also, what exactly (if you know) is being rendered at the bottom of the front-facing quad with the brick texture? It looks like another texture, or perhaps the brick texture, scaled and with different coloring (I can't really tell). That seems like a clue as well.

Again, the problem may be evident from what you've posted so far, and if so, maybe someone else will spot it.

Share this post


Link to post
Share on other sites
Posted (edited)
3 hours ago, Zakwayda said:

- Try a 512x512 version of the brick texture to see if the problem is size-related.

This worked. I resized the image with windows painter and it worked.

But what is causing that? Why a high resolution image would create such an effect? Also you are right about the bottom of the front quad, you can see other textures too which i actually use for the other faces, but that mix of them is just so weird, I literally can't tell why it causes this when i use a high resolution image. Also from what i learned so far, high resolution images are always better because they cover a big range of sizes, also i'm generating mipmaps.

I also tried the following and it worked:

I kept the original image 2048x2048 and I loaded only that image as a texture (in the previous examples i was loading up to 6 differently textures) and the cube was getting rendered just fine with the high resolution image. So probably the problem must be in the loading texture class. If anyone has any ideas, help me.

 

I attached the program (build in visual studio for windows 32). Can someone download and run it to see if it works? Just to see if there is a bug with my graphics card drivers, because amd recently was having huge bugs on radeon, especially for my graphics card series.

This is what i see when i run the program which i attached:

Capture.png

 

openGL.rar

Edited by babaliaris

Share this post


Link to post
Share on other sites

I'm not set up for Windows development right now, else I'd give it a try.

Quote

Also from what i learned so far, high resolution images are always better because they cover a big range of sizes, also i'm generating mipmaps.

I don't know that high-resolution images are always better. There are various tradeoffs to consider, such as target platform, frame buffer resolution, texture memory usage, what sort of compressed formats are available and what effect they have on image quality, and so on.

Consider that if the frame buffer resolution and texture usage patterns are such that the top mipmap level is never touched, you're just wasting texture memory (or so it would seem to me). A texture management system could, for example, take this into account by selecting a texture size based on (e.g.) frame buffer resolution and expected usage. (And of course some platforms, like iOS and Android, have OS-level support for image resolution selection.)

Of course that's all tangential here, since the real question is why you're getting the behavior you're getting.

Couple other things to try would be checking glGetError() at some point, and (just to be sure) checking for program compile/link errors as well. If you have OpenGL-related diagnostic tools available (e.g. something similar to what's available with Xcode), you could try that as well.

It's also possible to check the maximum texture size that the OpenGL implementation supports, and (if I recall correctly) to check that a particular texture will be uploaded successfully using texture proxies. It seems unlikely that that's the issue here, but if this is Windows, there may be some vagaries with respect to OpenGL support (at least that's been the case in the past).

With any luck, someone who's set up for Windows will be able to try out your app.

Share this post


Link to post
Share on other sites

I use glGetError in every gl function, it's the GLCall macro in my code. I'm not getting any errors or compilation errors. 

Share this post


Link to post
Share on other sites

By calling:

GLint data;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &data);

I'm getting: 16384

and with a google search I found out that this means my graphics card can manipulate up to 16384x16384 resolution textures. So the brick texture which is 2048x2048 should be fine.

Share this post


Link to post
Share on other sites
Posted (edited)

Seems to be a problem with the texture loading.

In your texture source file change to the following code:

//Not Transparent texture.
if (!trans)
{
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data));
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}

Another way is to force stbi to use 4 channels so that it aligns to four bytes

Texture::Texture(std::string path, bool trans, int unit)
{
// ...
	unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 4);
// ...
	if (data)
	{
		//Not Transparent texture.
		if (!trans)
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
		}
	// ...	
	}
//...
}

 

Edited by stororokw

Share this post


Link to post
Share on other sites
1 hour ago, stororokw said:

Seems to be a problem with the texture loading.

In your texture source file change to the following code:


//Not Transparent texture.
if (!trans)
{
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data));
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}

Another way is to force stbi to use 4 channels so that it aligns to four bytes


Texture::Texture(std::string path, bool trans, int unit)
{
// ...
	unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 4);
// ...
	if (data)
	{
		//Not Transparent texture.
		if (!trans)
		{
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
		}
	// ...	
	}
//...
}

 

This is what I get when I'm using 4 channels:

four_channels.png

//Not Transparent texture.
		if (!trans)
		{
			GLCall(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
			GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data));
			GLCall(glPixelStorei(GL_UNPACK_ALIGNMENT, 4));
		}

And when I use the above code I'm getting this:

Capture.png

Share this post


Link to post
Share on other sites
Posted (edited)

I took a look at your code from github OpenGLTextureProblem and for me things appear to be working properly.

Do you have the version of the code you used to post that last screenshot?

ogl.jpg

Edited by stororokw

Share this post


Link to post
Share on other sites
Posted (edited)
31 minutes ago, stororokw said:

I took a look at your code from github OpenGLTextureProblem and for me things appear to be working properly.

Do you have the version of the code you used to post that last screenshot?

ogl.jpg

Can you change the input from the first texture in Main.cpp

	Texture *texture1 = new Texture("Resources/brick1.jpg", false);
	Texture *texture2 = new Texture("Resources/container.jpg", false);
	Texture *texture3 = new Texture("Resources/brick2.jpg", false);
	Texture *texture4 = new Texture("Resources/brick3.jpg", false);
	Texture *texture5 = new Texture("Resources/brick4.jpg", false);
	Texture *texture6 = new Texture("Resources/container2.png", true);

from brick1.jpg to a.jpg and show me again the result? brick1.jpg is a resized version of a.jpg and it works on my computer as well.

So change the *texture1 in Main.cpp with:

Texture *texture1 = new Texture("Resources/a.jpg", false);

 

Edited by babaliaris
I posted Wrong Code!!!!

Share this post


Link to post
Share on other sites

  • 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!