Nothing shows while trying to render a texture

Hi! I am trying to render texture a texture. The quad draws well but texture does not want to attach.

Mesh class


void Mesh::CreateQuad(Rect destRect, Rect uvRect, ColorRGBA color, GLuint texture)
{
	this->texture = texture;
        //Vertex is a class that contains 3 structs: Position(float x and y), Color (Glubyte r and g, and b, and a), UV (float u and v)
	Vertex vertex[6];

	vertex[0].color = color;
	vertex[0].setPosition(destRect.x, destRect.y + destRect.h);
	vertex[0].setUV(uvRect.x, uvRect.y + uvRect.h);

	vertex[1].color = color;
	vertex[1].setPosition(destRect.x, destRect.y);
	vertex[1].setUV(uvRect.x, uvRect.y);

	vertex[2].color = color;
	vertex[2].setPosition(destRect.x + destRect.w, destRect.y);
	vertex[2].setUV(uvRect.x + uvRect.w, uvRect.y);

	vertex[3].color = color;
	vertex[3].setPosition(destRect.x + destRect.w, destRect.y + destRect.h);
	vertex[3].setUV(uvRect.x + uvRect.w, uvRect.y + uvRect.h);

	GLuint index[] = {
		0, 1, 2,
		0, 2, 3
	};

	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(Vertex), nullptr, GL_DYNAMIC_DRAW);
	glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(Vertex), vertex);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), nullptr, GL_DYNAMIC_DRAW);
	glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 6 * sizeof(GLuint), index);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Mesh::CreateVertexArray()
{
	if (vao == 0) {
		glGenVertexArrays(1, &vao);
	}
	glBindVertexArray(vao);

	if (vbo == 0) {
		glGenBuffers(1, &vbo);
	}
	glBindBuffer(GL_ARRAY_BUFFER, vbo);

	if (ebo == 0) {
		glGenBuffers(1, &ebo);
	}
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glEnableVertexAttribArray(2);

	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
	glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));

	glGenVertexArrays(1, 0);
}

void Mesh::DrawQuad()
{
	glBindVertexArray(vao);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_FRONT);
	glFrontFace(GL_CW);

	glBindTexture(GL_TEXTURE_2D, texture);
	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);

	glBindVertexArray(0);
	glBindTexture(GL_TEXTURE_2D, 0);

	std::cout << "Texture " << texture << std::endl;
}

texture class



void Texture::Init()
{
        //Creates vbo vao ebo
	mesh.CreateVertexArray();
}

void Texture::LoadFromFile(const std::string & filePath)
{
        //attaches texture to the textureID
	textureID = texture.getTexture(filePath);
}

void Texture::Draw(Rect destRect, Rect uvRect, ColorRGBA color)
{
        //creates and draws a quad with texture ID
	mesh.CreateQuad(destRect, uvRect, color, textureID);
	mesh.DrawQuad();
}

GLuint TextureCache::loadFromFile(const std::string & filePath)
{
	textureMap.clear();

	SDL_Surface* surface = IMG_Load(filePath.c_str());

	GLuint texture = 0;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);

	int format;
	surface->format->BitsPerPixel == 4 ? format = GL_RGBA : format = GL_RGB;

	w = surface->w;
	h = surface->h;

	glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, surface->pixels);

	SDL_FreeSurface(surface);
	glBindTexture(GL_TEXTURE_2D, 0);

	return texture;
}

GLuint TextureCache::getTexture(const std::string & filePath)
{
        //finds texture
	auto texMap = textureMap.find(filePath);

        //if there is no texture create one
	if (texMap == textureMap.end()) {
		GLuint newTexture = loadFromFile(filePath);

		textureMap[filePath] = newTexture;

		return newTexture;
	}
        // else return existing one
	return texMap->second;
}


and a bit of main.cpp


	Texture texture;
	texture.Init();
	texture.LoadFromFile("MenuImage.png");

	Shader shader;
	std::string vertex = shader.LoadFromFile("vertex.shader");
	std::string fragment = shader.LoadFromFile("fragment.shader");
	shader.CreateShaderProgram(vertex.c_str(), fragment.c_str());

	GLint u_textureSampler = shader.GetUniformLocation("u_textureSampler");
	glUniform1f(u_textureSampler, 0);

	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

	bool quit = false;
	SDL_Event event;

	while (!quit) {
		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT) {
				SDL_Quit();
				exit(0);
			}
		}

		glClearDepth(1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		Rect destRect = { -0.5, -0.5, 1.0, 1.0 };
		Rect uvRect = { 0.0, 0.0, 1.0, 1.0f };
		ColorRGBA color = { 255, 0, 255,  255 };

		texture.Draw(destRect, uvRect, color);

		SDL_GL_SwapWindow(window);
	}

and shaders


#version 330 core

layout (location = 0) in vec2 aPosition;
layout (location = 1) in vec4 aColor;
layout (location = 2) in vec2 aUV;

out vec4 v_fragmentColor;
out vec2 v_fragmentUV;

void main()
{
	gl_Position = vec4(aPosition, 0.0, 1.0);

	v_fragmentColor = aColor;
	v_fragmentUV = aUV;
}


#version 330 core

out vec4 outColor;

in vec2 v_fragmentUV;
in vec4 v_fragmentColor;

uniform sampler2D u_textureSampler;

void main()
{
	vec4 textureColor = texture(u_textureSampler, v_fragmentUV);
	outColor = v_fragmentColor * textureColor;
}

And still there is no texture on the screen. There is only nothing :c
Yes, so I know there is a lot of code and I almost said nothing but there is nothing to say. I think my comments attached to code are enough. If you have more questions ask, though. Maybe there is better way to do it. let me know, please.

This call is invalid.

This should be using the BytesPerPixel field, not BitsPerPixel. It won’t handle anything other than 888 or 8888 formats; I don’t know whether you’re likely to encounter those. You can use SDL_ConvertSurfaceFormat() to convert other formats to 888 or 8888. I’d suggest just converting everything to SDL_PIXELFORMAT_RGBA8888 or SDL_PIXELFORMAT_ABGR8888 (depending up byte order) so that you only have to deal with one format. The OpenGL implementation will probably expand GL_RGB8 to 32 bits internally for performance, so you won’t save video memory using RGB.

This doesn’t account for alignment. You need glPixelStorei(GL_UNPACK_ALIGNMENT,1) if you want to support RGB data with arbitrary widths (RGBA data will always have a multiple of 4 bytes per line).

Also, the minification filter is initially GL_NEAREST_MIPMAP_LINEAR, which requires mipmaps. Either change the filter to something which doesn’t require mipmaps with e.g. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR) or generate mipmap levels with e.g. glGenerateMipmap(GL_TEXTURE_2D). Otherwise, texturing is disabled (texture() will return zeros).

Sampler uniforms can only be set with glUniform1i() or glUniform1iv().

[QUOTE=GClements;1290048]This call is invalid.

This should be using the BytesPerPixel field, not BitsPerPixel. It won’t handle anything other than 888 or 8888 formats; I don’t know whether you’re likely to encounter those. You can use SDL_ConvertSurfaceFormat() to convert other formats to 888 or 8888. I’d suggest just converting everything to SDL_PIXELFORMAT_RGBA8888 or SDL_PIXELFORMAT_ABGR8888 (depending up byte order) so that you only have to deal with one format. The OpenGL implementation will probably expand GL_RGB8 to 32 bits internally for performance, so you won’t save video memory using RGB.

This doesn’t account for alignment. You need glPixelStorei(GL_UNPACK_ALIGNMENT,1) if you want to support RGB data with arbitrary widths (RGBA data will always have a multiple of 4 bytes per line).

Also, the minification filter is initially GL_NEAREST_MIPMAP_LINEAR, which requires mipmaps. Either change the filter to something which doesn’t require mipmaps with e.g. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR) or generate mipmap levels with e.g. glGenerateMipmap(GL_TEXTURE_2D). Otherwise, texturing is disabled (texture() will return zeros).

Sampler uniforms can only be set with glUniform1i() or glUniform1iv().[/QUOTE]

Do not know why there is bites per pixel. Going to change it.

However you are not exactly right with uniform, because in the other project I am using the same glUniform1f(u_textureSampler, 0); it works perfectly fine

[QUOTE=DonPedross;1290056]
However you are not exactly right with uniform, because in the other project I am using the same glUniform1f(u_textureSampler, 0); it works perfectly fine[/QUOTE]
The call doesn’t work; the program just happens to work in spite of that.

Are you checking for errors? Setting a sampler variable with glUniform1f() should report GL_INVALID_OPERATION; if it doesn’t, that’s a driver bug. The specification is quite clear on this.

However, the value is likely to be 0 initially (recent versions of the GLSL specification require sampler uniforms without a [var]binding[/var] qualifier to be initialised to 0, but this is typical behaviour in earlier versions), so the fact that the call fails won’t matter in this specific case. If you want to actually change the value, you must use glUniform1i() or glUniform1iv().