Первая проблема - это ортографическая проекция.
projection = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
Поскольку ваша геометрия рисуется с координатой z, равной 0,0, она обрезается в ближней плоскости проекции (0,1).Круг обведен (0, 0), поэтому вы должны выбрать проекцию, которая удерживает центр в центре области просмотра:
projection = glm::ortho(-400.0f, 400.0f, -300.0f, 300.0f, -1.0f, 1.0f);
Когда вы используете glVertexAttribPointer
glVertexAttribPointer(0, 2, GL_INT, GL_TRUE, 0, (void *)0);
затем 4-й параметр указывает, следует ли нормализовать значения данных с фиксированной точкой (GL_TRUE
) или преобразовать их непосредственно в значения с фиксированной точкой (GL_FALSE
).Это означает, что если параметр GL_TRUE
, то значение в диапазоне типа данных int
отображается на значения с плавающей запятой в диапазоне [-1.0, 1.0].Вы хотите преобразовать целые значения 1: 1 в значения точки трения, поэтому параметр должен быть GL_FALSE
:
glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, (void *)0);
Примечание. В качестве альтернативы можно использовать glVertexAttribIPointer
(фокус на I
), который предназначен для входных атрибутов интегральных вершинных шейдеров:
glVertexAttribIPointer(0, 2, GL_INT, 0, (void *)0);
Конечно, тогда тип данных атрибута в вершинном шейдере долженбыть ivec2
вместо vec2
:
#version 330 core
layout (location = 0) in ivec2 apos;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(vec2(apos), 0.0, 1.0);
}
Идея буфера состоит в том, чтобы хранить в буфере как можно больше данных, а затем визуализировать все вершины одновременно.
Но даже если вы хотите нарисовать одну точку, плохая идея - создать Vertex Array Object и Vertex Buffer Object для каждой точки и уничтожить ее сразу после рисования.
Создание пустого буфера и объекта массива вершин при инициализации перед основным циклом:
unsigned int VBO, VAO;
int main() {
// [...]
glGenVertexArrays(1,&VAO);
glBindVertexArray(VAO);
glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 2*sizeof(int), 0, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, (void *)0);
//glVertexAttribIPointer(0, 2, GL_INT, 0, (void *)0);
glEnableVertexAttribArray(0);
while(!glfwWindowShouldClose(window))
{
// [...]
}
// [...]
}
Использование glBufferSubData
для инициализации / изменения содержимогохранилища данных буферных объектов, перед рисованием точки:
void plot(int x, int y)
{
int vertices[] = {x, y};
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glDrawArrays(GL_POINTS, 0, 1);
}
SiОбратите внимание, что третий параметр glDrawArrays
- это число координат вершины, но не количество элементов в массиве.Размер кортежа (число компонентов на координату) задается в спецификации атрибута вершины.