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 7 of 7

Thread: Texturing using shaders

  1. #1
    Intern Newbie
    Join Date
    Jul 2013
    Posts
    35

    Texturing using shaders

    I'm trying to upgrade my code to modern OpenGL, so far I've successfully got a rectangular VBO drawn on the screen and was able to get it textured without shaders. But now I'm having trouble getting the texture displayed when using shaders.

    As said before, I have gotten the texture to be drawn on the VBO without using shaders, so texture loading is not the issue here, I have also checked that the shaders are successfully compiled and binded to a program object, so you can rule that out too.

    Here is my code, I hope this is all that is needed since I've done the error checking stated above however if you do, just ask.

    main.c (slighlty simplified):
    Code :
    GLuint titleTexture;
    loadTexture(binary_title_jpg_start, (size_t)binary_title_jpg_size, &titleTexture, SOIL_FLAG_COMPRESS_TO_DXT);
    short titleShader = compileShaders(binary_testVertex_glsl_start, (size_t)binary_testVertex_glsl_size, binary_testFragment_glsl_start, (size_t)binary_testFragment_glsl_size);
     
    while(1) {
    	glUseProgram(titleShader);
    	glEnable(GL_TEXTURE_2D);
    	glActiveTexture(GL_TEXTURE0_ARB);
    	int textureSampler = glGetUniformLocation(titleShader, "textureS");
    	glUniform1i(textureSampler, titleTexture);
    	glBindTexture(GL_TEXTURE_2D, titleTexture);
    	drawVBO(&menuBackground);
    	glDisable(GL_TEXTURE_2D);
    	glUseProgram(0);
    }

    testVertex.glsl:
    Code :
    void main() {
    	gl_TexCoord[0] = gl_MultiTexCoord0;
    	gl_Position = gl_Vertex * gl_ModelViewProjectionMatrix;
    }

    testFragment.glsl:
    Code :
    uniform sampler2D textureS;
     
    void main(void) {
    	gl_FragColor = texture2D(textureS, gl_TexCoord[0].st);
    }

    The VBO rendered is just plain black, what's up with that?

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Posts
    757
    Code :
    glUniform1i(textureSampler, titleTexture);

    You are setting the sampler uniform to the id of the texture object, you should set it to the texture unit (0 in your case) you want to sample from.

  3. #3
    Intern Newbie
    Join Date
    Jul 2013
    Posts
    35
    Thanks for your help, now the whole rectangle is one solid color which appears to be the first color in the image; so what else is wrong? Do I need to glEnable anything else perhaps?

  4. #4
    Member Regular Contributor
    Join Date
    Jan 2012
    Location
    Germany
    Posts
    325
    Hello,

    sounds like your texture coordinates are wrong. Maybe seeing how they are defined would help. One additional note: If you really want to upgrade to modern OpenGL, you also want to get rid of the build-in variables gl_TexCoord, gl_MultiTexCoord0, gl_ModelViewProjectionMatrix, gl_FragColor, gl_Vertex, gl_ModelViewProjectionMatrix etc (basically everything except gl_Position). Enabling and disabling Texture_2D is also not used in modern GL anymore. As textures are not an extension anymore, I would also change GL_TEXTURE0_ARB to GL_TEXTURE0.

  5. #5
    Intern Newbie
    Join Date
    Jul 2013
    Posts
    35
    Thanks for your answer, I have made slight adaptations to my loopMenu function, as well as updating testVertex.glsl; my drawing code which shows how my texture coords are set up is also here.

    I know it's a lot of code so thanks again for taking the time to look through it all.

    My OpenGL version is 3.1.0, so it should be high enough to do this, no?

    relevant parts of draw.c and draw.h:
    Code :
    typedef struct {
    	float s;
    	float t;
    } textureCoord;
     
    typedef struct {
    	float x;
    	float y;
    	float z;
    } vertexLocation;
     
    typedef struct {
    	vertexLocation vertLo;
    	textureCoord textCo;
    } vertex;
     
    typedef struct {
    	GLuint VBOIndex;
    	vertex *vertices;
    	int vertexCount;
    } VBO;
     
    short createRectangeVBO(VBO *object, int width, int height) {
    	object->vertices = NULL;
    	object->vertices = malloc(4 * sizeof(vertex));
    	if(object->vertices == NULL) return 0;
     
    	object->vertexCount = 4;
     
    	if(!generateRectangleVerts(object, width, height)) return 0;
    	if(!generateRectangleTextureCoords(object)) return 0;
    	storeVBO(object);
     
    	return 1;
    }
     
    short generateRectangleVerts(VBO *object, int width, int height) {
    	if(object->vertexCount != 4) return 0;
     
    	object->vertices[0].vertLo.x = 0.0f;
    	object->vertices[0].vertLo.y = 0.0f;
    	object->vertices[0].vertLo.z = 0.0f;
     
    	object->vertices[1].vertLo.x = width;
    	object->vertices[1].vertLo.y = 0.0f;
    	object->vertices[1].vertLo.z = 0.0f;
     
    	object->vertices[2].vertLo.x = width;
    	object->vertices[2].vertLo.y = height;
    	object->vertices[2].vertLo.z = 0.0f;
     
    	object->vertices[3].vertLo.x = 0.0f;
    	object->vertices[3].vertLo.y = height;
    	object->vertices[3].vertLo.z = 0.0f;
     
    	return 1;
    }
     
    short generateRectangleTextureCoords(VBO *object) {
    	object->vertices[0].textCo.s = 0;
    	object->vertices[0].textCo.t = 0;
     
    	object->vertices[1].textCo.s = 1;
    	object->vertices[1].textCo.t = 0;
     
    	object->vertices[2].textCo.s = 1;
    	object->vertices[2].textCo.t = 1;
     
    	object->vertices[3].textCo.s = 0;
    	object->vertices[3].textCo.t = 1;
     
    	return 1;
    }
     
    void storeVBO(VBO *object) {
    	glGenBuffers(1, &object->VBOIndex);
    	glBindBuffer(GL_ARRAY_BUFFER, object->VBOIndex);
    	glBufferData(GL_ARRAY_BUFFER, object->vertexCount * sizeof(vertex), object->vertices, GL_STATIC_DRAW);
    }
     
    void drawVBO(VBO *object) {
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     
    	glBindBuffer(GL_ARRAY_BUFFER, object->VBOIndex);
    	glVertexPointer(3, GL_FLOAT, sizeof(vertex), NULL);
    	glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (void *)(3 * sizeof(float)));
    	glDrawArrays(GL_QUADS, 0, object->vertexCount);
     
    	glDisableClientState(GL_VERTEX_ARRAY);
    	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    }
     
    void freeVBO(VBO *object) {
    	object->vertexCount = 0;
    	free(object->vertices);
    }

    testVertex.glsl:
    Code :
    void main() {
    	gl_TexCoord[0] = gl_MultiTexCoord0;
    	gl_Position = gl_Vertex;
    }

    testFragment.glsl:
    Code :
    uniform sampler2D textureS;
     
    void main(void) {
    	gl_FragColor = texture2D(textureS, gl_TexCoord[0].st);
    	//gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
    }

    menu.c:
    Code :
    VBO menuBackground;
     
    short titleShader = 0;
     
    short initMenu(void) {
    	if(!loadTexture(binary_title_jpg_start, (size_t)binary_title_jpg_size, &titleTexture, SOIL_FLAG_COMPRESS_TO_DXT)) {
    		return 0;
    	}
    	if(!createRectangeVBO(&menuBackground, getWidth(), getHeight())) {
    		return 0;
    	}
    	titleShader = compileShaders(binary_testVertex_glsl_start, (size_t)binary_testVertex_glsl_size, binary_testFragment_glsl_start, (size_t)binary_testFragment_glsl_size);
    	if(!titleShader) {
    		return 0;
    	}
    	return 1;
    }
     
    void loopMenu(void) {
    	glUseProgram(titleShader);
    	glActiveTexture(GL_TEXTURE0);
    	int textureSampler = glGetUniformLocation(titleShader, "textureS");
    	glUniform1i(textureSampler, 0);
    	glBindTexture(GL_TEXTURE_2D, titleTexture);
    	drawVBO(&menuBackground);
    	glUseProgram(0);
    }
     
    void deinitMenu(void) {
    	freeVBO(&menuBackground);
    }
    Last edited by Quaver; 09-14-2013 at 06:46 AM.

  6. #6
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    491
    Your vertex coordinates are derived from integers width and height, but you're storing them in gl_Position (which is in clip coordinates) without any transformation (the projection and model-view matrices aren't being used). If GetWidth() and GetHeight() are returning integers much larger than 1, your quad will be much larger than the viewport, resulting in only a small portion of it being visible.

    The projection and model-view matrices are available to the shader via the compatibility variables gl_ModelViewMatrix and gl_ProjectionMatrix (and their concatenation is available via gl_ModelViewProjectionMatrix), but the shader has to use them explicitly, e.g.:
    Code :
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

  7. #7
    Intern Newbie
    Join Date
    Jul 2013
    Posts
    35
    Thanks very much!

Posting Permissions

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