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: using multiple programs in open gl es 2

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2012
    Posts
    25

    using multiple programs in open gl es 2

    Hi,

    Is there any online sample that shows how to use two or more gles2 programs (using glUseProgram)? I'm getting strange errors when i try to do that here.

    thanks in advance,

    guich

  2. #2
    Junior Member Regular Contributor
    Join Date
    Jun 2012
    Posts
    207
    can you post your code here? and what error are you getting?

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,129
    At the same time? You can create as much programs as you want. You can have only one active program at a time when using glUseProgram() and since that's the only way in GLES2/3 you have to stick with that.

  4. #4
    Junior Member Newbie
    Join Date
    Sep 2012
    Posts
    25
    Hi,

    Here's the code:

    Code :
    #define TEXTURE_VERTEX_CODE  \
          "uniform vec4 uTextureColor;" \
          "attribute vec4 vertexPoint;" \
          "attribute vec2 aTextureCoord;" \
          "uniform mat4 projectionMatrix; " \
          "varying vec2 vTextureCoord;" \
          "varying vec4 vTextureColor;" \
          "void main()" \
          "{" \
          "    gl_Position = vertexPoint * projectionMatrix;" \
          "    vTextureCoord = aTextureCoord;" \
          "    vTextureColor = uTextureColor;" \
          "}"                         
     
    #define TEXTURE_FRAGMENT_CODE \
          "precision mediump float;" \
          "varying vec2 vTextureCoord;" \
          "varying vec4 vTextureColor;" \
          "uniform sampler2D sTexture;" \
          "void main() {gl_FragColor = texture2D(sTexture, vTextureCoord) * vTextureColor;}"
     
    static GLuint textureProgram;
    static GLuint textureColor,texturePoint;
    static GLuint textureCoord,textureId;
     
    //////////// points (text)
     
    #define POINTS_VERTEX_CODE \
          "attribute vec4 a_Position; attribute vec4 a_Color; varying vec4 v_Color;" \
          "uniform mat4 projectionMatrix;" \
          "void main() {v_Color = a_Color; gl_Position = a_Position * projectionMatrix;}"
     
    #define POINTS_FRAGMENT_CODE \
          "precision mediump float;" \
          "varying vec4 v_Color;" \
          "void main() {gl_FragColor = v_Color;}"
     
    void initTexture()
    {  
       GLfloat textureVerts[8] = { 0, 1,  1, 1,  1, 0,  0, 0 };
       debug("init texture");
     
       textureProgram = glCreateProgram();
       glAttachShader(textureProgram, loadShader(GL_VERTEX_SHADER, TEXTURE_VERTEX_CODE));
       glAttachShader(textureProgram, loadShader(GL_FRAGMENT_SHADER, TEXTURE_FRAGMENT_CODE));
       glLinkProgram(textureProgram);
       glUseProgram(textureProgram);
     
       glEnable(GL_TEXTURE_2D);
       glActiveTexture(GL_TEXTURE0);
     
       textureColor = glGetUniformLocation(textureProgram, "uTextureColor");
       textureId    = glGetUniformLocation(textureProgram, "sTexture");
       texturePoint = glGetAttribLocation(textureProgram, "vertexPoint");
       textureCoord = glGetAttribLocation(textureProgram, "aTextureCoord");
     
       glEnableVertexAttribArray(textureCoord);
       glVertexAttribPointer(textureCoord, 2, GL_FLOAT, false, 0, textureVerts);
     
       glEnableVertexAttribArray(texturePoint);
    }
     
    void initPoints()
    {
       debug("init points");
       pointsProgram = glCreateProgram();
       glAttachShader(pointsProgram, loadShader(GL_VERTEX_SHADER, POINTS_VERTEX_CODE));
       glAttachShader(pointsProgram, loadShader(GL_FRAGMENT_SHADER, POINTS_FRAGMENT_CODE));
       glLinkProgram(pointsProgram);
       glUseProgram(pointsProgram);
     
       pointsColor    = glGetAttribLocation(pointsProgram, "a_Color");
       pointsPosition = glGetAttribLocation(pointsProgram, "a_Position"); // get handle to vertex shader's vPosition member
       glEnableVertexAttribArray(pointsColor); // Enable a handle to the colors
       glEnableVertexAttribArray(pointsPosition); // Enable a handle to the vertices
    }
    GLuint loadShader(GLenum shaderType, const char* pSource)
    {
       GLuint shader = glCreateShader(shaderType);
       checkGlErrorI("loadShader createShader",shaderType); // ***
       glShaderSource(shader, 1, &pSource, NULL);
       checkGlError("loadShader glShaderSource");
       glCompileShader(shader);
       checkGlError("loadShader glCompileShader");
       return shader;
    }

    If i call

    initTexture();
    initPoints();

    then i get a GL_INVALID_ENUM when compiling the GL_VERTEX_SHADER of initPoints in line marked with ***. If i call only initPoints(), i don't get such error.

    If i use both codes standalone, they work.

    thanks

    guich

  5. #5
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    456
    The GL_INVALID_ENUM error is probably from this line:
    Code :
    glEnable(GL_TEXTURE_2D);
    Since enabling/disabling textures is only used by fixed function OpenGL, not while using shaders.

  6. #6
    Junior Member Newbie
    Join Date
    Sep 2012
    Posts
    25
    Quote Originally Posted by Dan Bartlett View Post
    The GL_INVALID_ENUM error is probably from this line:
    Code :
    glEnable(GL_TEXTURE_2D);
    Since enabling/disabling textures is only used by fixed function OpenGL, not while using shaders.
    You were right! Removing the line made the code work without such error.

    Something i cant understand is about the state changes. What is and what is not stored in the program when you call glUseProgram? For example, are the glEnableVertexAttribArray calls persistent across glUseProgram calls? Is there any document that says what you have to call again after each program change and what is persisted?

    From my researches, everyone says that to keep performance a high rate, you have to batch the commands to opengl. I believe that a program change flushes the pipeline. So, would it be faster to add a variable inside a program and a if/else to select the desired program code, or do 3 distinct programs for each situation? I have 3 here: one program to draw point,line,rect; one to draw points; and one to draw textures.

    thanks!

    guich

  7. #7
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    What is and what is not stored in the program when you call glUseProgram?
    Nothing. Calling `glUseProgram` does not "store" anything in the program. It makes the state that is already stored in the program available to the context. That state includes:

    * The compiled/linked programs.
    * The uniform values for each non-default block uniform variable.
    * The UBO binding indices for uniform blocks in the programs.
    * Other similar state.

    Program state deals with programs and stuff within programs; it has nothing to do (directly of course) with vertex arrays. That state is owned by the Vertex Array Object. You shouldn't be concerned about `glUseProgram` smashing some random and arbitrary state. OpenGL's API may be a bit odd, but it's not that stupid.

    Most of the time...

    I believe that a program change flushes the pipeline.
    Why? Do you know enough about various OpenGL implementations to know that for a fact? And if you don't know it, why would you base optimization decisions on it?

    Profile first, optimize later.

Posting Permissions

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