季节问候大家!我改写了this tutorial中的代码以支持使用VAO / VBO,但现在我明白了:
而不是一个漂亮的圆形圆圈。这是代码:
#define GLEW_STATIC
#include <GLEW/glew.h>
#include <GLFW/glfw3.h>
#include <corecrt_math_defines.h>
#include <cmath>
#include <vector>
#define SCREEN_WIDTH 3000
#define SCREEN_HEIGHT 1900
void drawPolygon(GLuint& vao, GLuint& vbo, GLfloat x,
GLfloat y, GLdouble radius, GLint numberOfSides);
int main(void) {
if (!glfwInit()) {
return -1;
}
GLFWwindow* window = glfwCreateWindow(SCREEN_WIDTH,
SCREEN_HEIGHT, "Hello World", NULL, NULL);
if (!window) {
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
glGetError();
glViewport(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT);
GLuint vao, vbo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT, -1, 1);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
drawPolygon(vao, vbo, SCREEN_WIDTH / 2,
SCREEN_HEIGHT / 2, 250.0f, 50);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void drawPolygon(GLuint& vao, GLuint& vbo, GLfloat x,
GLfloat y, GLdouble radius, GLint numberOfSides) {
int numVertices = numberOfSides + 2;
GLdouble twicePi = 2.0f * M_PI;
vector<GLdouble> circleVerticesX;
vector<GLdouble> circleVerticesY;
circleVerticesX.push_back(x);
circleVerticesY.push_back(y);
for (int i = 1; i < numVertices; i++) {
circleVerticesX.push_back(x + (radius *
cos(i * twicePi / numberOfSides)));
circleVerticesY.push_back(y + (radius *
sin(i * twicePi / numberOfSides)));
}
vector<GLdouble> vertices;
for (int i = 0; i < numVertices; i++) {
vertices.push_back(circleVerticesX[i]);
vertices.push_back(circleVerticesY[i]);
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(
GLdouble), vertices.data(), GL_STATIC_DRAW);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_DOUBLE, GL_FALSE,
2 * sizeof(GLdouble), (void*)0);
glDrawArrays(GL_TRIANGLE_FAN, 0, 27);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
我到底做错了什么?!使用the original code可以工作,所以我对这个荒谬的结果感到困惑! MTIA给任何可以帮助的人:-)
您的VBO的大小为numVertices * sizeof(GLdouble)
,它是顶点数据的实际大小的一半(每个顶点都有一个x 和 y分量)。因此,最终绘制的顶点是VBO实际具有顶点数据的两倍。读取VBO的边界时,在OpenGL实现中恰好导致零,这就是为什么圆下半部分的所有顶点都在左下角的原因…
注释夫妇:
double
,除非需要它。 double
占用两倍的内存带宽,并且double
的算术通常至少比float
慢一点。特别是GPU是为float
算术而构建的。尤其是在消费类GPU上,double
算法比float
慢[(明显)](一个数量级)。您实际上不需要中心点。由于圆是凸形的,因此您可以简单地将圆上的点之一用作风扇的中心顶点。 glDrawArrays
调用绘制顶点的实际数量,而不仅仅是总是27
…