如何在具有正交投影的OpenGL Core 3.3中绘制圆?

问题描述 投票:0回答:1

我是OpenGL编程的一个完整的初学者,正在尝试按照learnopengl.com的Breakout教程进行操作,但希望将球绘制为实际的圆,而不是使用Joey建议的纹理四边形。但是,对于“ draw circle opengl 3.3”或类似的短语,Google抛给我的所有结果似乎都至少存在了几年,并且使用了比该版本还要早的版本:-(

我发现的最接近的东西是this SO question,但是,当然,OP只是had使用自定义VertexFormat对象来抽象一些细节,而无需共享他/她的实现!只是我的运气! :P

[还有this YouTube tutorial使用的API看似较旧的版本,但是逐字复制代码(最后几行除外,因为代码看上去很旧)仍然无济于事。

我的本教程的SpriteRenderer::initRenderData()版本:

SpriteRenderer::initRenderData()

这是void SpriteRenderer::initRenderData() { GLuint vbo; auto attribSize = 0; GLfloat* vertices = nullptr; // Determine whether this sprite is a circle or // quad and setup the vertices array accordingly if (!this->isCircle) { attribSize = 4; vertices = new GLfloat[24] {...} // works for rendering quads } else { // This code is adapted from the YouTube tutorial that I linked // above and is where things go pear-shaped for me...or at least // **not** circle-shaped :P attribSize = 3; GLfloat x = 0.0f; GLfloat y = 0.0f; GLfloat z = 0.0f; GLfloat r = 100.0f; GLint numSides = 6; GLint numVertices = numSides + 2; GLfloat* xCoords = new GLfloat[numVertices]; GLfloat* yCoords = new GLfloat[numVertices]; GLfloat* zCoords = new GLfloat[numVertices]; xCoords[0] = x; yCoords[0] = y; zCoords[0] = z; for (auto i = 1; i < numVertices; i++) { xCoords[i] = x + (r * cos(i * (M_PI * 2.0f) / numSides)); yCoords[i] = y + (r * sin(i * (M_PI * 2.0f) / numSides)); zCoords[i] = z; } vertices = new GLfloat[numVertices * 3]; for (auto i = 0; i < numVertices; i++) { vertices[i * 3] = xCoords[i]; vertices[i * 3 + 1] = yCoords[i]; vertices[i * 3 + 2] = zCoords[i]; } } // This is where I go back to the learnopengl.com code. Once // again, the following works for quads but not circles! glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 24 * sizeof( GLfloat), vertices, GL_STATIC_DRAW); glBindVertexArray(vao); glEnableVertexAttribArray(0); glVertexAttribPointer(0, attribSize, GL_FLOAT, GL_FALSE, attribSize * sizeof(GLfloat), (GLvoid*)0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } 方法(与原始方法的唯一区别是第24-28行):

SpriteRenderer::DrawSprite()

最后,着色器(与用于四边形的着色器不同:

SpriteRenderer::DrawSprite()

P.S。我知道我可以只使用一个四边形,但是我正在尝试学习如何在OpenGL中绘制all基本体,而不仅仅是四边形和三角形(感谢Joey)!

PPS我刚刚意识到,learnopengl.com网站上有一整节内容专门用于调试OpenGL应用程序,因此我将其设置为无效,但无济于事:-(我不认为错误处理受驱动程序支持(Intel UHD显卡620最新驱动程序),因为在按照说明进行操作后未设置void SpriteRenderer::Draw(vec2 position, vec2 size, GLfloat rotation, vec3 colour) { // Prepare transformations shader.Use(); auto model = mat4(1.0f); model = translate(model, vec3(position, 0.0f)); model = translate(model, vec3(0.5f * size.x, 0.5f * size.y, 0.0f)); // Move origin of rotation to center model = rotate(model, rotation, vec3(0.0f, 0.0f, 1.0f)); // Rotate quad model = translate(model, vec3(-0.5f * size.x, -0.5f * size.y, 0.0f)); // Move origin back model = scale(model, vec3(size, 1.0f)); // Lastly, scale shader.SetMatrix4("model", model); // Render textured quad shader.SetVector3f("spriteColour", colour); glActiveTexture(GL_TEXTURE0); texture.Bind(); glBindVertexArray(vao); if (!isCircular) { glDrawArrays(GL_TRIANGLES, 0, 6); } else { glDrawArrays(GL_TRIANGLE_FAN, 0, 24); // also tried "12" and "8" for the last param, to no avail } glBindVertexArray(0); }

在GLFW中请求调试上下文非常容易,因为我们要做的就是向GLFW传递一个我们希望拥有调试输出上下文的提示。我们必须在调用glfwCreateWindow之前执行此操作:

glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT,GL_TRUE);

一旦初始化GLFW,如果我们使用的是OpenGL 4.3或更高版本,我们应该有一个调试上下文,否则我们必须抓住机会,希望系统仍然能够请求调试上下文。否则,我们必须使用其OpenGL扩展请求调试输出。

要检查我们是否成功初始化了调试上下文,我们可以查询OpenGL:

GLint标志; glGetIntegerv(GL_CONTEXT_FLAGS,&flags);

如果(标志和GL_CONTEXT_FLAG_DEBUG_BIT){//初始化调试输出}

// Vertex shader #version 330 core layout (location = 0) in vec3 position; uniform mat4 model; uniform mat4 projection; void main() { gl_Position = projection * model * vec4(position.xyz, 1.0f); } // Fragment shader #version 330 core out vec4 colour; uniform vec3 spriteColour; void main() { colour = vec4(spriteColour, 1.0); } 语句永远不会输入!

c++ opengl glfw glew
1个回答
0
投票

感谢@Mykola对GL_CONTEXT_FLAG_DEBUG_BIT的回答,我已经到了一半:

if

哪个给了我this question

我还有两个问题:

  1. 为什么从中心到右侧有多余的线,我该如何解决?
  2. 根据相关SO答案上的numVertices = 43; vertices = new GLfloat[numVertices]; auto i = 2; auto x = 0.0f, y = x, z = x, r = 0.3f; auto numSides = 21; auto TWO_PI = 2.0f * M_PI; auto increment = TWO_PI / numSides; for (auto angle = 0.0f; angle <= TWO_PI; angle += increment) { vertices[i++] = r * cos(angle) + x; vertices[i++] = r * sin(angle) + y; } ,我应该能够在(0,0)处将另一个顶点添加到数组中,并使用this代替@user1118321's comment得到一个彩色的圆圈。但这对我来说没有输出:-(为什么?
© www.soinside.com 2019 - 2024. All rights reserved.