绘制流程为
1、创建上下文,初始化opengl环境
#include <GLFW/glfw3.h>
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, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
2、创建顶点着色器与片段着色器
//顶点着色器
const char* learnVertexShader = R"
(
attribute vec4 position;
void main()
{
gl_Position = vec4(position * 2.0 -1.0);
}
)";
//片段着色器
const char* learnFragmentShader = R"
(
void main()
{
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
)";
3、创建着色器程序,链接到第2步的两个着色器
//创建着色器
//unsigned int 与GLuint是同样类型
//创建顶点着色器
unsigned int vs = glCreateShader(GL_VERTEX_SHADER);
const GLchar* vertexSource = [learnVertexShader UTF8String];
glShaderSource(vs,1,&vertexSource,nullptr);//
glCompileShader(vs);
//错误处理
int result;
glGetShaderiv(vs,GL_COMPILE_STATUS,&result);
if(result==GL_FALSE){
//输出错误信息,glGetShaderInfoLog();
}
//创建片段着色器
unsigned int fs = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* fargmentSource = [learnFragmentShader UTF8String];
glShaderSource(fs,1,&fargmentSource,nullptr);//
glCompileShader(fs);
glGetShaderiv(fs,GL_COMPILE_STATUS,&result);
if(result==GL_FALSE){
//输出错误信息,glGetShaderInfoLog();
}
//创建着色器程序
unsigned int program = glCreateProgram();
glAttachShader(program,vs);//添加到着色器程序中
glAttachShader(program,fs);
glLinkProgram(program);//链接到着色器程序
//错误处理
glValidateProgram(program);
GLint validationStatus;
glGetProgramiv(program, GL_VALIDATE_STATUS, &validationStatus);
if (validationStatus == GL_FALSE) {
// 输出错误信息
GLint infoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
GLchar* infoLog = new GLchar[infoLogLength];
GLsizei bufferSize;
glGetProgramInfoLog(program, infoLogLength, &bufferSize, infoLog);
printf(infoLog);
delete[] infoLog;
}
}
//已链接,可以删除着色器对象
glDeleteShader(vs);
glDeleteShader(fs);
//在GL环境中使用着色器程序
glUseProgram(program);
4、创建顶点数组、索引数组
//顶点数组
float positions[8] = {
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f
};
//索引数组
unsigned int indices[] = {
0 , 1 , 2 ,
0 , 2 , 3 ,
};
//注意顶点的坐标位于-1到1之间
5、创建和绑定缓冲区
//绑定索引缓冲区
unsigned int ibo;
glGenBuffers(1,&ibo);//声明缓冲区,1表示个数
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);//绑定缓冲区
glBufferData(GL_ELEMENT_ARRAY_BUFFER,6*sizeof(unsigned int),indices,GL_STATIC_DRAW);
//绑定顶点缓冲区
unsigned int buffer;
glGenBuffers(1,&buffer);//声明缓冲区,1表示个数
glBindBuffer(GL_ARRAY_BUFFER,buffer);//绑定缓冲区
//绑定缓冲区数据,最后一个参数表示数据很少修改,否则使用L_DYNAMIC_DRAW
glBufferData(GL_ARRAY_BUFFER,8*sizeof(float),positions,GL_STATIC_DRAW);
6、设置顶点属性和激活顶点数组
/*
index:指定要设置的顶点属性的索引值。这个索引值对应于顶点着色器中对应顶点属性的位置。
size:指定每个顶点属性的组件数量。例如,如果顶点属性是二维坐标,则 size 为 2;如果是颜色属性,则 size 为 3 或 4。
type:指定顶点属性数据的类型。常见的类型包括 GL_FLOAT (浮点型)、GL_INT (整型) 等。
normalized:指定是否对非浮点型数据进行归一化处理。
stride:指定相邻顶点属性之间的偏移量(以字节为单位)。如果顶点属性是连续存储的,可以将 stride 设置为 0。
pointer:指定顶点属性数据在缓冲区中的起始位置的偏移量(以字节为单位)。
glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, _customVertices);/
*/
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,sizeof(float) * 2,0);
7、绘制
//绘制
//glDrawArrays(GL_TRIANGLES,0,3);// 绘制三角形,从索引0开始绘制,共计3个顶点
//使用索引来绘制,要用GL_ELEMENT,6表示索引数量,最后一个指针表示从缓冲区的哪里开始
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,nullptr);
版权声明:本文为Akiyama_sou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。