GLEW说明
GLEW(OpenGL Extension Wrangler) 是OpenGL的另一个辅助库,主要封装了从OpenGL库中获取函数地址的过程,还包含了一些可以跨平台使用的OpenGL编程方法。
本次实践是使用数据缓存绘制两个三角形,重点是缓存的创建和数据输入。数据输入后,根据数据使用方式可分为非基于索引绘制和基于索引绘制,使用的方法分别为glDrawArray和glDrayElements。
首先,明确OpenGL缓存使用步骤:
- glGenBuffer
 - glBindBuffer
 - glBufferData
 - glVertexAttribPointer
 - glBindVertexArray
 - glDrawArrays
 
简单来说就是:先创建缓存,然后输入缓存数据,然后绘制。以下是相关API的一个说明:
创建缓存
glGenBuffer(GLsizei n, GLuint* buffers);//创建n个缓存对象,保存在buffers数组中
向缓存中输入或输出数据
glBindBuffer(GLenum target, GLuint buffer); //绑定缓存到target指定的缓存结合点
glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); //为绑定到target的缓存对象分配size大小的存储空间,如果data不为NULL,则使用data初始化所为配的存储空间。usage指示缓存中的数据可能具备的一些特定的用途。
glBufferSubData(GLenum target, GLsizeiptr offset, GLsizeiptr size, const GLvoid* data);//使用新数据替换缓存中的部分数据
清除数据
glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const GLvoid* data); //使用data填充缓存存储空间,format和type指定data的数据格式和类型,填充前需要把data转化为internalformat
glClearSubBufferData(GLenum target, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const GLvoid* data); //同上,区别是这个方法只填充offset和size指定的区域;
设置顶点属性
glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
绘制
glDrawArrays(GLenum mode, GLint first, GLsizei count);//直接读取顶点数据绘制
glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);基于索引绘制(即所有的顶点在一个数组中,使用索引来引用顶点数据)
以下是根据上述API编写的绘制两个三角形的例子。
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include "ShaderHelper.h"
#define BUFFER_OFFSET(n) ((GLvoid*)n)
enum VAO_IDs { Triangles,NumVAOs};
enum Buffers_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition=0 };
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices=6;
void init();
void display();
int main(int argc,char* argv[])
{
        glutInit(&argc,argv);
        glutInitContextVersion(3,3);
        glutInitContextProfile(GLUT_CORE_PROFILE);
        glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
        glutInitWindowPosition(0,0);
        glutInitWindowSize(300,300);
        glutCreateWindow("Frame Buffer");
/*      const GLubyte* name = glGetString(GL_VENDOR); //返回负责当前OpenGL实现厂商的名字
        const GLubyte* biaoshifu = glGetString(GL_RENDERER); //返回一个渲染器标识符,通常是个硬>
件平台
        const GLubyte* OpenGLVersion =glGetString(GL_VERSION); //返回当前OpenGL实现的版本号
        const GLubyte* gluVersion= gluGetString(GLU_VERSION); //返回当前GLU工具库版本
        printf("OpenGL实现厂商的名字:%s\n", name);
        printf("渲染器标识符:%s\n", biaoshifu);
        printf("OOpenGL实现的版本号:%s\n",OpenGLVersion );
         printf("OGLU工具库版本:%s\n", gluVersion);*/
         glewExperimental=GL_TRUE;
         glewInit();
         init();
         glutDisplayFunc(display);
 
         glutMainLoop();
         return 0;
 }
 
 void init()
 {
         glClearColor(0.0,0.0,0.0,1.0);
         glMatrixMode(GL_PROJECTION);
         glOrtho(-5,5,-5,5,5,15);
         glMatrixMode(GL_MODELVIEW);
         gluLookAt(0,0,10,0,0,0,0,1,0);
 
         glGenVertexArrays(NumVAOs,VAOs);
         glBindVertexArray(VAOs[Triangles]);
 
         GLfloat vertices[NumVertices][2]={
                 {-0.90,-0.90},
                 {0.85, -0.90},
                 { -0.90, 0.85 },
                 { 0.90, -0.85 },
                 { 0.90, 0.90 },
                 {-0.85, 0.90 },
         };
 
         glGenBuffers(NumBuffers,Buffers);
         glBindBuffer(GL_ARRAY_BUFFER,Buffers[ArrayBuffer]);
         glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
 
         ShaderInfo shaders[] = {
                 {GL_VERTEX_SHADER,"triangles.vert"},
                 {GL_FRAGMENT_SHADER,"triangles.frag"},
                {GL_NONE,NULL},
        };
        GLuint program = LoadShaders(shaders);
        glUseProgram(program);
        glVertexAttribPointer(vPosition,2,GL_FLOAT,GL_FALSE,0,BUFFER_OFFSET(0));
        glEnableVertexAttribArray(vPosition);
}
void display()
{
        glClear(GL_COLOR_BUFFER_BIT);
        glBindVertexArray(VAOs[Triangles]);
        glDrawArrays(GL_TRIANGLES,0,NumVertices);
        glFlush();
}
注意:代码根据红宝书编写,一些辅助性代码(如LoadShader)并未贴出,详情请参照www.opengl-readbook.com。
最终的效果如下:
