C++ 加载指向OpenGL函数的指针是绝对必要的吗
我从在线教程开始学习OpenGL,其中一些教程使用了GLEAD和GLEW。 我读到有必要手动或使用加载库加载指向OpenGL函数的指针C++ 加载指向OpenGL函数的指针是绝对必要的吗,c++,opengl,C++,Opengl,我从在线教程开始学习OpenGL,其中一些教程使用了GLEAD和GLEW。 我读到有必要手动或使用加载库加载指向OpenGL函数的指针 但是有些教程只使用glut,没有使用指针来加载像glbegin这样的函数。您看到的OpenGL有两个不同的部分:OpenGL遗留部分和现代api。 您提到的不使用指针的教程使用的是遗留函数,这些函数非常简单,但速度也很慢 OpenGL遗留功能: glBegin(GL_QUADS); glVertex2d(-0.5, -0.5); glVertex2d( 0.5,
但是有些教程只使用glut,没有使用指针来加载像glbegin这样的函数。您看到的OpenGL有两个不同的部分:OpenGL遗留部分和现代api。 您提到的不使用指针的教程使用的是遗留函数,这些函数非常简单,但速度也很慢 OpenGL遗留功能:
glBegin(GL_QUADS);
glVertex2d(-0.5, -0.5);
glVertex2d( 0.5, -0.5);
glVertex2d( 0.5, 0.5);
glVertex2d(-0.5, 0.5);
glEnd();
这些函数简单而缓慢:基本上,您可以将每个顶点分别发送到GPU
现代管道:(来自LearnOpenGL.com的不完整代码示例)
使用这个现代的管道,你已经在一个数组中有了所有的顶点,你用glBufferData()将整个数组发送到GPU,这就是你对指针的意思——实际上所有的都只是数组
通过这种方式,所有数据都在一大块数据中发送,所有这些三角形都是通过一个draw调用绘制的:使用这种方法,每帧可以绘制数万个三角形
但还有更多:(同样,LearnOpenGL.com的不完整代码示例)
这段代码使用的是顶点索引,这是常用的方法。如果没有此选项,则必须为每个三角形指定三个顶点,并包含所有数据,这意味着如果多个面使用同一顶点,则该顶点将被复制。但使用此方法,您只需指定一次所有顶点,并在单独的索引缓冲区中指定哪些面应使用哪些顶点,您基本上会说:
我想要这些顶点在这些位置,然后我想要一个从顶点1到顶点7到顶点89的三角形
但是回到主题,最后一种方法——索引缓冲——是使用最广泛的方法,可能也是您应该使用的方法。是的,它要复杂得多,您需要顶点数组、顶点缓冲区、索引缓冲区、顶点着色器、片段着色器等,但是当您阅读这些教程时,它们会详细解释所有内容,您还可以查看示例中的源代码
另外,您可能指的是加载.obj文件的模型加载器,但加载模型独立于渲染管道-如果您使用的是遗留函数(不应该这样做),您也需要它
glad和glut之间没有区别,它们都是提供OpenGL函数的头文件-只是具有相同功能的不同项目即时模式()OpenGL函数(如glBegin
)可能由“gl.h”提供。“Moden”OpenGL函数必须由loder(如glad或gelw)加载。。
float vertices[] = {
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f // top
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, 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);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while(true) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
float vertices[] = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
unsigned int indices[] = { // note that we start from 0!
0, 1, 3, // first Triangle
1, 2, 3 // second Triangle
};
unsigned int VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (true) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}