我是OpenGL编程的完整入门者,正在尝试遵循learnopengl.com的Breakout教程,但希望将球绘制为实际的圆,而不是使用Joey建议的纹理四边形。但是,Google针对“ draw circle opengl 3.3”或类似短语抛出的所有结果似乎都至少存在了几年,并且使用了比该版本还要早的API:-(
我找到的最接近的东西是this SO question,但是OP只是必须使用自定义的VertexFormat
对象来抽象一些细节,而没有分享他/她的实现!只是我的运气! :P
还有this YouTube tutorial使用了看似较旧的API版本,但是逐字复制代码(除了最后几行代码看起来很旧),我还是一无所获。
该教程中我的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);
}
这是SpriteRenderer::DrawSprite()
方法(与原始方法的唯一区别是第24-28行):
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);
}
最后,着色器(与用于四边形的着色器不同):
// 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);
}
P.S。我知道我可以只使用四边形,但是我正在尝试学习如何在OpenGL中绘制 all 基本体,而不仅仅是四边形和三角形(无论如何,要感谢Joey)!
PPS我刚刚意识到,learnopengl.com网站上有一整节专门用于调试OpenGL应用程序,因此我进行了设置,但无济于事:-(我不认为错误处理受驱动程序支持(Intel按照说明,未设置GL_CONTEXT_FLAG_DEBUG_BIT
,因为UHD Graphics 620是最新的驱动程序:
在GLFW中请求调试上下文非常容易,因为我们要做的就是向GLFW传递一个我们希望拥有调试输出上下文的提示。我们必须在调用glfwCreateWindow之前执行此操作:
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT,GL_TRUE);
一旦我们初始化GLFW,如果我们使用的是OpenGL 4.3或更高版本,我们应该有一个调试上下文,否则我们必须抓住机会,希望系统仍然能够请求调试上下文。否则,我们必须使用其OpenGL扩展请求调试输出。
要检查是否成功初始化了调试上下文,我们可以查询OpenGL:
GLint标志; glGetIntegerv(GL_CONTEXT_FLAGS,&flags);
if(标志和GL_CONTEXT_FLAG_DEBUG_BIT){ //初始化调试输出 }
从未输入过该if
语句!
答案 0 :(得分:0)
感谢@Mykola对this question的回答,我已经中途了:
int status = std::system("ls -l >test.txt"); // execute the UNIX command "ls -l >test.txt"
std::cout << std::ifstream("test.txt").rdbuf();
std::cout << "Exit code: " << WEXITSTATUS(status) << std::endl;
我还有两个问题:
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;
}
代替GL_TRIANGLE_FAN
得到一个彩色的圆圈。但这对我来说没有输出结果:-(为什么?