Search code examples
c++openglglm-math

opengl drawing multipe objects from one vao


i have a single vao that contains a character set of a font. Each character is drawn with a set of indices belonging to it. The idea was to write a couple of chars and bind the vao only one time.

Everything works fine - except the positioning of the glyphs. The loop is like

glGetUniformLocations()
glBindVertexArray( vao )
for( i=0; i< lg; i++ )
{
  glUniforMatrix4fV();      // send translation matrix to shader
  glDrawElements( part of the indexbuffer );
  trans_mx = glm::translate();  // compute the translation matrix
}

Vertexshader is:

#version 450 core

layout( location = 0 ) in vec3 vx;          // the vertex_buffer in modelspace
layout( location = 1 ) in vec4 vx_col;      // color of each vertex

out vec4 fragment_color;                   

uniform mat4  mvp_mx;         
uniform mat4  trans_mx;         

void main()
{
  gl_Position = mvp_mx * vec4( trans_mx * vec4( vx, 1.0f ) );

  fragment_color = vx_col;
}

The translation works - but not between the draw calls. All chars are drawn at the same position. which is translated. For me it seems as if the translation matrix will not be updated. ??????

this is the code from the function that draws the chars

  lg  = strlen( str );
  vao = sfs->vao;
  _sys.mvp_mx   = _sys.proj_mx * _sys.view_mx * vao->model_mx;   // compute global mvp


  sh_s = &__sh_list[ vao->shd_ind ];       // pointer to our shader_struct
  sh_s->get_uniform_loc();                 // get uniform locations for this shader
  glBindVertexArray( vao->id );            // bind vao

  glUseProgram( sh_s->prg_id );            // use the shader

  for(  c1 = 0; c1 < lg; c1++ )
  {
    sh_s->send_uniform();                    // send uniforms to the shader
    i_seg = &vao->ind_b->seg[ str[ c1 ] ];   // segment for this character
    glDrawElements( i_seg->prim, i_seg->count, i_seg->type, ( void* )i_seg->offset );
    _sys.trans_mx = glm::translate( glm::mat4( 1.0f ), glm::vec3( 10.0f, 0.0f, 0.0f ) );     
  }

  glBindVertexArray( 0 );           // unbind vao
  glUseProgram( 0 );                // unbind shader

Solution

  • The expression

    for(  c1 = 0; c1 < lg; c1++ )
    {
        .....
        _sys.trans_mx = glm::translate(glm::mat4(1.0f), glm::vec3(10.0f, 0.0f, 0.0f));
    }
    

    will ongoing calculate the same matrix.

    If you want to calculate a continuously changing matrix in the loop, then you have to continually change the matrix based on its current value:

    for(  c1 = 0; c1 < lg; c1++ )
    {
        .....
        _sys.trans_mx = glm::translate(_sys.trans_mx, glm::vec3(10.0f, 0.0f, 0.0f));
    }
    

    Or you calculate the matrix dependent on the control variable of the loop

    for(  c1 = 0; c1 < lg; c1++ )
    {
        .....
        _sys.trans_mx = glm::translate(glm::mat4(1.0f), glm::vec3(10.0f * c1, 0.0f, 0.0f));
    }