Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Texture renders as black square

  1. #1
    Newbie Newbie
    Join Date
    May 2017
    Posts
    3

    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:
    Code :
    	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:
    Code :
    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)):
    Code :
    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:
    Code :
    #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:
    Code :
    #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.

  2. #2
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    418
    I haven't read all your post. But here is the first thing I could notice:

    Code :
    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 ?

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

  3. #3
    Advanced Member Frequent Contributor arekkusu's Avatar
    Join Date
    Nov 2003
    Posts
    870
    Quote Originally Posted by perplexedMurfy View Post
    Code :
        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.

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

  4. #4
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    418
    Quote Originally Posted by arekkusu View Post
    Do you understand what glEnableVertexAttribArray() does? What happens to attributes that aren't enabled?
    Haven't seen that.
    +1

  5. #5
    Intern Contributor
    Join Date
    Dec 2016
    Posts
    54
    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

  6. #6
    Advanced Member Frequent Contributor arekkusu's Avatar
    Join Date
    Nov 2003
    Posts
    870
    Quote Originally Posted by OceanJeff40 View Post
    You may not have included the code, but it doesn't look like you pass the image variable to the uniform variable in code.
    Uniforms are initialized to zero by glLinkProgram. Zero matches glActiveTexture(GL_TEXTURE0).

  7. #7
    Newbie Newbie
    Join Date
    May 2017
    Posts
    3
    Quote Originally Posted by arekkusu View Post
    Do you understand what glEnableVertexAttribArray() does? What happens to attributes that aren't enabled?
    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 Originally Posted by Silence View Post
    I haven't read all your post. But here is the first thing I could notice:

    Code :
    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 ?

    Code :
    color = vec4 (spriteColor, 1.0) * texture(image, TexCoords);
    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.

  8. #8
    Advanced Member Frequent Contributor arekkusu's Avatar
    Join Date
    Nov 2003
    Posts
    870
    Quote Originally Posted by perplexedMurfy View Post
    I'm pretty sure that glEnableVertexAttribArray() allows you to actually use the index when you (location = n) in a shader, right?
    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?


    Quote Originally Posted by perplexedMurfy View Post
    Even when I remove the vec4 (spriteColor, 1.0) part it still draws as a black box.
    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.

  9. #9
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,683
    Quote Originally Posted by perplexedMurfy View Post
    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.
    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.

  10. #10
    Newbie Newbie
    Join Date
    May 2017
    Posts
    3
    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;;

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •