Could not show multiple textures

This topic contains 20 replies, has 4 voices, and was last updated by  renaissance 6 years, 11 months ago.

Viewing 15 posts - 1 through 15 (of 21 total)
  • Author
    Posts
  • #30326

    I use the PVRTTextureLoadFromPVR to load two different textures into two different GLuint as following

     

     if(PVRTTextureLoadFromPVR(c_sz_BK_TextureFile, &m_uiBKTex) != PVR_SUCCESS)
     {
      PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
      return false;
     }

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

     if(PVRTTextureLoadFromPVR(c_sz_FG_TextureFile, &m_uiFGTex) != PVR_SUCCESS)
     {
      PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
      return false;
     }

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

     

    In the RenderScene function, I did the following

     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
     glActiveTexture(GL_TEXTURE1);
     glBindTexture(GL_TEXTURE_2D, m_uiFGTex);

     

    Then I draw two planes, one big and one small. Each is with the corresponding texture. However, I always see the same texture is mapped on both planes. The second one is not mapped on the 2nd plane as I expected.

     

    Can you give me a hint why I could not map the 2nd texture?

     

     
    #34445

    Here is the complete source code.

     

    #include <math.h>
    #include <stdio.h>

    #include <EGL/egl.h>
    #include <GLES2/gl2.h>
    #include “OGLES2Tools.h” 
    #include “PVRShell.h”

    // Index to bind the attributes to vertex shaders
    #define VERTEX_ARRAY 0
    #define TEXCOORD_ARRAY 1
    #define NORMAL_ARRAY 2
    #define COLOR_ARRAY  3

    const char c_sz_BK_TextureFile[]  = “BG-m.pvr”;
    const char c_sz_FG_TextureFile[]  = “FG-m.pvr”;

    //two triangles
    GLfloat BK_TRIANGLE_VETEX[18] ={
    -1.0f, 1.0f, -1.0f,
    1.0f, 1.0f, -1.0f,
    1.0f, -1.0f, -1.0f,
    -1.0f, 1.0f, -1.0f,
    1.0f, -1.0f, -1.0f,
    -1.0f, -1.0f, -1.0f
    };

    //normal for each vertex of the two triangles
    GLfloat BK_TRIANGLE_NORMAL[18] = {
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f};

    GLfloat BK_TRIANGLE_COLOR[24] = {
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f};

    GLfloat BK_TRIANGLE_TEXTCOORD[12] = {
            0.0f,1.0f ,   // UVs
            1.0f,1.0f ,
            1.0f,0.0f,
            0.0f,1.0f ,  
            1.0f,0.0f ,
            0.0f,0.0f};

     

    //two triangles as popup button
    GLfloat FG_TRIANGLE_VETEX[18] ={
    0.55f, 0.22f, 1.0f,
    1.0f, 0.22f, 1.0f,
    1.0f, -1.0f, 1.0f,
    0.55f, 0.22f,  1.0f,
    1.0f, -1.0f, 1.0f,
    0.55f, -1.0f, 1.0f
    };

    //normal for each vertex of the two triangles as popup button
    GLfloat FG_TRIANGLE_NORMAL[18] = {
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f};

    GLfloat FG_TRIANGLE_COLOR[24] = {
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f};

    GLfloat FG_TRIANGLE_TEXTCOORD[12] = {
            0.0f,1.0f ,   // UVs
            1.0f,1.0f ,
            1.0f,0.0f,
            0.0f,1.0f ,  
            1.0f,0.0f ,
            0.0f,0.0f};

    /*!****************************************************************************
     Class implementing the PVRShell functions.
    ******************************************************************************/
    class OGLESBasicTnL : public PVRShell
    {
     // The vertex and fragment shader OpenGL handles
     GLuint m_uiVertexShader, m_uiFragShader;

     // The program object containing the 2 shader objects
     GLuint m_uiProgramObject;

     // Texture handle
     GLuint m_uiBKTex;
     GLuint m_uiFGTex;

    public:
     virtual bool InitApplication();
     virtual bool InitView();
     virtual bool ReleaseView();
     virtual bool QuitApplication();
     virtual bool RenderScene();
    };

    /*!****************************************************************************
     @Function  InitApplication
     @Return  bool  true if no error occured
     @Description Code in InitApplication() will be called by PVRShell once per
        run, before the rendering context is created.
        Used to initialize variables that are not dependant on it
        (e.g. external modules, loading meshes, etc.)
        If the rendering context is lost, InitApplication() will
        not be called again.
    ******************************************************************************/
    bool OGLESBasicTnL::InitApplication()
    {
        bool m_bUseVertexProgram = true;

     return true;
    }

    /*!****************************************************************************
     @Function  QuitApplication
     @Return  bool  true if no error occured
     @Description Code in QuitApplication() will be called by PVRShell once per
        run, just before exiting the program.
        If the rendering context is lost, QuitApplication() will
        not be called.
    ******************************************************************************/
    bool OGLESBasicTnL::QuitApplication()
    {
        return true;
    }

    /*!****************************************************************************
     @Function  InitView
     @Return  bool  true if no error occured
     @Description Code in InitView() will be called by PVRShell upon
        initialization or after a change in the rendering context.
        Used to initialize variables that are dependant on the rendering
        context (e.g. textures, vertex buffers, etc.)
    ******************************************************************************/
    bool OGLESBasicTnL::InitView()
    {
     // Fragment and vertex shaders code

     char* pszFragShader = “
      uniform sampler2D sampler2d;
      varying mediump float varDot;
      varying mediump vec2 varCoord;
      varying mediump vec4 v_primaryColor;
      void main (void)
      {
       gl_FragColor = texture2D(sampler2d,varCoord) * varDot*v_primaryColor;
      }”;
     char* pszVertShader = “
      attribute highp vec4 myVertex;
      attribute mediump vec3 myNormal;
      attribute mediump vec4 myUV;
      attribute mediump vec4  myColor;
      uniform mediump mat4 myPMVMatrix;
      uniform mediump vec4 myTMatrix;
      uniform mediump float myScale;
      uniform mediump float myYScale;
      uniform mediump mat3 myModelViewIT;
      uniform mediump vec3 myLightDirection;
      varying mediump float varDot;
      varying mediump vec2 varCoord;
      varying mediump vec4 v_primaryColor;
      void main(void)
      {
       v_primaryColor = myColor;
       gl_Position = (myPMVMatrix * myVertex);
       gl_Position.x = gl_Position.x*myScale;
       gl_Position.y = gl_Position.y*myScale*myYScale;
       gl_Position.z = gl_Position.z*myScale;
       gl_Position = gl_Position + myTMatrix;
       varCoord = myUV.st;
       mediump vec3 transNormal = myModelViewIT * myNormal;
       varDot = max( dot(transNormal, myLightDirection), 0.0 );
      }”;

     // Create the fragment shader object
     m_uiFragShader = glCreateShader(GL_FRAGMENT_SHADER);

     // Load the source code into it
     glShaderSource(m_uiFragShader, 1, (const char**)&pszFragShader, NULL);

     // Compile the source code
     glCompileShader(m_uiFragShader);

     // Check if compilation succeeded
     GLint bShaderCompiled;
        glGetShaderiv(m_uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled);
     if (!bShaderCompiled)
     {
      // An error happened, first retrieve the length of the log message
      int i32InfoLogLength, i32CharsWritten;
      glGetShaderiv(m_uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);

      // Allocate enough space for the message and retrieve it
      char* pszInfoLog = new char[i32InfoLogLength];
            glGetShaderInfoLog(m_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);

      /*
       Displays the message in a dialog box when the application quits
       using the shell PVRShellSet function with first parameter prefExitMessage.
      */
      char* pszMsg = new char[i32InfoLogLength+256];
      sprintf(pszMsg, “Failed to compile fragment shader: %s”, pszInfoLog);
      PVRShellSet(prefExitMessage, pszMsg);
      delete [] pszMsg;
      delete [] pszInfoLog;
      return false;
     }

     // Loads the vertex shader in the same way
     m_uiVertexShader = glCreateShader(GL_VERTEX_SHADER);
     glShaderSource(m_uiVertexShader, 1, (const char**)&pszVertShader, NULL);
     glCompileShader(m_uiVertexShader);
        glGetShaderiv(m_uiVertexShader, GL_COMPILE_STATUS, &bShaderCompiled);
     if (!bShaderCompiled)
     {
      int i32InfoLogLength, i32CharsWritten;
      glGetShaderiv(m_uiVertexShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
      char* pszInfoLog = new char[i32InfoLogLength];
            glGetShaderInfoLog(m_uiVertexShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
      char* pszMsg = new char[i32InfoLogLength+256];
      sprintf(pszMsg, “Failed to compile vertex shader: %s”, pszInfoLog);
      PVRShellSet(prefExitMessage, pszMsg);
      delete [] pszMsg;
      delete [] pszInfoLog;
      return false;
     }

     // Create the shader program
        m_uiProgramObject = glCreateProgram();

     // Attach the fragment and vertex shaders to it
        glAttachShader(m_uiProgramObject, m_uiFragShader);
        glAttachShader(m_uiProgramObject, m_uiVertexShader);

     // Bind the custom vertex attribute “myVertex” to location VERTEX_ARRAY
        glBindAttribLocation(m_uiProgramObject, VERTEX_ARRAY, “myVertex”);
     // Bind the custom vertex attribute “myUV” to location TEXCOORD_ARRAY
        glBindAttribLocation(m_uiProgramObject, TEXCOORD_ARRAY, “myUV”);
     // Bind the custom vertex attribute “myNormal” to location NORMAL_ARRAY
        glBindAttribLocation(m_uiProgramObject, NORMAL_ARRAY, “myNormal”);
     // Bind the custom vertex attribute “myColor” to location COLOR_ARRAY
        glBindAttribLocation(m_uiProgramObject, COLOR_ARRAY, “myColor”);
     // Link the program
        glLinkProgram(m_uiProgramObject);

     // Check if linking succeeded in the same way we checked for compilation success
        GLint bLinked;
        glGetProgramiv(m_uiProgramObject, GL_LINK_STATUS, &bLinked);
     if (!bLinked)
     {
      int i32InfoLogLength, i32CharsWritten;
      glGetProgramiv(m_uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
      char* pszInfoLog = new char[i32InfoLogLength];
      glGetProgramInfoLog(m_uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
      char* pszMsg = new char[i32InfoLogLength+256];
      sprintf(pszMsg, “Failed to link program: %s”, pszInfoLog);
      PVRShellSet(prefExitMessage, pszMsg);
      delete [] pszMsg;
      delete [] pszInfoLog;
      return false;
     }
     
     if(PVRTTextureLoadFromPVR(c_sz_BK_TextureFile, &m_uiBKTex) != PVR_SUCCESS)
     {
      PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
      return false;
     }

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

     if(PVRTTextureLoadFromPVR(c_sz_FG_TextureFile, &m_uiFGTex) != PVR_SUCCESS)
     {
      PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
      return false;
     }

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

     return true;
    }

    /*!****************************************************************************
     @Function  ReleaseView
     @Return  bool  true if no error occured
     @Description Code in ReleaseView() will be called by PVRShell when the
        application quits or before a change in the rendering context.
    ******************************************************************************/
    bool OGLESBasicTnL::ReleaseView()
    {
     // Frees the texture
     glDeleteTextures(1, &m_uiBKTex);
     glDeleteTextures(1, &m_uiFGTex);

     // Frees the OpenGL handles for the program and the 2 shaders
     glDeleteProgram(m_uiProgramObject);
     glDeleteShader(m_uiVertexShader);
     glDeleteShader(m_uiFragShader);

     return true;
    }

    /*!****************************************************************************
     @Function  RenderScene
     @Return  bool  true if no error occured
     @Description Main rendering loop function of the program. The shell will
        call this function every frame.
        eglSwapBuffers() will be performed by PVRShell automatically.
        PVRShell will also manage important OS events.
        Will also manage relevent OS events. The user has access to
        these events through an abstraction layer provided by PVRShell.
    ******************************************************************************/
    bool OGLESBasicTnL::RenderScene()
    {
     glViewport(0, 0, 800, 600);
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

     glUseProgram(m_uiProgramObject);

     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
     glActiveTexture(GL_TEXTURE1);
     glBindTexture(GL_TEXTURE_2D, m_uiFGTex);

     glEnable(GL_CULL_FACE);
     glCullFace(GL_FRONT);

     // Clears the color and depth buffer
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

     //*************************************************************************
     //Draw the background
     //*************************************************************************

     float alpha = 0;  //-p
     float beta =  0;  //-q
     float theta = 0;           // o

     float aModelViewIT0[] =
     {
      cos(theta)*cos(alpha), cos(alpha)*sin(beta)*sin(theta)-sin(alpha)*cos(beta), cos(alpha)*cos(beta)*sin(theta)+sin(alpha)*sin(beta),
      cos(theta)*sin(alpha), sin(alpha)*sin(beta)*sin(theta)+cos(alpha)*cos(beta), sin(alpha)*cos(beta)*sin(theta)-sin(beta)*cos(alpha),
      -sin(theta),   sin(beta)*cos(theta),         cos(beta)*cos(theta)
     };

     /*
      Bind the projection model view matrix (PMVMatrix) to the
      corresponding uniform variable in the shader.
      This matrix is used in the vertex shader to transform the vertices.
     */
     float aPMVMatrix0[] =
     {
      cos(theta)*cos(alpha), cos(alpha)*sin(beta)*sin(theta)-sin(alpha)*cos(beta), cos(alpha)*cos(beta)*sin(theta)+sin(alpha)*sin(beta), 0,
      cos(theta)*sin(alpha), sin(alpha)*sin(beta)*sin(theta)+cos(alpha)*cos(beta), sin(alpha)*cos(beta)*sin(theta)-sin(beta)*cos(alpha),0,
      -sin(theta),   sin(beta)*cos(theta),         cos(beta)*cos(theta),0,
      0,0,0,1
     };

     int i32Location = glGetUniformLocation(m_uiProgramObject, “myPMVMatrix”);
     glUniformMatrix4fv( i32Location, 1, GL_FALSE, aPMVMatrix0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myModelViewIT”);
     glUniformMatrix3fv( i32Location, 1, GL_FALSE, aModelViewIT0);

     float aTMatrix0[] = {0.0f,0.0f,0.0f,0.0f};
     i32Location = glGetUniformLocation(m_uiProgramObject, “myTMatrix”);
     glUniform4fv( i32Location,1,aTMatrix0);

     float aScale0 = 1.0;
     i32Location = glGetUniformLocation(m_uiProgramObject, “myScale”);
     glUniform1f( i32Location,aScale0);

     float aYScale0 = 1.0;
     i32Location = glGetUniformLocation(m_uiProgramObject, “myYScale”);
     glUniform1f( i32Location,aYScale0);

     // Bind the Light Direction vector to the shader
     i32Location = glGetUniformLocation(m_uiProgramObject, “myLightDirection”); 
     glUniform3f( i32Location, 0, 0, 1.5);

     //*************************************************************************
     //Draw the background
     //*************************************************************************
     glEnableVertexAttribArray(VERTEX_ARRAY);
     glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_VETEX);
     
     glEnableVertexAttribArray(NORMAL_ARRAY);
     glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_NORMAL);

     glEnableVertexAttribArray(TEXCOORD_ARRAY); 
     glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_TEXTCOORD);

     glEnableVertexAttribArray(COLOR_ARRAY); 
     glVertexAttribPointer(COLOR_ARRAY, 4, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_COLOR);

     glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
     // Draws a non-indexed triangle array
     glDrawArrays(GL_TRIANGLES, 0,6);

     glUseProgram(m_uiProgramObject);
     //*************************************************************************
     //Draw the foreground
     //*************************************************************************
     glViewport(0, 0, 800, 600);
     i32Location = glGetUniformLocation(m_uiProgramObject, “myPMVMatrix”);
     glUniformMatrix4fv( i32Location, 1, GL_FALSE, aPMVMatrix0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myModelViewIT”);
     glUniformMatrix3fv( i32Location, 1, GL_FALSE, aModelViewIT0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myTMatrix”);
     glUniform4fv( i32Location,1,aTMatrix0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myScale”);
     glUniform1f( i32Location,aScale0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myYScale”);
     glUniform1f( i32Location,aYScale0);
     
     i32Location = glGetUniformLocation(m_uiProgramObject, “myLightDirection”);
     glUniform3f( i32Location, 0, 0, 1.5);

     glEnableVertexAttribArray(VERTEX_ARRAY);
     glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_VETEX);
     
     glEnableVertexAttribArray(NORMAL_ARRAY);
     glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_NORMAL);

     glEnableVertexAttribArray(TEXCOORD_ARRAY);  
     glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_TEXTCOORD); 

     glEnableVertexAttribArray(COLOR_ARRAY); 
     glVertexAttribPointer(COLOR_ARRAY, 4, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_COLOR);

     glBindTexture(GL_TEXTURE_2D, m_uiFGTex); 
     // Draws a non-indexed triangle array
     glDrawArrays(GL_TRIANGLES, 0,6);

     return true;

    }

    /*!****************************************************************************
     @Function  NewDemo
     @Return  PVRShell*  The demo supplied by the user
     @Description This function must be implemented by the user of the shell.
        The user should return its PVRShell object defining the
        behaviour of the application.
    ******************************************************************************/
    PVRShell* NewDemo()
    {
     return new OGLESBasicTnL();
    }

    /******************************************************************************
     End of file (OGLESBasicTnL.cpp)
    ******************************************************************************/
    #34446

    Hi renaissance,< ?: prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    The reason you are getting this problem seems to stem from your use of glActiveTexture. GL has up to 8 active texture units, GL_TEXTURE0-7 which can be used for multitexturing.

    You’ve assigned your background to active texture 0 and then the foreground to active texture 1. Calls to glActiveTexture() are used to bind a given texture to your specified texture unit (e.g. GL_TEXTURE0), and this texture unit will remain active until you call it again with a different texture unit. So later in your render loop, when you call glBindTexture again to set the texture, it is binding them to GL_TEXTURE1.

    Although it is essentially undefined behaviour, it appears that GL_TEXTURE0 is used by your sampler in the shader. So GL_TEXTURE0 is never changing, whilst GL_TEXTURE1 is changing but is never sampled, which causes you to see the same texture twice.

     

    To solve your issue, firstly, you should add glUniform1i(glGetUniformLocation(m_uiProgramObject, “sampler2d”), 0); within InitView to explicitly state that you are sampling GL_TEXTURE0 in your shader. The integer value you pass in to this function refers to the active texture you are using, so 0 means that the sampler will use GL_TEXTURE0.

    You also need to remove the following four lines from your RenderScene function

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, m_uiFGTex);
    [/CODE]

    But leave in your other glBindTexture calls as these will be needed to change textures.

    For a good example of how to use multiple textures in a program I suggest you look at the Bumpmap training course in the SDK. The second texture is actually a normal map but the methods still apply. I’d also suggest taking a look at our performance recommendations on optimising your code (particularly for reducing the number of calls you make to GL), which you can find in the SDK package documentation folder.

    Hope this helps 🙂

    [CODE]glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, m_uiFGTex);
    [/CODE]

    But leave in your other glBindTexture calls as these will be needed to change textures.

    For a good example of how to use multiple textures in a program I suggest you look at the Bumpmap training course in the SDK. The second texture is actually a normal map but the methods still apply. I’d also suggest taking a look at our performance recommendations on optimising your code (particularly for reducing the number of calls you make to GL), which you can find in the SDK package documentation folder.

    Hope this helps 🙂

    #34447

    Thank you so much, Tobias.

    As you suggested, I did the modification and the method works for the two texture code.
    #34448

    Here is a follow-up question.

     

    In my original code, you may see the two planes are with the same z offset. But the final rendering effect is related to the order which plane is rendered first.  If I change the the following offset as

    //two triangles as popup button
    GLfloat FG_TRIANGLE_VETEX[18] ={
    0.55f, 0.22f, 1.0f,
    1.0f, 0.22f, 1.0f,
    1.0f, -1.0f, 1.0f,
    0.55f, 0.22f,  1.0f,
    1.0f, -1.0f, 1.0f,
    0.55f, -1.0f, 1.0f
    };

     

    =>

     

    //two triangles as popup button
    GLfloat FG_TRIANGLE_VETEX[18] ={
    0.55f, 0.22f, -1.0f,
    1.0f, 0.22f, -1.0f,
    1.0f, -1.0f, -1.0f,
    0.55f, 0.22f,  -1.0f,
    1.0f, -1.0f, -1.0f,
    0.55f, -1.0f, -1.0f
    };

     

    The small plane is not blocked by the big one as I expected. However, if I choose to render this plane before the big one, we can see it is blocked. Looks to me the rendering result is only related to the order which plane is rendered first in this example. I am just wondering why the depth information is not taking effect in the example.

     

    Thank you very much,

     

    Renaissance
    #34449

    You might have to enable the depth test with glEnable(GL_DEPTH_TEST);

    #34450

    Thank you, Martin.

     

    First of all, I tried what you suggested by enabling GL_DEPTH_TEST. However, I can only have on plane rendered.

     

    Do I also need to create a depthRenderbuffer object when enabling GL_DEPTH_TEST?  I tried the following approach but it is still not working. I still can only get on plane in the output window…

     

    GLuint depthRenderbuffer

    glGenRenderbuffers(1, &depthRenderbuffer);

    ….

    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
    #34451

    No, I don’t think you need renderbuffers for depth tests. Make sure that the z coordinates returned by the vertex shader are in the visible range (between -w coordinate and +w coordinate). Your vertex shader is somewhat strange, in particular these lines:

       gl_Position.x = gl_Position.x*myScale;
       gl_Position.y = gl_Position.y*myScale*myYScale;
       gl_Position.z = gl_Position.z*myScale;
       gl_Position = gl_Position + myTMatrix;

    It is hard to understand what your are doing if you use this kind of nonstandard transformations. You should probably use the viewport transformation (glViewport) for whatever you are trying to achieve with these lines.

    #34452

    Hi Martin:

    Thank you again for your response.

     

    The Z coordinate range I am using is -1.0 to 1.0 for x, y, z. For the shader, since my output screen is 800 by 600 and it is not square, I have to squeeze my target a littlle bit. But for the two planes, you can see these scaling factors are all 1.0. In other word, it will not affact the rendering of the two planes.  If you run my very original code, you will see the shader works fine.

     

    As to my question in the previous post, the z location for the two planes are 1.0 and -1.0 and they are in the valid range.

     

    Thanks,

     

    Renaissance
    #34453

    Can anyone give me some help on this question?

     

    Thank you,

     

    Renaissance
    #34454

    Could you post your current code again?

    #34455

    Thank you, Martin

     

    #include <math.h>
    #include <stdio.h>

    #include <EGL/egl.h>
    #include <GLES2/gl2.h>
    #include “OGLES2Tools.h” 
    #include “PVRShell.h”

    // Index to bind the attributes to vertex shaders
    #define VERTEX_ARRAY 0
    #define TEXCOORD_ARRAY 1
    #define NORMAL_ARRAY 2
    #define COLOR_ARRAY  3

    const char c_sz_BK_TextureFile[]  = “BG-m.pvr”;
    const char c_sz_FG_TextureFile[]  = “FG-m.pvr”;

    //two triangles
    GLfloat BK_TRIANGLE_VETEX[18] ={
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, -1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, -1.0f, 1.0f,
    -1.0f, -1.0f, 1.0f
    };

    //normal for each vertex of the two triangles
    GLfloat BK_TRIANGLE_NORMAL[18] = {
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f};

    GLfloat BK_TRIANGLE_COLOR[24] = {
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f};

    GLfloat BK_TRIANGLE_TEXTCOORD[12] = {
                              0.0f,1.0f ,   // UVs
            1.0f,1.0f ,
            1.0f,0.0f,
            0.0f,1.0f ,  
            1.0f,0.0f ,
            0.0f,0.0f};

     

    //two triangles as popup button
    GLfloat FG_TRIANGLE_VETEX[18] ={
    0.55f, 0.22f, -1.0f,
    1.0f, 0.22f, -1.0f,
    1.0f, -1.0f, -1.0f,
    0.55f, 0.22f,  -1.0f,
    1.0f, -1.0f, -1.0f,
    0.55f, -1.0f, -1.0f
    };

    //normal for each vertex of the two triangles as popup button
    GLfloat FG_TRIANGLE_NORMAL[18] = {
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f,
     0.0f,0.0f,1.0f};

    GLfloat FG_TRIANGLE_COLOR[24] = {
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f,
     1.0f,1.0f,1.0f,1.0f};

    GLfloat FG_TRIANGLE_TEXTCOORD[12] = {
                              0.0f,1.0f ,   // UVs
            1.0f,1.0f ,
            1.0f,0.0f,
            0.0f,1.0f ,  
            1.0f,0.0f ,
            0.0f,0.0f};

    /*!****************************************************************************
     Class implementing the PVRShell functions.
    ******************************************************************************/
    class OGLESBasicTnL : public PVRShell
    {
     // The vertex and fragment shader OpenGL handles
     GLuint m_uiVertexShader, m_uiFragShader;

     // The program object containing the 2 shader objects
     GLuint m_uiProgramObject;

     // Texture handle
     GLuint m_uiBKTex;
     GLuint m_uiFGTex;
     GLuint depthRenderbuffer;

    public:
     virtual bool InitApplication();
     virtual bool InitView();
     virtual bool ReleaseView();
     virtual bool QuitApplication();
     virtual bool RenderScene();
    };

    /*!****************************************************************************
     @Function  InitApplication
     @Return  bool  true if no error occured
     @Description Code in InitApplication() will be called by PVRShell once per
        run, before the rendering context is created.
        Used to initialize variables that are not dependant on it
        (e.g. external modules, loading meshes, etc.)
        If the rendering context is lost, InitApplication() will
        not be called again.
    ******************************************************************************/
    bool OGLESBasicTnL::InitApplication()
    {
        bool m_bUseVertexProgram = true;

     return true;
    }

    /*!****************************************************************************
     @Function  QuitApplication
     @Return  bool  true if no error occured
     @Description Code in QuitApplication() will be called by PVRShell once per
        run, just before exiting the program.
        If the rendering context is lost, QuitApplication() will
        not be called.
    ******************************************************************************/
    bool OGLESBasicTnL::QuitApplication()
    {
        return true;
    }

    /*!****************************************************************************
     @Function  InitView
     @Return  bool  true if no error occured
     @Description Code in InitView() will be called by PVRShell upon
        initialization or after a change in the rendering context.
        Used to initialize variables that are dependant on the rendering
        context (e.g. textures, vertex buffers, etc.)
    ******************************************************************************/
    bool OGLESBasicTnL::InitView()
    {
     // Fragment and vertex shaders code

     char* pszFragShader = “
      uniform sampler2D sampler2d;
      varying mediump float varDot;
      varying mediump vec2 varCoord;
      varying mediump vec4 v_primaryColor;
      void main (void)
      {
       gl_FragColor = texture2D(sampler2d,varCoord) * varDot*v_primaryColor;
      }”;
     char* pszVertShader = “
      attribute highp vec4 myVertex;
      attribute mediump vec3 myNormal;
      attribute mediump vec4 myUV;
      attribute mediump vec4  myColor;
      uniform mediump mat4 myPMVMatrix;
      uniform mediump vec4 myTMatrix;
      uniform mediump float myScale;
      uniform mediump float myYScale;
      uniform mediump mat3 myModelViewIT;
      uniform mediump vec3 myLightDirection;
      varying mediump float varDot;
      varying mediump vec2 varCoord;
      varying mediump vec4 v_primaryColor;
      void main(void)
      {
       v_primaryColor = myColor;
       gl_Position = (myPMVMatrix * myVertex);
       gl_Position.x = gl_Position.x*myScale;
       gl_Position.y = gl_Position.y*myScale*myYScale;
       gl_Position.z = gl_Position.z*myScale;
       gl_Position = gl_Position + myTMatrix;
       varCoord = myUV.st;
       mediump vec3 transNormal = myModelViewIT * myNormal;
       varDot = max( dot(transNormal, myLightDirection), 0.0 );
      }”;

     // Create the fragment shader object
     m_uiFragShader = glCreateShader(GL_FRAGMENT_SHADER);

     // Load the source code into it
     glShaderSource(m_uiFragShader, 1, (const char**)&pszFragShader, NULL);

     // Compile the source code
     glCompileShader(m_uiFragShader);

     // Check if compilation succeeded
     GLint bShaderCompiled;
        glGetShaderiv(m_uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled);
     if (!bShaderCompiled)
     {
      // An error happened, first retrieve the length of the log message
      int i32InfoLogLength, i32CharsWritten;
      glGetShaderiv(m_uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);

      // Allocate enough space for the message and retrieve it
      char* pszInfoLog = new char[i32InfoLogLength];
            glGetShaderInfoLog(m_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);

      /*
       Displays the message in a dialog box when the application quits
       using the shell PVRShellSet function with first parameter prefExitMessage.
      */
      char* pszMsg = new char[i32InfoLogLength+256];
      sprintf(pszMsg, “Failed to compile fragment shader: %s”, pszInfoLog);
      PVRShellSet(prefExitMessage, pszMsg);
      delete [] pszMsg;
      delete [] pszInfoLog;
      return false;
     }

     // Loads the vertex shader in the same way
     m_uiVertexShader = glCreateShader(GL_VERTEX_SHADER);
     glShaderSource(m_uiVertexShader, 1, (const char**)&pszVertShader, NULL);
     glCompileShader(m_uiVertexShader);
        glGetShaderiv(m_uiVertexShader, GL_COMPILE_STATUS, &bShaderCompiled);
     if (!bShaderCompiled)
     {
      int i32InfoLogLength, i32CharsWritten;
      glGetShaderiv(m_uiVertexShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
      char* pszInfoLog = new char[i32InfoLogLength];
            glGetShaderInfoLog(m_uiVertexShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
      char* pszMsg = new char[i32InfoLogLength+256];
      sprintf(pszMsg, “Failed to compile vertex shader: %s”, pszInfoLog);
      PVRShellSet(prefExitMessage, pszMsg);
      delete [] pszMsg;
      delete [] pszInfoLog;
      return false;
     }

     // Create the shader program
        m_uiProgramObject = glCreateProgram();

     // Attach the fragment and vertex shaders to it
        glAttachShader(m_uiProgramObject, m_uiFragShader);
        glAttachShader(m_uiProgramObject, m_uiVertexShader);

     // Bind the custom vertex attribute “myVertex” to location VERTEX_ARRAY
        glBindAttribLocation(m_uiProgramObject, VERTEX_ARRAY, “myVertex”);
     // Bind the custom vertex attribute “myUV” to location TEXCOORD_ARRAY
        glBindAttribLocation(m_uiProgramObject, TEXCOORD_ARRAY, “myUV”);
     // Bind the custom vertex attribute “myNormal” to location NORMAL_ARRAY
        glBindAttribLocation(m_uiProgramObject, NORMAL_ARRAY, “myNormal”);
     // Bind the custom vertex attribute “myColor” to location COLOR_ARRAY
        glBindAttribLocation(m_uiProgramObject, COLOR_ARRAY, “myColor”);
     // Link the program
        glLinkProgram(m_uiProgramObject);

     // Check if linking succeeded in the same way we checked for compilation success
        GLint bLinked;
        glGetProgramiv(m_uiProgramObject, GL_LINK_STATUS, &bLinked);
     if (!bLinked)
     {
      int i32InfoLogLength, i32CharsWritten;
      glGetProgramiv(m_uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
      char* pszInfoLog = new char[i32InfoLogLength];
      glGetProgramInfoLog(m_uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
      char* pszMsg = new char[i32InfoLogLength+256];
      sprintf(pszMsg, “Failed to link program: %s”, pszInfoLog);
      PVRShellSet(prefExitMessage, pszMsg);
      delete [] pszMsg;
      delete [] pszInfoLog;
      return false;
     }
     
     if(PVRTTextureLoadFromPVR(c_sz_BK_TextureFile, &m_uiBKTex) != PVR_SUCCESS)
     {
      PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
      return false;
     }

     //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
     //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

     if(PVRTTextureLoadFromPVR(c_sz_FG_TextureFile, &m_uiFGTex) != PVR_SUCCESS)
     {
      PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
      return false;
     }

     //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
     //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

     //glUniform1i(glGetUniformLocation(m_uiProgramObject, “sampler2d”), 0);

     //glGenRenderbuffers(1, &depthRenderbuffer);

     return true;
    }

    /*!****************************************************************************
     @Function  ReleaseView
     @Return  bool  true if no error occured
     @Description Code in ReleaseView() will be called by PVRShell when the
        application quits or before a change in the rendering context.
    ******************************************************************************/
    bool OGLESBasicTnL::ReleaseView()
    {
     // Frees the texture
     glDeleteTextures(1, &m_uiBKTex);
     glDeleteTextures(1, &m_uiFGTex);

     // Frees the OpenGL handles for the program and the 2 shaders
     glDeleteProgram(m_uiProgramObject);
     glDeleteShader(m_uiVertexShader);
     glDeleteShader(m_uiFragShader);

     return true;
    }

    /*!****************************************************************************
     @Function  RenderScene
     @Return  bool  true if no error occured
     @Description Main rendering loop function of the program. The shell will
        call this function every frame.
        eglSwapBuffers() will be performed by PVRShell automatically.
        PVRShell will also manage important OS events.
        Will also manage relevent OS events. The user has access to
        these events through an abstraction layer provided by PVRShell.
    ******************************************************************************/
    bool OGLESBasicTnL::RenderScene()
    {
     glViewport(0, 0, 800, 600);
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

     glUseProgram(m_uiProgramObject);

     glEnable(GL_CULL_FACE);
     glCullFace(GL_FRONT);

     //glEnable(GL_DEPTH_TEST); 

     // Clears the color and depth buffer
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

     glEnable(GL_TEXTURE_2D);

     //*************************************************************************
     //Draw the background
     //*************************************************************************

     float alpha = 0;  //-p
     float beta =  0;  //-q
     float theta = 0;           // o

     float aModelViewIT0[] =
     {
      cos(theta)*cos(alpha), cos(alpha)*sin(beta)*sin(theta)-sin(alpha)*cos(beta), cos(alpha)*cos(beta)*sin(theta)+sin(alpha)*sin(beta),
      cos(theta)*sin(alpha), sin(alpha)*sin(beta)*sin(theta)+cos(alpha)*cos(beta), sin(alpha)*cos(beta)*sin(theta)-sin(beta)*cos(alpha),
      -sin(theta),   sin(beta)*cos(theta),         cos(beta)*cos(theta)
     };

     /*
      Bind the projection model view matrix (PMVMatrix) to the
      corresponding uniform variable in the shader.
      This matrix is used in the vertex shader to transform the vertices.
     */
     float aPMVMatrix0[] =
     {
      cos(theta)*cos(alpha), cos(alpha)*sin(beta)*sin(theta)-sin(alpha)*cos(beta), cos(alpha)*cos(beta)*sin(theta)+sin(alpha)*sin(beta), 0,
      cos(theta)*sin(alpha), sin(alpha)*sin(beta)*sin(theta)+cos(alpha)*cos(beta), sin(alpha)*cos(beta)*sin(theta)-sin(beta)*cos(alpha),0,
      -sin(theta),   sin(beta)*cos(theta),         cos(beta)*cos(theta),0,
      0,0,0,1
     };

     int i32Location = glGetUniformLocation(m_uiProgramObject, “myPMVMatrix”);
     glUniformMatrix4fv( i32Location, 1, GL_FALSE, aPMVMatrix0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myModelViewIT”);
     glUniformMatrix3fv( i32Location, 1, GL_FALSE, aModelViewIT0);

     float aTMatrix0[] = {0.0f,0.0f,0.0f,0.0f};
     i32Location = glGetUniformLocation(m_uiProgramObject, “myTMatrix”);
     glUniform4fv( i32Location,1,aTMatrix0);

     float aScale0 = 1.0;
     i32Location = glGetUniformLocation(m_uiProgramObject, “myScale”);
     glUniform1f( i32Location,aScale0);

     float aYScale0 = 1.0;
     i32Location = glGetUniformLocation(m_uiProgramObject, “myYScale”);
     glUniform1f( i32Location,aYScale0);

     // Bind the Light Direction vector to the shader
     i32Location = glGetUniformLocation(m_uiProgramObject, “myLightDirection”); 
     glUniform3f( i32Location, 0, 0, 1.5);

     //*************************************************************************
     //Draw the background
     //*************************************************************************
     glEnableVertexAttribArray(VERTEX_ARRAY);
     glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_VETEX);
     
     glEnableVertexAttribArray(NORMAL_ARRAY);
     glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_NORMAL);

     glEnableVertexAttribArray(TEXCOORD_ARRAY); 
     glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_TEXTCOORD);

     glEnableVertexAttribArray(COLOR_ARRAY); 
     glVertexAttribPointer(COLOR_ARRAY, 4, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_COLOR);

     glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
     glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);

     // Draws a non-indexed triangle array
     glDrawArrays(GL_TRIANGLES, 0,6);

     

     glUseProgram(m_uiProgramObject);
     //*************************************************************************
     //Draw the foreground
     //*************************************************************************
     glViewport(0, 0, 800, 600);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myPMVMatrix”);
     glUniformMatrix4fv( i32Location, 1, GL_FALSE, aPMVMatrix0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myModelViewIT”);
     glUniformMatrix3fv( i32Location, 1, GL_FALSE, aModelViewIT0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myTMatrix”);
     glUniform4fv( i32Location,1,aTMatrix0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myScale”);
     glUniform1f( i32Location,aScale0);

     i32Location = glGetUniformLocation(m_uiProgramObject, “myYScale”);
     glUniform1f( i32Location,aYScale0);
     
     i32Location = glGetUniformLocation(m_uiProgramObject, “myLightDirection”);
     glUniform3f( i32Location, 0, 0, 1.5);

     glEnableVertexAttribArray(VERTEX_ARRAY);
     glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_VETEX);

     glEnableVertexAttribArray(NORMAL_ARRAY);
     glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_NORMAL);

     glEnableVertexAttribArray(TEXCOORD_ARRAY);  
     glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_TEXTCOORD); 

     glEnableVertexAttribArray(COLOR_ARRAY); 
     glVertexAttribPointer(COLOR_ARRAY, 4, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_COLOR);

    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
     glBindTexture(GL_TEXTURE_2D, m_uiFGTex); 
     // Draws a non-indexed triangle array
     glDrawArrays(GL_TRIANGLES, 0,6);

     

     return true;

    }

    /*!****************************************************************************
     @Function  NewDemo
     @Return  PVRShell*  The demo supplied by the user
     @Description This function must be implemented by the user of the shell.
        The user should return its PVRShell object defining the
        behaviour of the application.
    ******************************************************************************/
    PVRShell* NewDemo()
    {
     return new OGLESBasicTnL();
    }

    /******************************************************************************
     End of file (OGLESBasicTnL.cpp)
    ******************************************************************************/
    #34456

    Gordon
    Moderator

    Some notes:

    – I suspect your projection matrix is not helping as drawing outside a very small z range results in nothing appearing on the screen.
    – You really don’t need a renderbuffer for this stuff at all

    I’ve taken the liberty of editing your code. I would suggest comparing what’s below with what you hav in an automated diff, if you have one.

    I stripped out a lot of redundant calls and manipulated the vertex positions a bit. Also, I have added a little interactivity – on windows, press 1 to enable and disable the depth test; press 2 to reverse the render order of the quads. The keys will be different on other platforms – they are the standard PVRShell Action1 and Action2 keys. Switching the render order should make no difference to the output until the depth test is disabled.

    I hope this helps – if you have further questions please post.

    Code:
    #include <math.h>
    #include <stdio.h>
    #include <EGL/egl.h>
    #include <GLES2/gl2.h>
    #include “OGLES2Tools.h”
    #include “PVRShell.h”
    // Index to bind the attributes to vertex shaders
    #define VERTEX_ARRAY 0
    #define TEXCOORD_ARRAY 1
    #define NORMAL_ARRAY 2
    #define COLOR_ARRAY  3
    const char c_sz_BK_TextureFile[]  = “BG-m.pvr”;
    const char c_sz_FG_TextureFile[]  = “FG-m.pvr”;

    //two triangles
    GLfloat BK_TRIANGLE_VETEX[18] ={
        -1.0f, 1.0f, 0.6f,
        1.0f, 1.0f, 0.6f,
        1.0f, -1.0f, 0.6f,
        -1.0f, 1.0f, 0.6f,
        1.0f, -1.0f, 0.6f,
        -1.0f, -1.0f, 0.6f
    };
    //normal for each vertex of the two triangles
    GLfloat BK_TRIANGLE_NORMAL[18] = {
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f
    };
    GLfloat BK_TRIANGLE_COLOR[24] = {
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f
    };
    GLfloat BK_TRIANGLE_TEXTCOORD[12] = {
        0.0f,1.0f ,   // UVs
        1.0f,1.0f ,
        1.0f,0.0f,
        0.0f,1.0f , 
        1.0f,0.0f ,
        0.0f,0.0f
    };

    GLfloat FG_TRIANGLE_VETEX[18] ={
        -1.0f, 0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
        0.5f, -1.0f, 0.5f,
        -1.0f, 0.5f, 0.5f,
        0.5f, -1.0f, 0.5f,
        -1.0f, -1.0f, 0.5f
    };

    //normal for each vertex of the two triangles as popup button
    GLfloat FG_TRIANGLE_NORMAL[18] = {
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f,
        0.0f,0.0f,1.0f
    };
    GLfloat FG_TRIANGLE_COLOR[24] = {
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f,
        1.0f,1.0f,1.0f,1.0f
    };
    GLfloat FG_TRIANGLE_TEXTCOORD[12] = {
        0.0f,1.0f ,   // UVs
        1.0f,1.0f ,
        1.0f,0.0f,
        0.0f,1.0f , 
        1.0f,0.0f ,
        0.0f,0.0f
    };

    /*!****************************************************************************
    Class implementing the PVRShell functions.
    ******************************************************************************/
    class OGLESBasicTnL : public PVRShell
    {
        // The vertex and fragment shader OpenGL handles
        GLuint m_uiVertexShader, m_uiFragShader;
        // The program object containing the 2 shader objects
        GLuint m_uiProgramObject;
        // Texture handle
        GLuint m_uiBKTex;
        GLuint m_uiFGTex;

        bool m_bDepthTest, m_bRenderOrder;
    public:
        virtual bool InitApplication();
        virtual bool InitView();
        virtual bool ReleaseView();
        virtual bool QuitApplication();
        virtual bool RenderScene();
    };

    /*!****************************************************************************
    @function  InitApplication
    @Return  bool  true if no error occured
    @Description Code in InitApplication() will be called by PVRShell once per
    run, before the rendering context is created.
    Used to initialize variables that are not dependant on it
    (e.g. external modules, loading meshes, etc.)
    If the rendering context is lost, InitApplication() will
    not be called again.
    ******************************************************************************/
    bool OGLESBasicTnL::InitApplication()
    {
        PVRShellSet(prefWidth,800);
        PVRShellSet(prefHeight,600);

        m_bDepthTest = m_bRenderOrder = true;
        return true;
    }
    /*!****************************************************************************
    @function  QuitApplication
    @Return  bool  true if no error occured
    @Description Code in QuitApplication() will be called by PVRShell once per
    run, just before exiting the program.
    If the rendering context is lost, QuitApplication() will
    not be called.
    ******************************************************************************/
    bool OGLESBasicTnL::QuitApplication()
    {
        return true;
    }
    /*!****************************************************************************
    @function  InitView
    @Return  bool  true if no error occured
    @Description Code in InitView() will be called by PVRShell upon
    initialization or after a change in the rendering context.
    Used to initialize variables that are dependant on the rendering
    context (e.g. textures, vertex buffers, etc.)
    ******************************************************************************/
    bool OGLESBasicTnL::InitView()
    {
        // Fragment and vertex shaders code
        char* pszFragShader = “
                              uniform sampler2D sampler2d;
                              varying mediump float varDot;
                              varying mediump vec2 varCoord;
                              varying mediump vec4 v_primaryColor;
                              void main (void)
                              {
                              gl_FragColor = texture2D(sampler2d,varCoord) * varDot*v_primaryColor;
                              }”;
        char* pszVertShader = “
                              attribute highp vec4 myVertex;
                              attribute mediump vec3 myNormal;
                              attribute mediump vec4 myUV;
                              attribute mediump vec4  myColor;
                              uniform mediump mat4 myPMVMatrix;
                              uniform mediump vec4 myTMatrix;
                              uniform mediump float myScale;
                              uniform mediump float myYScale;
                              uniform mediump mat3 myModelViewIT;
                              uniform mediump vec3 myLightDirection;
                              varying mediump float varDot;
                              varying mediump vec2 varCoord;
                              varying mediump vec4 v_primaryColor;
                              void main(void)
                              {
                              v_primaryColor = myColor;
                              gl_Position = (myPMVMatrix * myVertex);
                              gl_Position.x = gl_Position.x*myScale;
                              gl_Position.y = gl_Position.y*myScale*myYScale;
                              gl_Position.z = gl_Position.z*myScale;
                              gl_Position = gl_Position + myTMatrix;
                              varCoord = myUV.st;
                              mediump vec3 transNormal = myModelViewIT * myNormal;
                              varDot = max( dot(transNormal, myLightDirection), 0.0 );
                              }”;

        // Create the fragment shader object
        m_uiFragShader = glCreateShader(GL_FRAGMENT_SHADER);
        // Load the source code into it
        glShaderSource(m_uiFragShader, 1, (const char**)&pszFragShader, NULL);
        // Compile the source code
        glCompileShader(m_uiFragShader);
        // Check if compilation succeeded
        GLint bShaderCompiled;
        glGetShaderiv(m_uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled);
        if (!bShaderCompiled)
        {
            // An error happened, first retrieve the length of the log message
            int i32InfoLogLength, i32CharsWritten;
            glGetShaderiv(m_uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
            // Allocate enough space for the message and retrieve it
            char* pszInfoLog = new char[i32InfoLogLength];
            glGetShaderInfoLog(m_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
            /*
            Displays the message in a dialog box when the application quits
            using the shell PVRShellSet function with first parameter prefExitMessage.
            */
            char* pszMsg = new char[i32InfoLogLength+256];
            sprintf(pszMsg, “Failed to compile fragment shader: %s”, pszInfoLog);
            PVRShellSet(prefExitMessage, pszMsg);
            delete [] pszMsg;
            delete [] pszInfoLog;
            return false;
        }
        // Loads the vertex shader in the same way
        m_uiVertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(m_uiVertexShader, 1, (const char**)&pszVertShader, NULL);
        glCompileShader(m_uiVertexShader);
        glGetShaderiv(m_uiVertexShader, GL_COMPILE_STATUS, &bShaderCompiled);
        if (!bShaderCompiled)
        {
            int i32InfoLogLength, i32CharsWritten;
            glGetShaderiv(m_uiVertexShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
            char* pszInfoLog = new char[i32InfoLogLength];
            glGetShaderInfoLog(m_uiVertexShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
            char* pszMsg = new char[i32InfoLogLength+256];
            sprintf(pszMsg, “Failed to compile vertex shader: %s”, pszInfoLog);
            PVRShellSet(prefExitMessage, pszMsg);
            delete [] pszMsg;
            delete [] pszInfoLog;
            return false;
        }
        // Create the shader program
        m_uiProgramObject = glCreateProgram();
        // Attach the fragment and vertex shaders to it
        glAttachShader(m_uiProgramObject, m_uiFragShader);
        glAttachShader(m_uiProgramObject, m_uiVertexShader);
        // Bind the custom vertex attribute “myVertex” to location VERTEX_ARRAY
        glBindAttribLocation(m_uiProgramObject, VERTEX_ARRAY, “myVertex”);
        // Bind the custom vertex attribute “myUV” to location TEXCOORD_ARRAY
        glBindAttribLocation(m_uiProgramObject, TEXCOORD_ARRAY, “myUV”);
        // Bind the custom vertex attribute “myNormal” to location NORMAL_ARRAY
        glBindAttribLocation(m_uiProgramObject, NORMAL_ARRAY, “myNormal”);
        // Bind the custom vertex attribute “myColor” to location COLOR_ARRAY
        glBindAttribLocation(m_uiProgramObject, COLOR_ARRAY, “myColor”);
        // Link the program
        glLinkProgram(m_uiProgramObject);
        // Check if linking succeeded in the same way we checked for compilation success
        GLint bLinked;
        glGetProgramiv(m_uiProgramObject, GL_LINK_STATUS, &bLinked);
        if (!bLinked)
        {
            int i32InfoLogLength, i32CharsWritten;
            glGetProgramiv(m_uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
            char* pszInfoLog = new char[i32InfoLogLength];
            glGetProgramInfoLog(m_uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
            char* pszMsg = new char[i32InfoLogLength+256];
            sprintf(pszMsg, “Failed to link program: %s”, pszInfoLog);
            PVRShellSet(prefExitMessage, pszMsg);
            delete [] pszMsg;
            delete [] pszInfoLog;
            return false;
        }

        if(PVRTTextureLoadFromPVR(c_sz_BK_TextureFile, &m_uiBKTex) != PVR_SUCCESS)
        {
            PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
            return false;
        }
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
        if(PVRTTextureLoadFromPVR(c_sz_FG_TextureFile, &m_uiFGTex) != PVR_SUCCESS)
        {
            PVRShellSet(prefExitMessage, “ERROR: Cannot load the texturen”);
            return false;
        }
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
        //glUniform1i(glGetUniformLocation(m_uiProgramObject, “sampler2d”), 0);

        //glGenRenderbuffers(1, &depthRenderbuffer);
        return true;
    }
    /*!****************************************************************************
    @function  ReleaseView
    @Return  bool  true if no error occured
    @Description Code in ReleaseView() will be called by PVRShell when the
    application quits or before a change in the rendering context.
    ******************************************************************************/
    bool OGLESBasicTnL::ReleaseView()
    {
        // Frees the texture
        glDeleteTextures(1, &m_uiBKTex);
        glDeleteTextures(1, &m_uiFGTex);
        // Frees the OpenGL handles for the program and the 2 shaders
        glDeleteProgram(m_uiProgramObject);
        glDeleteShader(m_uiVertexShader);
        glDeleteShader(m_uiFragShader);

        return true;
    }
    /*!****************************************************************************
    @function  RenderScene
    @Return  bool  true if no error occured
    @Description Main rendering loop function of the program. The shell will
    call this function every frame.
    eglSwapBuffers() will be performed by PVRShell automatically.
    PVRShell will also manage important OS events.
    Will also manage relevent OS events. The user has access to
    these events through an abstraction layer provided by PVRShell.
    ******************************************************************************/
    bool OGLESBasicTnL::RenderScene()
    {

        if(PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
            m_bDepthTest = !m_bDepthTest;
        if(PVRShellIsKeyPressed(PVRShellKeyNameACTION2))
            m_bRenderOrder = !m_bRenderOrder;

        glViewport(0, 0, 800, 600);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_FRONT);
        if(m_bDepthTest)
        {
            glEnable(GL_DEPTH_TEST);
        }
        else
        {
            glDisable(GL_DEPTH_TEST);
        }

        // Clears the color and depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_TEXTURE_2D);

        //*************************************************************************
        //Draw the background
        //*************************************************************************
        float alpha = 0;  //-p
        float beta =  0;  //-q
        float theta = 0;           // o

        float aModelViewIT0[] =
        {
            cos(theta)*cos(alpha), cos(alpha)*sin(beta)*sin(theta)-sin(alpha)*cos(beta), cos(alpha)*cos(beta)*sin(theta)+sin(alpha)*sin(beta),
            cos(theta)*sin(alpha), sin(alpha)*sin(beta)*sin(theta)+cos(alpha)*cos(beta), sin(alpha)*cos(beta)*sin(theta)-sin(beta)*cos(alpha),
            -sin(theta),   sin(beta)*cos(theta),         cos(beta)*cos(theta)
        };

        /*
        Bind the projection model view matrix (PMVMatrix) to the
        corresponding uniform variable in the shader.
        This matrix is used in the vertex shader to transform the vertices.
        */
        float aPMVMatrix0[] =
        {
            cos(theta)*cos(alpha), cos(alpha)*sin(beta)*sin(theta)-sin(alpha)*cos(beta), cos(alpha)*cos(beta)*sin(theta)+sin(alpha)*sin(beta), 0,
            cos(theta)*sin(alpha), sin(alpha)*sin(beta)*sin(theta)+cos(alpha)*cos(beta), sin(alpha)*cos(beta)*sin(theta)-sin(beta)*cos(alpha),0,
            -sin(theta),   sin(beta)*cos(theta),         cos(beta)*cos(theta),0,
            0,0,0,1
        };

        // same shader for both quads so only need to make these calls once
        glUseProgram(m_uiProgramObject);   

        int i32Location = glGetUniformLocation(m_uiProgramObject, “myPMVMatrix”);
        glUniformMatrix4fv( i32Location, 1, GL_FALSE, aPMVMatrix0);
        i32Location = glGetUniformLocation(m_uiProgramObject, “myModelViewIT”);
        glUniformMatrix3fv( i32Location, 1, GL_FALSE, aModelViewIT0);
        float aTMatrix0[] = {0.0f,0.0f,0.0f,0.0f};
        i32Location = glGetUniformLocation(m_uiProgramObject, “myTMatrix”);
        glUniform4fv( i32Location,1,aTMatrix0);
        float aScale0 = 1.0;
        i32Location = glGetUniformLocation(m_uiProgramObject, “myScale”);
        glUniform1f( i32Location,aScale0);
        float aYScale0 = 1.0;
        i32Location = glGetUniformLocation(m_uiProgramObject, “myYScale”);
        glUniform1f( i32Location,aYScale0);
        // Bind the Light Direction vector to the shader
        i32Location = glGetUniformLocation(m_uiProgramObject, “myLightDirection”);
        glUniform3f( i32Location, 0, 0, 1.5);

        // these are the same for both quads as well so only make the calls once
        glEnableVertexAttribArray(NORMAL_ARRAY);
        glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_NORMAL);
        glEnableVertexAttribArray(TEXCOORD_ARRAY);
        glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_TEXTCOORD);
        glEnableVertexAttribArray(COLOR_ARRAY);
        glVertexAttribPointer(COLOR_ARRAY, 4, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_COLOR);

        // draw

        if(m_bRenderOrder)
        {    // draw one way
            //*************************************************************************
            //Draw the background
            //*************************************************************************
            glEnableVertexAttribArray(VERTEX_ARRAY);
            glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_VETEX);

            glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
            glDrawArrays(GL_TRIANGLES, 0,6);

            //*************************************************************************
            //Draw the foreground
            //*************************************************************************

            // different vertex positions
            glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_VETEX);

            // different texture
            glBindTexture(GL_TEXTURE_2D, m_uiFGTex);
            glDrawArrays(GL_TRIANGLES, 0,6);
        }
        else
        {    // draw in the other order
            //*************************************************************************
            //Draw the foreground
            //*************************************************************************

            // different vertex positions
            glEnableVertexAttribArray(VERTEX_ARRAY);
            glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, FG_TRIANGLE_VETEX);

            // different texture
            glBindTexture(GL_TEXTURE_2D, m_uiFGTex);
            glDrawArrays(GL_TRIANGLES, 0,6);

            //*************************************************************************
            //Draw the background
            //*************************************************************************
            glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, BK_TRIANGLE_VETEX);

            glBindTexture(GL_TEXTURE_2D, m_uiBKTex);
            glDrawArrays(GL_TRIANGLES, 0,6);

        }

        return true;
    }
    /*!****************************************************************************
    @function  NewDemo
    @Return  PVRShell*  The demo supplied by the user
    @Description This function must be implemented by the user of the shell.
    The user should return its PVRShell object defining the
    behaviour of the application.
    ******************************************************************************/
    PVRShell* NewDemo()
    {
        return new OGLESBasicTnL();
    }
    /******************************************************************************
    End of file (OGLESBasicTnL.cpp)
    ******************************************************************************/

    Gordon2010-11-18 19:04:44

    #34457

    Thank you so much, Gordon.  I do appreciate it that you trimmed my code and made it running.

     

    I played with the program and I found out that after setting a new z locations for BK_TRIANGLE_VETEX and FG_TRIANGLE_VETEX, such as

     

    GLfloat BK_TRIANGLE_VETEX[18] ={< ?: prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    -1.0f, 1.0f, 1.0f,

    1.0f, 1.0f, 1.0f,

    1.0f, -1.0f, 1.0f,

    -1.0f, 1.0f, 1.0f,

    1.0f, -1.0f, 1.0f,

    -1.0f, -1.0f, 1.0f

    };

     

    Your code will fail too and it generated a black background when depth_test is enabled. If I choose to set as following,

     

    GLfloat BK_TRIANGLE_VETEX[18] ={

    -1.0f, 1.0f, 0.995f,

    1.0f, 1.0f, 0.995f,

    1.0f, -1.0f, 0.995f,

    -1.0f, 1.0f, 0.995f,

    1.0f, -1.0f, 0.995f,

    -1.0f, -1.0f, 0.995f

    };

     

    Your code runs well and background is visualized correctly when depth_test is enabled.

     

    For the Foreground, your program works even I choose the following setting

    GLfloat FG_TRIANGLE_VETEX[18] ={

        -1.0f, 0.5f, -1.0f,

        0.5f, 0.5f, -1.0f,

        0.5f, -1.0f,-1.0f,

        -1.0f, 0.5f, -1.0f,

        0.5f, -1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f

    };

     

    I run my original code with the above tests, I got the same visualization results as yours. So, I think the real problem is I should have not use the 1.0 setting for BK.

     

    So from the above test, can I say in the PVRShell, the range of z is actually

    -1.0<= z < 1.0

    Is this correct?

     

    Thank you very much.

     

    Renaissance.

     

     

    #34458

    Another related question is that if we define the location close to the view point with small value and the location far away with large value, how about the normal definition?

     

    In the above code, the normal is defined as  0.0f,0.0f,1.0f, which is not towards the view point. But why we still can see the light reflect from this plane? Can you help me explain this? I have a feeling I do not have a correct understanding of the coordinate system in the OpenGL ES.

     

    Thank u very much,

     

    Renaissance
Viewing 15 posts - 1 through 15 (of 21 total)
You must be logged in to reply to this topic.