顶点缓冲对象 VBO(Vertex Buffer Object)
unsigned int VBO;
glGenBuffers(1, &VBO);//生成顶点缓冲对象
glBindBuffer(GL_ARRAY_BUFFER, VBO);//将新建的缓冲绑定至GL_ARRAY_BUFFER上
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//用于将用户的数据复制到当前绑定的缓冲
顶点数组对象 VAO(Vertex Array Object)
OpenGL的核心就是去使用VAO,如果VAO绑定失败,OpenGL将不会去绘制任何东西
unsigned int VAO;
glGenVertexArrays(1, &VAO);//生成VAO对象
glBindVertexArray(VAO);//绑定VAO对象
顶点着色器(Vertex Shader)
顶点着色器(Vertex Shader)是几个可编程着色器中的一个。如果我们打算做渲染的话,OpenGL需要我们至少设置一个顶点和一个片段着色器。
//顶点着色器代码
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
//创建一个着色器 类型为GL_VERTEX_SHADER
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);//将顶点着色器代码附着到着色器上
glCompileShader(vertexShader);//进行编译
片段着色器(Fragment Shader)
//片元着色器代码
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\0";
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
着色器程序对象(Shader Program Object)
着色器程序对象是多个着色器合并之后并最终完成链接的版本,如果要使用刚才编译的着色器,那么必须进行链接,编译相当于lib,而链接程序对象相当于dll。
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram,vertexShader);//将着色器附着到程序对象上
glAttachShader(shaderProgram,fragmentShader);
glLinkProgram(shaderProgram);//链接着色器对象
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
//0:指定我们要配置的顶点属性,在顶点着色器硬编码中layout(location = 0)
//3:指定顶点属性的大小,顶点属性是一个vec3,它由3个值组成,所以大小是3
//GL_FLOAT:GLSL中vec*都是由浮点数值组成的
//3 * sizeof(float):顶点属性的步长,三个坐标一共12个字节,所以偏移12
//(void *)0:它表示位置数据在缓冲中起始位置的偏移量(Offset),由于位置数据在数组的开头,所以这里是0
学完以上对象,就可以画出一个三角形
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
//ESC退出界面
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
//GLFW显示窗口宽度和高度
const unsigned int SCR_WIDTH = 1280;
const unsigned int SCR_HEIGHT = 720;
//顶点着色器代码
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
//片元着色器代码
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\0";
float vertices[] =
{
-0.5f, -0.5f, 0.0f, //左
0.5f, -0.5f, 0.0f, //右
0.0f, 0.5f, 0.0f //上
};
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
unsigned int VBO;
glGenBuffers(1, &VBO);//顶点缓冲对象
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//用于将用户的数据复制到当前绑定的缓冲
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);//和顶点着色器的layout (location = 0) 0对应,设置索引,在glDrawArrays之前调用
while (!glfwWindowShouldClose(window))
{
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
}