Texture renders as black square

Hi all, I’m currently trying to render a textured quad but for some reason the quad always appears as black.
I’ve made sure that the file is present, and the library that I’m useing (SOIL) is loading it correctly.
Here are some rellevent parts

Image loading:


	int iwidth, iheight;
	unsigned char* image = SOIL_load_image ("img.jpg", &iwidth, &iheight, NULL, SOIL_LOAD_RGB);
	
	GLuint texture;
	glGenTextures (1, &texture);
	glBindTexture (GL_TEXTURE_2D, texture);
	glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, iwidth, iheight, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glGenerateMipmap (GL_TEXTURE_2D);

	SOIL_free_image_data (image);
	glBindTexture (GL_TEXTURE_2D, 0);

Set up for Renderer:


void SpriteRenderer::init () {
	GLuint vbo;
	GLfloat verts[] = {	// pos(2) texcoord(2)
		0.0f, 1.0f, 0.0f, 1.0f,
		1.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 0.0f, 0.0f,

		0.0f, 1.0f, 0.0f, 1.0f,
		1.0f, 1.0f, 1.0f, 1.0f,
		1.0f, 0.0f, 1.0f, 0.0f};
	glGenVertexArrays (1, &Vao);
	glGenBuffers (1, &vbo);

	glBindBuffer (GL_ARRAY_BUFFER, vbo);
	glBufferData (GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

	glBindVertexArray (Vao);
	glEnableVertexAttribArray (0);
	glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
	glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(sizeof(GLfloat) * 2));
	glBindBuffer (GL_ARRAY_BUFFER, 0);
	glBindVertexArray (0);
}

Rendering (texture from above is passed to this function as tex and color is(1.0f, 1.0f, 1.0f)):


void SpriteRenderer::drawSprite (unsigned int tex, V2 pos, V2 size, float rotation, V3 color) {
	Shader->use ();
	glm::mat4 model;
	model = glm::translate (model, V3(pos, 0.0f));

	model = glm::translate (model, V3(0.5f * size.x, 0.5f * size.y, 0.0f));
	model = glm::rotate (model, rotation, V3(0.0f, 0.0f, 1.0f));
	model = glm::translate (model, V3(-0.5f * size.x, -0.5f * size.y, 0.0f));

	model = glm::scale (model, V3(size, 1.0f));

	Shader->setMat4 ("model", model);
	Shader->setV3 ("spriteColor", color);

	glActiveTexture (GL_TEXTURE0);
	glBindTexture (GL_TEXTURE_2D, tex);

	glBindVertexArray (Vao);
	glDrawArrays (GL_TRIANGLES, 0, 6);

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

The vertex shader:


#version 330 core
layout (location = 0) in vec2 pos;
layout (location = 1) in vec2 texcoord;

uniform mat4 model;
uniform mat4 projection;

out vec2 TexCoords;

void main () {
	TexCoords = texcoord;
	gl_Position = projection * model * vec4(pos, 0.0, 1.0);
}

And fragment shader:


#version 330 core
in vec2 TexCoords;

uniform sampler2D image;
uniform vec3 spriteColor;

out vec4 color;

void main () {
	color = vec4 (spriteColor, 1.0) * texture(image, TexCoords);
}

What’s even stranger is that there I’m able to render text just fine, which is just lots of textured quads, so I’m really at a loss for what’s going wrong here. Thank you for any help.

I haven’t read all your post. But here is the first thing I could notice:


glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenerateMipmap (GL_TEXTURE_2D);

Your parameters don’t go along with mipmapping. So whether don’t generate mipmaps, whether choose mipmap compatible parameters.

Plus, what color do you send as spriteColor ?


color = vec4 (spriteColor, 1.0) * texture(image, TexCoords);

[QUOTE=perplexedMurfy;1287104]


    glBindVertexArray (Vao);
    glEnableVertexAttribArray (0);
    glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
    glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(sizeof(GLfloat) * 2));

I’m really at a loss for what’s going wrong here.[/QUOTE]

Do you understand what glEnableVertexAttribArray() does? What happens to attributes that aren’t enabled?

Haven’t seen that.
+1

You may not have included the code, but it doesn’t look like you pass the image variable to the uniform variable in code.

glGetUniformLocation

and

glUniform****

Regards,
Jeff

Uniforms are initialized to zero by glLinkProgram. Zero matches glActiveTexture(GL_TEXTURE0).

I… I can’t believe I missed that. I’m pretty sure that glEnableVertexAttribArray() allows you to actually use the index when you (location = n) in a shader, right?
Dispite enableing both of them now it still appears as a black box.

[QUOTE=Silence;1287111]I haven’t read all your post. But here is the first thing I could notice:


glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenerateMipmap (GL_TEXTURE_2D);

Your parameters don’t go along with mipmapping. So whether don’t generate mipmaps, whether choose mipmap compatible parameters.

Plus, what color do you send as spriteColor ?


color = vec4 (spriteColor, 1.0) * texture(image, TexCoords);

[/QUOTE]

I don’t follow what you’re saying for mipmapping, checking docs.gl it appears that GL_NEAREST is a-ok for GL_TEXTURE_MAG_FILTER and GL_TEXTURE_MIN_FILTER. I have a feeling that I missed the point there though.
spriteColor has always been set to (1, 1, 1) for my tests, so I don’t think that should be the source of it. Even when I remove the vec4 (spriteColor, 1.0) part it still draws as a black box.

Also sorry for the lateness, I’ve had real life stuff tie me up from checking back at this thread for the past week, I should be a lot more prompt now that it’s over with.

No. You can use up to MAX_VERTEX_ATTRIBS locations in your vertex shader. Attributes which are enabled will be read from your vertex arrays. Attributes which are not enabled will read from the constant "current’ vertex. Did you read the instructions?

So, you eliminated one of the three inputs to your fragment shader and verified it wasn’t the source of your bug. Keep doing that. Delete the sampler from your fragment shader and verify that TexCoords is correct.

You don’t have a mip filter set which means your texture isn’t going to be mipmapped. The mag and min filters specify how a texture is magnified or minified, the mip filter specifies how it blends between mip levels, and not specifying a mip filter is equivalent to saying: “draw this without mipmapping”.

In OpenGL specifying the mip filter is done as part of the min filter, and uses filter names in the format GL_MIPMAP, where the first * is the min filter and the second * is the mip filter. Going by the rest of your code I would suggest that GL_NEAREST_MIPMAP_NEAREST is what you want, although you could try GL_NEAREST_MIPMAP_LINEAR for the crunchy pixel look but with less abrupt transitions between mip levels.

Thank you for all of the help, turns out I was linking the wrong frag shader, namely one that doesn’t have texcoords nor a sampler. I’m really thankful for all of the pointers you guys did give! I wasn’t aware that it was nessarry to set a mipmap filter, or what it was before this! Sorry it was just a copy-paste error;;