0

I'm completely new to OpenGL and am having trouble sorting out how binding textures and shaders to VBOs works.

I'm using Cinder's texture and shader classes. Here's part of my draw method:

mShader.bind();

myImage.bind();
glPushMatrix();
glTranslated( scaledX, scaledY, scaledZ);
gl::draw(sphere.getVBO());
glPopMatrix();

glPushMatrix();
glTranslated( 0, 0, zshift - 200);
mDisc.draw();
glPopMatrix();

In the above code if I comment out the call to mShader.bind(), my sphere VBO will display the texture (myImage). My shader works fine for plain (untextured) shapes, but when I bind the shader before drawing any shapes with wrapped textures it blocks the textures from being displayed.

Is this a problem with the shader I'm using, or is it something else that I'm not understanding? (...there is still a lot I'm not understanding)

Thanks

edit:

here are the shaders I'm using:

(frag):

uniform sampler2DShadow     depthTexture;

varying vec3                N, V, L;
varying vec4                q;

void main(void)
{
    vec3 normal = normalize( N );
    vec3 R = -normalize( reflect( L, normal ) );

vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(dot( normal, L), 0.0);
vec4 specular = gl_FrontLightProduct[0].specular * pow(max(dot(R, V), 0.0), gl_FrontMaterial.shininess);

vec3 coord = 0.5 * (q.xyz / q.w + 1.0);
float shadow = shadow2D( depthTexture, coord ).r;
gl_FragColor = ((ambient + (0.2 + 0.8 * shadow) * diffuse) + specular * shadow);

}

(vert):

varying vec3        N, V, L;
varying vec4        q;
uniform mat4        shadowTransMatrix;

void main(void)
{
    vec4 eyeCoord = gl_ModelViewMatrix * gl_Vertex;

V = normalize( -eyeCoord.xyz );
L = normalize( gl_LightSource[0].position.xyz - eyeCoord.xyz );
N = gl_NormalMatrix * gl_Normal;

q = shadowTransMatrix * eyeCoord;

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}

3
  • 3
    Show your shader code. Most of the time you will need a different shader for texturing. Also this code is mixing VBOs and shaders with deprecated functions. Commented Aug 1, 2013 at 7:22
  • "I'm using Cinder's texture and shader classes." If you want to understand how OpenGL works, you need to expose yourself to OpenGL, not classes that hide OpenGL. Commented Aug 1, 2013 at 7:25
  • I've added the shaders. I am woking on a project for a psyc class and am very time-limited. I will learn OpenGL properly soon enough, but for now I'm just trying to understand enough to cobble something decent together. Commented Aug 1, 2013 at 8:01

1 Answer 1

5

You must implement the texture sampling yourself in your shader. I see that the shader already uses a shadow texture sampler, is that the texture that you want to use? If so, you have to do this:

  1. Set the active texture unit: glActiveTexture(GL_TEXTURE0);
  2. Activate the texture: probably myImage.bind();
  3. Get the location of the uniform variable 'depthTexture': GLint loc = glGetUniformLocation(program, "depthTexture");
  4. Bind the texture to you texture sampler in the shader: glUniform1i(loc, 0);

Notes: In step 3, you must pass the shader program ID as the first parameter to glGetUniformLocation. I don't know Cinder's texture and shader classes, but I suppose that there is either a way to query them directly for uniform variable locations (or even set the variable values directly), or at least they should allow you to get the program ID. In step 4, you are telling OpenGL to set the depthTexture sampler to the texture of the first texture unit (which has the index 0); you need to do this because you have previously selected this texture unit with glActiveTexture(GL_TEXTURE0);.

Please also see this for a more in-depth example of using textures in shaders.

Sign up to request clarification or add additional context in comments.

6 Comments

With shaders you no longer have to glEnable(GL_TEXTURE_…); Most of what used to be controlled by glEnable state is now defined in terms of shader execution.
ok hmm, yes I am missing some core info here obviously. The shadow texture in the shader is working the way I want it to when I draw geometric shapes using displaylists with materials (a cinder class) set to each list. The problem arises when I want to use that shadow shader on a VBO I've made (by importing an .obj file I made in photoshop); specifically, I can't seem to get the current shader to work with the VBO when I wrap a texture around it (which is just a .png of a flower)
So you want to additionally apply a texture to the faces of the object in your VBO?
Yes. I can get the texture working without the shader, and the shader working without the texture, but not both at the same time. The problem appears to be that I have zero understanding of how shaders work; I was hoping I was missing something simple, but probably not!
Did you check out the tutorial I linked in my answer?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.