OpenGL绘制方式

图元

点:                                GL_POINTS

线:                                GL_LINES

条带线:                        GL_LINE_STRIP

循环线:                        GL_LINE_LOOP

独立三角形:                GL_TRIANGLES

三角形条带:                GL_TRIANGLE_STRIP

三角形扇面:                GL_TRIANGLE_FAN



多边形

    1) 正反面的绘制模式:glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)   //GL_FRONT、GL_BACK;GL_LINE、GL_FILL

    2) 反转:    glFrontFace(GL_CCW)      //默认为逆时针,  GL_CW顺时针方向的面为正面  (控制正面的方向)

    3) 裁剪:    glEnable(GL_CULL_FACE)

                        glCullFace(GL_FRONT);          //GL_BACK、GL_FRONT_AND_BACK

    4) 偏移: glEnable(GL_POLYGON_OFFSET_FILL);               //多边形偏移避免深度数据的z-fighting问题

                   glPolygonOffset(2.0f, 4.0f);




OpenGL缓存


    object.BindVertexArray();                   //绑定

    glGenBuffers(1, &weight_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, weight_vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW); 

    
    glVertexAttribDivisor(3, 1);          //位于index的顶点属性分配到几个新的属性,启用顶点属性

    
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(3); 
    
    glGenBuffers(1, &color_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, color_vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); 

    glVertexAttribDivisor(4, 1);


    glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(4);
 
    glBindVertexArray(0);               //解绑


注意:在内存中数组之间可能是连续的,也可能不连续,此时无法用glBufferData()一次性更新所有数据,因此引入glBufferSubData()



访问缓存

     glGetBufferSubData() :将opengl内存中的数据拷贝到应用程序内存中。

     glMapBuffer() :通过获取一个指针的形式,直接在应用程序中对opengl内存进行访问

                                          void *a = glMapBuffer(GL_COPY_WRITE_BUFFER, GL_WRITE_ONLY);         //映射缓存

                                          fread(data, 1, filesize, f);                                                                         //将文件读入缓存

                                          glUnMapBuffer(GL_COPY_WRITE_BUFFER);                           //解除映射

                                     



绘制命令

   void Initial()

  {      ShaderInfo shader_info[] =

            {
                 { GL_VERTEX_SHADER, "media/shaders/primitive_restart/primitive_restart.vs.glsl" },
                 { GL_FRAGMENT_SHADER, "media/shaders/primitive_restart/primitive_restart.fs.glsl" },
                  { GL_NONE, NULL }
          }; 
    render_prog = LoadShaders(shader_info); 

    glUseProgram(render_prog); 
  
    render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix");
    render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix"); 
 
    static const GLfloat vertex_positions[] =
    {
        -1.0f, -1.0f,  0.0f, 1.0f,
         1.0f, -1.0f,  0.0f, 1.0f,
        -1.0f,  1.0f,  0.0f, 1.0f,
        -1.0f, -1.0f,  0.0f, 1.0f,
    };
 
    static const GLfloat vertex_colors[] =
    {
        1.0f, 1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 1.0f, 1.0f,
        0.0f, 1.0f, 1.0f, 1.0f
    };
 
 
    static const GLushort vertex_indices[] =    //此为元素,其他为顶点
    {
        0, 1, 2
    };
 
    glGenBuffers(1, ebo);                                                                   //设置元素属性数组
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW); 
 
    glGenVertexArrays(1, vao);      //设置顶点属性数组
    glBindVertexArray(vao[0]);
 
    glGenBuffers(1, vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors); 

    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
}

void  Display( )

      mat4 model_matrix; 

      ...
    glUseProgram(render_prog); 
     
    vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f));
    glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, projection_matrix);     //将矩阵传递给着色器程序
     
    glBindVertexArray(vao[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); 
    
    model_matrix = vmath::translate(-3.0f, 0.0f, -5.0f);
    glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix);    //绘制命令
    glDrawArrays(GL_TRIANGLES, 0, 3); 

    
    model_matrix = vmath::translate(-1.0f, 0.0f, -5.0f);
    glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL); 
 
    model_matrix = vmath::translate(1.0f, 0.0f, -5.0f);
    glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix);
    glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1); 

 
    model_matrix = vmath::translate(3.0f, 0.0f, -5.0f);
    glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix);
    glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); 

    base::Display();
}




图元重启动

         每次绘制的内容总是与前一次图元的类型相同,而且需要大量绘制时,使用glMultiDraw()需要很多额外的去管理起始索引位置和长度的数组,此时就需要用到图元重启动。

       glEnable(GL_PRIMITIVE_RESTART)
       glPrimitiveRestartIndex(0xFFFF);  
                   //从这个索引之后的顶点开始,重新开始进行相同图元的渲染
       glDrawElements(GL_TRIANGLES_STRIP)



实例化/多实例渲染

        1) 每连续执行多条相同的渲染命令,使用少量API渲染大量集合体的方法。

          glDrawArrayInstanced(GL_TRIANGLES, 0 , size, n)    //渲染n个

          glDrawElementsInstanced()


         2)多实例的顶点属性

               glGenBuffers(1, &color_vbo);
               glBindBuffer(GL_ARRAY_BUFFER, color_vbo);
               glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); 

               glVertexAttribDivisor(4, 1);    //控制顶点属性更新的频率,index位置分配几个新的属性,如果后者为0,则禁用


               glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 0, NULL);
               glEnableVertexAttribArray(4);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

屠变恶龙之人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值