1
\$\begingroup\$

I am trying to display a DXT1 compressed texture on a quad using a VBO and shaders, but I have been unable to get it working. All I get is a black square.

I know my texture is uploaded properly because when I use immediate mode without shaders the texture displays fine but I will include that part just in case. Also, when I change the gl_FragColor to something like vec4 (0.0, 1.0, 1.0, 1.0) then I get a nice blue quad so I know that my shader is able to set the colour. It appears to be either the texture is not being bound correctly in the shader or the texture coordinates are not being picked up. However, I can't find the error! What am I doing wrong?

I am using OpenTK in C# (not xna).

Vertex Shader:

void main() {            
    gl_TexCoord[0] = gl_MultiTexCoord0;    
    // Set the position of the current vertex 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment Shader:

uniform sampler2D diffuseTexture;
void main() {
    // Set the output color of our current pixel
    gl_FragColor = texture2D(diffuseTexture, gl_TexCoord[0].st);
    //gl_FragColor = vec4 (0.0,1.0,1.0,1.0);
}

Drawing Code:

int vb, eb;
GL.GenBuffers(1, out vb);
GL.GenBuffers(1, out eb);
//                      Position        Texture
float[] verts = {   0.1f, 0.1f, 0.0f,  0.0f, 0.0f,
                    1.9f, 0.1f, 0.0f,  1.0f, 0.0f,
                    1.9f, 1.9f, 0.0f,  1.0f, 1.0f,
                    0.1f, 1.9f, 0.0f,  0.0f, 1.0f
                };
uint[] indices = {  
                   0, 1, 2,
                   0, 2, 3
                 };

//upload data to the VBO
GL.BindBuffer(BufferTarget.ArrayBuffer, vb);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, eb);

GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(verts.Length * sizeof(float)), verts, BufferUsageHint.StaticDraw);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(uint)), indices, BufferUsageHint.StaticDraw);

//Upload texture
int buffer = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, buffer);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Linear);

GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (float)TextureEnvMode.Modulate);

GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, texture.format, texture.width, texture.height, 0, texture.data.Length, texture.data);

//Draw 
GL.UseProgram(shaderProgram);

GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.TextureCoordArray);

GL.VertexPointer(3, VertexPointerType.Float, 5 * sizeof(float), 0);
GL.TexCoordPointer(2, TexCoordPointerType.Float, 5 * sizeof(float), 3);

GL.ActiveTexture(TextureUnit.Texture0);
GL.Uniform1(GL.GetUniformLocation(shaderProgram, "diffuseTexture"), 0);

GL.DrawElements(BeginMode.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0);
\$\endgroup\$
5
\$\begingroup\$

The last param to your texcoord pointer is an offset in bytes, not floats, so it's 12 (or 3 * sizeof (float) if you prefer).

\$\endgroup\$
  • \$\begingroup\$ Oh . . . I had a feeling it was something simple like that but darn if I could have figured that out. Thanks! \$\endgroup\$ – Chewy Gumball Mar 23 '12 at 2:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.