工程代码
有了GLFW和GLEW的加持,就可以使用更为“现代”方式使用OpenGL提供的api了。下面的代码给出了基于GLEW库绘制三角形的方法
#include <iostream>
#include <GL/glew.h> //这个头文件一定要在最前面包含
#include <GLFW/glfw3.h>
using namespace std;
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "出来吧,三角形", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if(glewInit()!=GLEW_OK)
{
printf("GLEW Init Failed \n");
return 0;
}
printf("%s\n",glGetString(GL_VERSION));//打印当前的OpenGL版本号
GLfloat points[]={-0.5f,-0.5f,0.0f,0.5f,0.5f,-0.5f};
unsigned int buffer;
glCreateBuffers(1,&buffer);
glBindBuffer(GL_ARRAY_BUFFER,buffer);
glBufferData(GL_ARRAY_BUFFER,6*sizeof(GLfloat),points,GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof (GLfloat),0);
glBindBuffer(GL_ARRAY_BUFFER,0);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES,0,3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
把上面的代码复制到工程中编译执行就会在窗口中看到白色的三角形了,如果看不到也没关系,应为这段代码根本就没有调用“着色器(Shader)”,能看到三角形的原因是有些显卡供应商在实现OpenGL时,会设置一个默认的“着色器”,也就是说当程序没有给出“着色器”说明时,就会调用默认的“着色器”进行绘图。至少我这台电脑的上面是可以看到三角形的。
函数说明
glCreateBuffers
用于从显卡内存中申请缓冲区
函数原型
void glCreateBuffers(GLsizei n,GLuint *buffers);
参数说明
n:需要申请的缓冲区数量,注意是缓冲区数量,不是缓冲区长度。
buffers:用于存放申请到的缓冲区句柄的数组。这里描述成“句柄”可能不准确,其实可以说是指针、名字、偏移量都行,反正就是个无符号整数。
错误返回值
GL_INVALID_VALUE: 从参数说明中可以看出来n应该是大于等于零的,所以说当n小于0时,就会返回错误。
glBindBuffer
绑定缓冲区,其实就是给申请到的缓冲区指定一个类型。
函数原型
void glBindBuffer(GLenum target,GLuint buffer);
参数说明
target:要绑定的缓冲区类型。以下是target可以取的值以及含义。
buffer:通过glCreateBuffers申请到的缓冲区句柄。
错误返回值
GL_INVALID_ENUM :如果传入target的值不在上述表格内,则会返回这个错误。
GL_INVALID_VALUE:如果传入buffer的值不是经过申请得到的值,则会返回这个错误。换句话说,虽然buffer的值是个整数,但是其中的值必须要通过glCreateBuffers函数获取,并且不要修改。
glBufferData
创建并初始化缓冲区对象存储的数据,其实就是把数据存到缓冲区里面去。
函数原型
void glBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage);
参数说明
target:和glBindBuffer函数中的target参数一样,指明缓冲区的类型,可取的参数值也一样。
size:指明要存储的数据大小,其实就是设置缓冲区的长度。
data:要存入缓冲区的数据指针,要大于等于size指示的长度,不然就越界了。
usage:指明缓冲区中数据的使用方式。可以取GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY中的一个。
错误返回值
GL_INVALID_ENUM:当target和usage值不在指定的范围中时,会返回这个错误。
GL_INVALID_VALUE:当size小于零时,会返回这个错误。
GL_INVALID_OPERATION:有三种情况会返回这个错误,1.当buffer没有被绑定时、2.buffer的值不是经过申请得到的值、3.buffer的GL_BUFFER_IMMUTABLE_STORAGE标签被置为true时。
GL_OUT_OF_MEMORY:字面意思,显存的容量不足了,不能创建指定size的存储空间时,就会返回这个错误。
glEnableVertexAttribArray
使能通用顶点属性数组,默认情况下,存放顶点数据的缓冲区对着色器是不可见的,所以这里需要使能下。
函数原型
void glEnableVertexAttribArray(GLuint index);
参数说明
index:要使能的顶点属性索引,这里要说明,0表示使能顶点属性中的位置信息,也就是坐标值。
错误返回值
GL_INVALID_VALUE :当index的值大于或等于GL_MAX_VERTEX_ATTRIBS的值时会返回这个错误。
glVertexAttribPointer
注:这篇文章还没写完,等有了时间再补完。