Всем доброго времени суток. Отлавливаю клики мыши, затем преобразую каждый клик, который является центром примитива, в некоторый набор точек. Каждый набор состоит из 3-х точек (примитив - треугольник), каждая точка задаётся 3-мя координатами. Т.к. я использую ортогональную проекцию - координаты хранятся в пиксельном виде. Так же запоминаю позицию каждого центра. В игровом цикле модельную матрицу переношу в центр фигуры, которая рисуется.
Проблема в следующем: когда я кликаю первый раз - фигура рисуется так, как и нужно. Второй и последующий разы уже рисуются так, будто бы начало моих координат установилось в точке, где был первый клик. Я понимаю, что где-то нужно матрицу делать единичной, но не могу понять где. Как я понимаю, это происходит уже в мировых координатах - их начало координат смещается после первого клика.
Использую:
Обработка клика мыши:
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
{
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
cout << "Координаты : x: " << xpos << " ; y: " << ypos << endl;
float left = 0.0f;
float right = 800.0f;
float bottom = 0.0f;
float top = 600.0f;
float x = ((xpos / WIDTH) * (right - left)) + left;
float y = ((ypos / HEIGHT) * (bottom - top)) + top;
cout << "Координаты openGL: x: " << x << " ; y: " << y << endl;
GLfloat upd[] = {
x - param, y - param, -1.0f,
x, y + param, -1.0f,
x + param, y - param, -1.0f,
};
//number of primitives:
numVertices++;
GLintptr vertexOffset = (numVertices-1) * sizeof(upd);
glBufferSubData(GL_ARRAY_BUFFER, vertexOffset, sizeof(upd), upd);
GLfloat posX1 = x;
GLfloat posY1 = y;
GLfloat posZ1 = -1.0f;
glm::vec3 newPosition = glm::vec3(posX1, posY1, posZ1);
position[numVertices-1] = newPosition;
}
Настройки параметров и рисование:
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow * window = glfwCreateWindow(800, 600, "Learn OpenGL", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Ошибка при создании окна GLFW!" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (window == nullptr) return -1;
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
return -1;
int width_t, heigth_t;
glfwGetFramebufferSize(window, &width_t, &heigth_t);
glViewport(0, 0, width_t, heigth_t);
//устанавливаем callback-функции (регистрация идёт ПОСЛЕ создания окна и ДО запуска игрового цикла):
glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
ShadersFor1_2Lab ourShader("shader.vs", "shader.frag");
GLuint VAO, VBO;
GLsizeiptr vertexBufferSize = 10 * 3 * 3 * sizeof(GLfloat);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertexBufferSize, NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
//игровой цикл:
while (!glfwWindowShouldClose(window))
{
glfwPollEvents(); //проверяет, вызвано ли какое-либо событие. и если да - исполняет его
//glEnable(GL_DEPTH_TEST);
glClearColor(1.0f, 1.0f, 1.0f, .1f); //устанавливает состояние
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //использует состояние
ourShader.Use();
GLint projectionLoc = glGetUniformLocation(ourShader.Program, "projection"),
viewLoc = glGetUniformLocation(ourShader.Program, "view"),
modelLoc = glGetUniformLocation(ourShader.Program, "model");
glm::mat4 view(1.0);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -2.0f));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glm::mat4 projection(1.0);
projection = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(VAO);
glm::mat4 model(1.0f);
for (GLuint i = 0; i < position.size(); i++)
{
glm::mat4 model(1.0);
model = glm::translate(model, position[i]);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 3);
}
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
В цикле
for (GLuint i = 0; i < position.size(); i++)
{
glm::mat4 model(1.0);
model = glm::translate(model, position[i]);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 3);
}
вы для i-го треугольника используете свою матрицу модели, но рисуете первые три вершины из буфера, которые соответствуют нулевому треугольнику. Нужно вторым параметром указывать смещение в буфере:
glDrawArrays(GL_TRIANGLES, i * 3, 3);
Еще несколько настораживает то, что здесь
float x = ((xpos / WIDTH) * (right - left)) + left;
float y = ((ypos / HEIGHT) * (bottom - top)) + top;
cout << "Координаты openGL: x: " << x << " ; y: " << y << endl;
GLfloat upd[] = {
x - param, y - param, -1.0f,
x, y + param, -1.0f,
x + param, y - param, -1.0f,
};
вы задаете позиции вершины треугольника в мировых координатах смещенными на (x; y), а затем в цикле загружаете в шейдер матрицу модели, которой еще раз двигаете треугольник на (x; y). Чему равны WIDTH и HEIGHT?
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Описать структуру ABITURIENT со следующими полями:
На странице JSP находиться форма для добавления данных в БД с 3 кнопками (Add,Update,Delete)