Results 1 to 5 of 5

Thread: Texture Error

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2019
    Posts
    3

    Texture Error

    I've been trying to map a texture onto two triangles. After running into issues, I compressed the code into these few segments. The "Texture" at this point is a single red pixel for testing. You can see it in the variable "pixel". I've checked several tutorials, The OpenGL Programming Guide, and even some older code of mine that worked. I feel like there's a dumb mistake here that I'm just missing.

    I expect it to just draw a giant red square on the screen. Instead the actual drawn image is at the bottom of the post. I set glClearColor to a dark green so that the (accidently) black geometry is visible. Does anyone know what I might have done wrong?

    I can provide more code as requested, thanks.

    Code :
    	 GLint texUniform = glGetUniformLocation(program, "colorMap");
       	SpriteInvariant.texUniform = texUniform;
     
    	Sprite sprite;
    	{
     
    		u8 pixel[4] = { 255, 0, 0, 255};
     
    		 GLuint texture;
    		glGenTextures(1, &texture);
    		glBindTexture(GL_TEXTURE_2D, texture);
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
     
    		sprite = (Sprite) { 
    			.position = (v3) {0,0,-0.5}, 
    			.scale = (v3) {1,1,1},
    			.rotation = QuatFromEuler(0,0,0),
    			.texture = texture
    		};
    	}
     
    	glClearColor(0,0.1,0,1);
    	glClear(GL_COLOR_BUFFER_BIT);
    	{
    		FrameRenderInfo renderState = frameRenderInfo;
    		v2 windowSize = renderState.windowSize;
    		r32 aspectRatio = windowSize.x / windowSize.y;
     
    		mat4 cam = MulMat4(
    				Mat4FromQuat(renderState.camera.rotation),
    				Mat4FromPosition(renderState.camera.position));
    		mat4 proj = MulMat4( 
    				Mat4FromEuler(0,0,0),
    				Mat4FromPerspective(aspectRatio, renderState.camera.fov, renderState.camera.nearPlane, 
    					renderState.camera.farPlane));
    		mat4 view = InvertMat4(cam);
     
    		glUseProgram(SpriteInvariant.shader);
    		glBindVertexArray(SpriteInvariant.vao);
     
    		glUniformMatrix4fv(SpriteInvariant.projectionUniform, 1, GL_FALSE, proj.e);
    		glUniformMatrix4fv(SpriteInvariant.viewSpaceUniform, 1, GL_FALSE, view.e);
     
    		glActiveTexture(GL_TEXTURE0);
    		glBindTexture(GL_TEXTURE_2D, sprite.texture);
    		glUniform1i(SpriteInvariant.texUniform, sprite.texture);
     
    		mat4 modelSpace = MulMat4s( 3,
    				Mat4FromScaleV3(sprite.scale),
    				Mat4FromQuat(sprite.rotation),
    				Mat4FromPosition(sprite.position)
    				);
     
     
    		glUniformMatrix4fv(SpriteInvariant.modelSpaceUniform, 1, GL_FALSE, modelSpace.e);
     
    		glDrawArrays(GL_TRIANGLES, 0, 6);
    	glerror_to_debug(__FILE__,__LINE__);
    	}
     
    	SwapBuffers(deviceContext);

    Shaders:
    Vertex
    Code :
    #version 330 core
     
    in vec3 pos;
    in vec2 uv;
     
    uniform mat4 modelSpace;
    uniform mat4 viewSpace;
    uniform mat4 projection;
     
    out vec4 passPos;
    out vec2 passUv;
     
    void main()
    {
    	vec4 renderPosition = projection * viewSpace * modelSpace * vec4(pos,1f);
     
    	// render position
    	//vec4 renderPosition = projection * vec4(pos,1);
    	gl_Position = renderPosition;
     
    	// vert uv
    	passUv = uv;
     
    	// world position
    	vec4 vertWorldPosition = (modelSpace*vec4(pos,1.0f));
    	passPos = (vertWorldPosition)/vertWorldPosition.w;
    }

    Fragment
    Code :
    #version 330 core
    in vec4 passPos;
    in vec2 passUv;
     
    uniform sampler2D colorMap;
     
    out vec4 color;
     
    void main()
    {
    	float dist = 1.0f - length(passPos)/256.0f;
    	color = texture(colorMap, passUv);//+ vec4(0,passUv.x,passUv.y,1);
    }

    Right now, this code produces this output:
    screen.jpg

  2. #2
    Senior Member Regular Contributor
    Join Date
    Oct 2014
    Posts
    109
    What happens if you use
    Code :
    color = vec4(0,passUv.x,passUv.y,1);
    as output of the fragment shader?

    You can also try to use a much larger texture. Just fill your array with the same values until you get to a size of lets say 256x256. Reason for this is, that I am not sure how the magnification filter works on single pixel textures.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2019
    Posts
    3

    Solution

    Hi ProgrammerX, thanks for you help.

    So I looked into this more today and found the issue. I'm gonna describe it in more detail in case someone from the internet comes in with the same issues I had.

    I checked that the uv coordinates were working properly in the manner ProgrammerX suggested. I mapped passUv to the green and blue components. It looked like this:
    ub.jpg
    So I concluded that that was not the issue.

    In addition, I also became suspicious of the 1 pixel texture. While looking into MipMaps I discovered that mipmaps can only be generated for textures of a size that's a power of 2. (this is not surprising, actually) I figured this would not be an issue since I was not using mipmaps.

    However, because I never used glTexParameter to specify the mag and min filters, they defaulted to ones that require mipmaps.

    This meant that the GPU was not able to bind the textures to the shader as a resource. (Or at least that's what RenderDoc suggests.)
    I was very surprised that glGetError() did not report anything about this.

    In the end, my immediate problem was solved by either:
    - Changing the texture to be 2x2, and calling glGenerateMipMaps.
    OR
    - Setting glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); and glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); which does not need mipmaps and therefore avoids the issue altogether.

    Of course I had one more error, which is that I was calling glActiveTexture(GL_TEXTURE0); which was the wrong slot. I needed to call glActiveTexture(GL_TEXTURE0 + sprite.texture);

    The combination of these two issues solved the problem.

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,103
    Quote Originally Posted by AllBetsAreOff View Post
    In addition, I also became suspicious of the 1 pixel texture. While looking into MipMaps I discovered that mipmaps can only be generated for textures of a size that's a power of 2.
    This is incorrect. Any size texture can have mipmaps. In earlier versions, textures were required to have power-of-two dimensions, but that is ancient history now (and 1=20 is a power of two).

    Quote Originally Posted by AllBetsAreOff View Post
    However, because I never used glTexParameter to specify the mag and min filters, they defaulted to ones that require mipmaps.
    That isn't a problem here, as a 1x1 texture only has a single mipmap level, so it always has all mipmap levels defined. For larger textures, you must define additional levels or use a minification filter which doesn't require mipmaps.

    Quote Originally Posted by AllBetsAreOff View Post
    I was very surprised that glGetError() did not report anything about this.
    Using a minification filter which requires mipmaps with a texture with some levels undefined isn't an error; it just results in texture reads returning zero. However, that isn't an issue for a 1x1 texture, as mentioned above.

    Quote Originally Posted by AllBetsAreOff View Post
    In the end, my immediate problem was solved by either:
    - Changing the texture to be 2x2, and calling glGenerateMipMaps.
    OR
    - Setting glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); and glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); which does not need mipmaps and therefore avoids the issue altogether.
    If that actually affects the result, you have a (fairly serious) driver bug. 1x1 textures are perfectly valid (and not uncommon).

    Quote Originally Posted by AllBetsAreOff View Post
    Of course I had one more error, which is that I was calling glActiveTexture(GL_TEXTURE0); which was the wrong slot. I needed to call glActiveTexture(GL_TEXTURE0 + sprite.texture);

    The combination of these two issues solved the problem.
    Are you sure it wasn't just the second one?

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2019
    Posts
    3

    Follow Up

    Hey GClements,

    I went back to confirm that the behavior was the way that I though it was, and after doing some more testing today, I have found that you were right on every count.

    So that was embarrassing to discover, but thank you for your corrections.

Similar Threads

  1. Texture error
    By Dennis in forum OpenGL: Basic Coding
    Replies: 8
    Last Post: 08-29-2011, 12:54 PM
  2. Replies: 1
    Last Post: 09-24-2007, 04:02 AM
  3. 3D Texture error on ATI
    By Zodiac in forum OpenGL: Advanced Coding
    Replies: 2
    Last Post: 02-05-2005, 01:35 AM
  4. Odd Texture Error
    By swamster in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 05-29-2003, 01:37 PM
  5. Texture error
    By FatalError in forum OpenGL: Basic Coding
    Replies: 3
    Last Post: 04-04-2001, 08:12 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean