Textures With High Resolution Have Unexpected Behavior

I was working in a project and I faced something really weird which I can’t explain why it’s happening. In order to give you a good understanding of what is happening I created a whole new project to demonstrate to you the things that I noticed.
If you don’t like seeing code as a post, i uploaded the project on GitHub Here but i will also post some code at the end of this post.

In this project I’m just creating a cube which I apply a texture on it.

Plan A (Load only one texture with resolution 2048x2048 a.jpg and apply it):


	camera             = new Camera(glm::vec3(0.0f, 0.0f, 3.0f));
	Renderer *renderer = new Renderer();
	Shader *shader     = new Shader("Shaders/basic_vertex.glsl", "Shaders/basic_fragment.glsl");


	Texture *texture1 = new Texture("Resources/a.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);

The Result is what I expected:
[ATTACH=CONFIG]1860[/ATTACH]

Plan B (Load more textures before the bug appears):


	Texture *texture1 = new Texture("Resources/a.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);

The Result is what I expected:
[ATTACH=CONFIG]1860[/ATTACH]

Plan C (When does the bug appears?):


	Texture *texture1 = new Texture("Resources/a.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);

The Result is this:
[ATTACH=CONFIG]1861[/ATTACH]

If i continue:


	Texture *texture1 = new Texture("Resources/a.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);

More weird stuff:
[ATTACH=CONFIG]1862[/ATTACH]

As you can see I’m loading more than one textures but before the draw call I’m always binding only the first texture (I’m not using the other ones).

Best Plan (Resize the big image a.jpg to 512x512 which in the resources folder I call it brick1.jpg)


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

Result Is What I Expected:
[ATTACH=CONFIG]1863[/ATTACH]

Also GL_MAX_TEXTURE_SIZE returns: 16384

Honestly I can’t figure out what’s going on. I’m starting to suspect that it’s my graphic drivers (I use amd ati radean r9 200 series)

I compiled a win32 which you can download from here. Please if you have one minute download it and run it and tell me if you get the unexpected behavior like this:
[ATTACH=CONFIG]1862[/ATTACH]

I really want to find what is wrong with that before moving on learning more about opengl. I don’t wanna learn stuff without knowing what I am doing.
Thank you :slight_smile:

Main.cpp


#include "Renderer.h"
#include "camera.h"

Camera *camera;

//Handle Key Input.
void HandleInput(GLFWwindow *window)
{

	//Exit the application with ESCAPE KEY.
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, 1);


	//Move Forward.
	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
		camera->Move(true);

	//Move Backward.
	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
		camera->Move(false, true);

	//Move left.
	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
		camera->Move(false, false, true);

	//Move right.
	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
		camera->Move(false, false, false, true);
}



//Mouse Input.
void MouseInput(GLFWwindow *window, double x, double y)
{
	camera->UpdateRotation(x, y);
}



//Mouse Zoom input.
void MouseZoom(GLFWwindow *window, double x, double y)
{
	camera->UpdateZoom(x, y);
}



int main(void)
{
	GLFWwindow* window;

	/* Initialize the library */
	if (!glfwInit())
		return -1;


	//Use openGL version 3.3 Core Profile.
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	/* Create a windowed mode window and its OpenGL context */
	window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		return -1;
	}

	/* Make the window's context current */
	glfwMakeContextCurrent(window);


	//Initialize GLEW.
	if (glewInit() != GLEW_OK)
	{
		glfwTerminate();
		return -1;
	}

	//Set Callback functions.
	glfwSetCursorPosCallback(window, MouseInput);
	glfwSetScrollCallback(window, MouseZoom);

	//Disable the cursor.
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

	//Enable Depth Test.
	GLCall(glEnable(GL_DEPTH_TEST));





	camera             = new Camera(glm::vec3(0.0f, 0.0f, 3.0f));
	Renderer *renderer = new Renderer();
	Shader *shader     = new Shader("Shaders/basic_vertex.glsl", "Shaders/basic_fragment.glsl");


	Texture *texture1 = new Texture("Resources/a.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);
	std::vector<Texture *> textures = { texture1};


	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{

		//Handle input.
		HandleInput(window);

		//Clear the screen.
		renderer->ClearScreen(0.0f, 0.0f, 0.0f);

		//Render the cube.
		renderer->Render(textures, shader, camera);

		//Update.
		renderer->Update(window);
	}


	//-------------Clean Up-------------//
	delete camera;
	delete renderer;
	delete shader;
	for (unsigned int i = 0; i < textures.size(); i++)
		delete textures[i];
	//-------------Clean Up-------------//


	glfwTerminate();
	return 0;
}

Texture.cpp


#include "texture.h"
#include "stb_image/stb_image.h"
#include "glcall.h"
#include "engine_error.h"



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



	//Unbind the texture.
	GLCall(glBindTexture(GL_TEXTURE_2D, 0));

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

Renderer.cpp


#include "Renderer.h"


Renderer::Renderer()
{

	//Vertex Data.
	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
	};


	//Generate a VAO and a VBO.
	GLCall(glGenVertexArrays(1, &m_VAO));
	GLCall(glGenBuffers(1, &m_VBO));

	//Bind VAO and VBO.
	GLCall(glBindVertexArray(m_VAO));
	GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_VBO));

	//Transfer The Data.
	GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));

	//Positions.
	GLCall(glEnableVertexAttribArray(0));
	GLCall(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void *)0));

	//Normals.
	GLCall(glEnableVertexAttribArray(1));
	GLCall(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void *) 12));

	//Texture Coordinates.
	GLCall(glEnableVertexAttribArray(2));
	GLCall(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void *) 24));

	//Unbind The Buffers.
	GLCall(glBindVertexArray(0));
	GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0));
}





Renderer::~Renderer()
{
}





void Renderer::ClearScreen(float r, float g, float b)
{
	GLCall(glClearColor(r, g, b, 1.0f));
	GLCall(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
}





void Renderer::Update(GLFWwindow * window)
{
	glfwSwapBuffers(window);
	glfwPollEvents();
}





void Renderer::Render(std::vector<Texture *>textures, Shader *program, Camera *camera)
{
	//Bind VAO.
	GLCall(glBindVertexArray(m_VAO));

	//Bind the Shader.
	program->Bind();

	//Bind the texture at unit zero.
	textures[0]->Bind(0);

	glm::mat4 model = glm::mat4(1.0f);
	glm::mat4 view  = glm::mat4(1.0f);
	glm::mat4 proj  = glm::mat4(1.0f);

	//Get The View Matrix.
	view = camera->GetView();

	//Create The Perspective Projection.
	proj = glm::perspective(camera->m_fov, 800.0f / 600, 0.1f, 100.0f);

	//Set the transformation uniforms.
	program->SetUniformMat4f("model", model);
	program->SetUniformMat4f("view", view);
	program->SetUniformMat4f("proj", proj);

	//Draw Call.
	GLCall(glDrawArrays(GL_TRIANGLES, 0, 36));
}

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

Well People tried to run my application which you can find Here and they told me that they get a nice brick cube and not something like this:
[ATTACH=CONFIG]2851[/ATTACH]

Well, this probably means that my graphics drivers have something wrong with the openGL implementation right?
I use AMD Radeon R9 200 Series.

[QUOTE=babaliaris;1292697]Well People tried to run my application which you can find Here and they told me that they get a nice brick cube and not something like this…
Well, this probably means that my graphics drivers have something wrong with the openGL implementation right?
I use AMD Radeon R9 200 Series.[/QUOTE]

Possibly, but not necessarily. It could be your code has error(s), and the GL drivers those people are running on are just more forgiving of those errors.

If you post a short, stand-alone test program here, you’ll probably get more testing feedback here, and possibly a line on what it is you might be doing wrong (if in-fact you are).

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.