vertex shader. fragment shader. Mistakes I made. links to other resource and so on...

OpenGL Texturing the 6 faces of a cube

Search for: OpenGL Texturing the 6 faces of a cube

Here are my previous notes on textures for GL 1.1

2 textures 1 shader

This might answer using multiple textures. I haven't fully read it though how useful

another nice example to read from learnopengles.com

It was pulling teeth. But I have a much better understanding now. Hopefully I will document here some of the pain points.


uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
attribute vec2 aTextureCoordinate;

//out vec2 aTextureCoordinate: This doesn't work
//use varying instead
varying vec2 v_TextureCoordinate;

void main() 
{
   gl_Position = uMVPMatrix * aPosition;
   v_TextureCoordinate = aTextureCoordinate;
}

I have tried to use the "out" modifier on the texture coordinates that travel to the fragment shader. Compiler failed. Instead "varying" seem to work. It may be a question of GLSL version!!! When I know I will let you know.

You can use the following link to discover errors


precision mediump float; //Appears Mandatory for this version of GLSL 
varying vec2 v_TextureCoordinate;
uniform sampler2D s_2DtextureSampler;
void main() 
{
   gl_FragColor = texture2D(s_2DtextureSampler, v_TextureCoordinate);
}

The innocuous-unnecessary-looking precision line at the top is required for this fragment shader to compile.

Also pay attention to the name "sampler2D". I have misspelled it a few times.

Some books seem to use the function "texture" as opposed to "texture2D". Again it may just be a version dependent!!


texture attribute of a vertex is passed to the aTextureAttribute
this is similar to the aVertexAttribute where position is passed
vertex shader simply passes it down through a varying variable
Same variable name is used in fragment shader
a special function called texture2D is used to sample the 
  texture pixel at the fragment.
sampler2D is a special structure in GLSL
sampler2D is initialized in the client to the texture unit

Well, you load the single 2D texture first as a bitmap. And the coordinates will be between (0,0) to (1,1).

Each face of the cube will have 6 vertex coordinates making up 2 triangles. For each of the 6 vertices indicate how each of the vertex is mapped to one of 4 coordinates on the 2D texture above.

Just repeat this for each face.


//front-face: f1,f2,f3,f4
//starting top-right-anti-clockwise    
//f1(1,1) f2(-1,1) f3(-1,-1) f4(1,-1): z plane 0
    
//back-face: b1,b2,b3,b4
//starting bottom-right-anti-clockwise    
//b1(1,-1) b2(1,1) b3(-1,1) b4(-1,-1) : z plane 1
    private float z = 2.0f;
    private final float[] mTriangleVerticesData = {
          //1. front-triangles
          //f1,f2,f3
          1,1,0,        -1,1,0,             -1,-1,0,
          
          //f3,f4,f1
          -1,-1,0,       1,-1,0,          1,1,0,          
          
          //2. back-triangles
          //b1,b2,b3
          1,-1,z,          1,1,z,          -1,1,z,
          //b3,b4,b1
          -1,1,z,          -1,-1,z,          1,-1,z,
          
          //3. right-triangles
          //b2,f1,f4
          1,1,z,          1,1,0,          1,-1,0,
          //b2,f4,b1
          1,1,z,         1,-1,0,         1,-1,z,
          
          //4. left-triangles
          //b3, f2, b4
          -1,1,z,          -1,1,0,          -1,-1,z,
          //b4 f2 f3
          -1,-1,z,          -1,1,0,          -1,-1,0,
          
          //5. top-triangles
          //b2, b3, f2
          1,1,z,         -1,1,z,            -1,1,0,
          //b2, f2, f1
          1,1,z,         -1,1,0,         1,1,0,
          
          //6. bottom-triangles
          //b1, b4, f3
          1,-1,z,      -1,-1,z,   -1,-1,0,
          //b1, f3, f4
          1,-1,z,      -1,-1,0,   1,-1,0
/*
 */          
            };

    //f1(1,1) f2(0,1) f3(0,0) f4(1,0) 
    //b1(1,0) b2(1,1) b3(0,1) b4(0,0)
    private final float[] mTextureData = {
          //1. front-triangles
          //f1,f2,f3
          1,0,         0,0,            0,1,
          //f3,f4,f1
          0,1, 1,1,1,0,                      
          
          //2. back-triangles
          //b1,b2,b3
          1,0,   1,1,   0,1,
          //b3,b4,b1
          0,1,   0,0,   1,0,
          
          //3. right-triangles
          //b2,f1,f4
          1,1,   0,1,   0,0,
          //b2,f4,b1
          1,1,   0,0,   1,0,
          
          //4. left-triangles
          //b3, f2, b4
          0,1,    1,1,    0,0,
          //b4 f2 f3
          0,0,    1,1,    1,0,
          
          //5. top-triangles
          //b2, b3, f2
          1,1,    0,1,    0,0,
          //b2, f2, f1
          1,1,    0,0,    1,0,
          
          //6. bottom-triangles
          //b1, b4, f3
          1,1,   0,1,   0,0,
          //b1, f3, f4
          1,1,   0,0,   1,0
          /*          
*/          
            };

I keep getting this error when I ran my program for a while. The culprit could be anywhere because a client may have called glEnable() for any number of things!!


//GLES20.glEnable(GLES20.GL_TEXTURE_2D);

The figure was skewed and it was getting distorted. Not a clue what was going on. Took me in a number of directions. In the process I found out two ways of loading bitmaps. Turned out to be unrelated however but I will document here anyways.


final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;   // No pre-scaling
         
        // Read in the resource
        final Bitmap bitmap = BitmapFactory.decodeResource(
              MyApplication.m_appContext.getResources(), this.mImageResourceId, options);

InputStream is = MyApplication.m_appContext.getResources()
                .openRawResource(this.mImageResourceId);
        Bitmap bitmap;
        try {
            bitmap = BitmapFactory.decodeStream(is);
        } finally {
            try {
                is.close();
            } catch(IOException e) {
                // Ignore.
            }
        }

Apparently if the resource is not under the "raw" directory Android may try to scale the resource in approach 2. keep that in mind.

Then I have started questioning what should happen where in the call backs


Create, compile, link your shader programs
Bind variables from the shader programs
Load texture
Set your eye

Setup view port
Get your frustum/proj matrix

clear your colors
use gl program
activate texture
translate/rotate/etc transforms
apply eye transformations
apply projection
setup vertex attributes through buffers
transfer buffers to the server
draw

Even after all this textures were totally screwed up: weird shapes!!

No change!!! And there I was passing vertex buffers for texture buffers. So it didn't make a difference what i gave in the texture buffers.

I could but I can't blame OpenGL for all things!! Most things yes.

I will post the entire source code soon ...here