Я - новичок в программировании OpenGL и пытаюсь следовать учебному пособию Breakout на learnopengl.com , но хотел бы нарисовать шар как реальный круг, вместо того чтобы использовать текстурированный квад, как Джоипредлагает. Тем не менее, каждый результат, который Google выдает мне за «Draw Circle OpenGL 3.3» или подобные фразы, кажется, по крайней мере, несколько лет, и использует даже более старые версии API: - (
Самая близкая вещь, которую я нашел, это этот вопрос , но, конечно, у ОП просто было , чтобы использовать пользовательский объект VertexFormat
для абстрагирования некоторых деталей безподелился своей реализацией такой! Просто моя удача!: P
Также есть этот урок YouTube , который использует, казалось бы, более старую версию 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);
}
PS Я знаю, что могу просто использовать квад, но я пытаюсьЧтобы научиться рисовать все примитивы в OpenGL, а не только четырехугольники и треугольники (в любом случае, спасибо, Джои)!
PPS Я только что понял, что на сайте learnopengl.com есть целый раздел, посвященныйотлаживать приложения OpenGL, поэтому я настроил это, но безрезультатно :-( Я не думаю, что обработка ошибок поддерживается моим драйвером (последний драйвер Intel UHD Graphics 620), так как GL_CONTEXT_FLAG_DEBUG_BIT
не был установлен после следования инструкциям:
Запрос контекста отладки в GLFW удивительно прост, так как все, что нам нужно сделать, - это передать GLFW подсказку о том, что нам бы хотелось иметь выходной контекст отладки. Мы должны сделать это прежде, чем мы вызовем glfwCreateWindow:
glfwWindowHint (GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
Как только мы инициализируем GLFW, у нас должен быть контекст отладки, если мы используем OpenGL версии 4.3 или выше, иначе мы должны рискнуть и надеяться, что система все еще сможет запросить контекст отладки. В противном случае мы должны запросить выходные данные отладки, используя расширение (я) OpenGL.
Чтобы проверить, успешно ли мы инициализировали контекст отладки, мы можем запросить OpenGL:
GLint flags;glGetIntegerv (GL_CONTEXT_FLAGS, & flags);
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) {// инициализировать выходные данные отладки}
Этот оператор if
никогда не вводится!