文章目录
My Github Link
写再最开头:learnOpengl网站用的gflw3和glad两个库,由于我自己配置的环境是glut+glew两个库,所以我把那些例子改为了能在glut+glew两个库下运行的代码。
顶点数组对象:Vertex Array Object,VAO
顶点缓冲对象:Vertex Buffer Object,VBO
索引缓冲对象:Element Buffer Object,EBO或Index Buffer Object,IBO
参考:
https://blog.youkuaiyun.com/dcrmg/article/details/53556664
learnOpenGL网站实例代码
learnOpenGLl中文网站(个人认为最适合新手的教程)
VBO使用glDrawArrays()函数画梯形
#include <stdlib.h>
#include<iostream>
#include<GL/glew.h>
#include<GL/glut.h>
void userInit(); //自定义初始化
void display(void);
GLuint vboId;//vertex buffer object句柄
GLuint vaoId;//vertext array object句柄
GLuint programId;//shader program 句柄
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(512, 512);
glutCreateWindow("Rectangle demo");
//使用glew,需要执行glewInit,不然运行过程会报错
//glewInit要放在glut完成了基本的初始化之后执行
glewInit();
//自定义初始化,生成VAO,VBO对象
userInit();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void userInit()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
//创建顶点数据
const GLfloat vertices[] = {
-0.5f,-0.5f,0.0f,1.0f,
0.5f,-0.5f,0.0f,1.0f,
0.25f,0.5f,0.0f,1.0f,
-0.25f,0.5f,0.0f,1.0f,
};
//创建VBO对象
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
//传入VBO数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//解除VBO绑定
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//绘制回调函数
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//绑定VBO
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glEnableVertexAttribArray(0);
//解释顶点数据方式
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
//绘制模型
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
result:
在上一个例子的基础上改变背景颜色
数据类型由RGBA改为RGB
void userInit(); //自定义初始化
void display(void);
GLuint vboId;//vertex buffer object句柄
GLuint vaoId;//vertext array object句柄
GLuint programId;//shader program 句柄
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(512, 512);
glutCreateWindow("Rectangle demo");
//使用glew,需要执行glewInit,不然运行过程会报错
//glewInit要放在glut完成了基本的初始化之后执行
glewInit();
//自定义初始化,生成VAO,VBO对象
userInit();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void userInit()
{
glClearColor(1.0f, 0.3f, 0.3f, 1.0f);//背景颜色
//创建顶点数据
const GLfloat vertices[] = {
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.25f,0.5f,0.0f,
-0.25f,0.5f,0.0f
};
//创建VBO对象
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
//传入VBO数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//解除VBO绑定
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//绘制回调函数
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//绑定VBO
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glEnableVertexAttribArray(0);
//解释顶点数据方式
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
//绘制模型
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
result:
VBO+VAO使用glDrawArrays()函数画梯形
VAO与VBO的关系,VAO利用VBO加载数据
#include <stdlib.h>
#include<iostream>
#include<GL/glew.h>
#include<GL/glut.h>
void userInit(); //自定义初始化
void display(void);
GLuint VAO;
GLuint VBO;
unsigned int fragmentShader;
unsigned int vertexShader;
unsigned int shaderProgram;
const GLfloat vertices[] = {
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.25f,0.5f,0.0f,
-0.25f,0.5f,0.0f,
};
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(512, 512);
glutCreateWindow("Rectangle demo");
//使用glew,需要执行glewInit,不然运行过程会报错
//glewInit要放在glut完成了基本的初始化之后执行
glewInit();
//自定义初始化,生成VAO,VBO对象
userInit();
glutDisplayFunc(display);
glutMainLoop();
glDeleteVertexArrays(1, &VAO);
glDeleteProgram(shaderProgram);
return 0;
}
void userInit()
{
glClearColor(1.0f, 0.3f, 0.3f, 1.0f);//背景颜色
//创建VAO对象
glGenVertexArrays(1, &VAO);
//VAO绑定
glBindVertexArray(VAO);
//创建VBO对象
glGenBuffers(1, &VBO);
//VBO绑定
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//给VBO传入数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//解绑VAO
glBindVertexArray(0);
//解绑VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//绘制回调函数
void display(void)
{
//绑定VA0
glBindVertexArray(VAO);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO); // 这里仅仅绑定了VAO,无需再绑定VBO
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
glutSwapBuffers();
}
result:
VBO+VAO+片段着色器给梯形着色
#include <stdlib.h>
#include<iostream>
#include<GL/glew.h>
#include<GL/glut.h>
void userInit(); //自定义初始化
void display(void);
GLuint VAO;
GLuint VBO;
unsigned int fragmentShader;
unsigned int vertexShader;
unsigned int shaderProgram;
const GLfloat vertices[] = {
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.25f,0.5f,0.0f,
-0.25f,0.5f,0.0f,
};
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(512, 512);
glutCreateWindow("Rectangle demo");
//使用glew,需要执行glewInit,不然运行过程会报错
//glewInit要放在glut完成了基本的初始化之后执行
glewInit();
//自定义初始化,生成VAO,VBO对象
userInit();
glutDisplayFunc(display);
glutMainLoop();
glDeleteVertexArrays(1, &VAO);
glDeleteProgram(shaderProgram);
return 0;
}
void userInit()
{
//glClearColor(1.0f, 0.3f, 0.3f, 1.0f);//背景颜色
//创建VAO对象
glGenVertexArrays(1, &VAO);
//VAO绑定
glBindVertexArray(VAO);
//创建VBO对象
glGenBuffers(1, &VBO);
//VBO绑定
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//给VBO传入数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//解绑VAO
glBindVertexArray(0);
//解绑VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// 片段着色器给三角形着色
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// link shaders
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
//绘制回调函数
void display(void)
{
//绑定VA0
glBindVertexArray(VAO);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO); // 这里仅仅绑定了VAO,无需再绑定VBO
glUseProgram(shaderProgram);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
glutSwapBuffers();
}
result:
EBO+VBO+VAO画两个三角形
可以按照上一个例子给三角形着色
#include <stdlib.h>
#include<iostream>
#include<GL/glew.h>
#include<GL/glut.h>
void userInit(); //自定义初始化
void display(void);
GLuint VAO;
GLuint VBO;
GLuint EBO;
GLuint programId;
float vertices[] = {
-1.0f, -0.5f, 0.0f,
0.f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
1.0f,-0.5f,0.0f,
0.5f,0.5f,0.0f
};
unsigned int indices[] = { // 注意索引从0开始!
0, 1, 2, // 第一个三角形
1, 3, 4 // 第二个三角形
};
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(512, 512);
glutCreateWindow("Rectangle demo");
//使用glew,需要执行glewInit,不然运行过程会报错
//glewInit要放在glut完成了基本的初始化之后执行
glewInit();
//自定义初始化,生成VAO,VBO对象
userInit();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void userInit()
{
glGenBuffers(1, &EBO);//创建EBO
glGenVertexArrays(1, &VAO);//创建VAO
glGenBuffers(1, &VBO);//创建VBO
glBindVertexArray(VAO);//绑定VAO
glBindBuffer(GL_ARRAY_BUFFER, VBO);//绑定VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//绑定EBO
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//这里缓冲定义和之前不一样
//解释顶点数据方式
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//解除VAO绑定
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
//绘制回调函数
void display(void)
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//绑定VAO
glBindVertexArray(VAO);
//绘制模型
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
result: