OpenGL: Study Notes 2 - Draw Triangle 画三角形
# 目标
- 学会使用VAO, VBO
- 画一个三角形 (使用默认着色器)
# 原理
## 归一化坐标表示
![](https://learnopengl.com/img/getting-started/ndc.png)
## vertex buffer objects (VBO)
![VBO](https://learnopengl.com/img/getting-started/vertex_attribute_pointer.png)
## Vertex Array Object (VAO)
用来管理VAO
![VAO](https://learnopengl.com/img/getting-started/vertex_array_objects.png)
# 程序
```cpp
// glad must put befor GLFW
#include
#include
#include
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
float vertices[] = {
-0.5f, -0.5f, 0.0f, //left
0.5f, -0.5f, 0.0f, //right
0.0f, 0.5f, 0.0f //top
};
GLFWwindow* window;
int init();
void VOASet();
int main()
{
init();
// draw triangle
VOASet();
// render loop
// -----------
while (!glfwWindowShouldClose(window)) {
// input
// -----
processInput(window);
// render
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw triangle
glDrawArrays(GL_TRIANGLES, 0, 3); // VBO 0->3
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}
//输入处理函数
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
//窗口大小设置回调函数
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
int init()
{
//设置OpenGL版本等信息
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "OpenGLExample", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//把OpenGL的函数指针导入给GLAD
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
}
void VOASet()
{
// ID
unsigned int VBO, VAO;
// 生成VAO
glGenVertexArrays(1, &VAO);
// 生成VBO
glGenBuffers(1, &VBO);
// 绑定VAO & VBO
glBindVertexArray(VAO);
// 指定这是一个VBO buffer,因为buffer的各类有很多种
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 开辟显存空间
// p1: 目标, p1: 写多少数据, p3: 写什么内容, p4: 表示以后不修改
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 告诉显卡值的结构
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
```
# 结果
No comments