@kudinovdenis

Какова логика вращения объекта (vbo) средствами OpenGL с использованием GLSL?

Привет,
Использую OpenGL 4.x, попутно само собой шейдеры, рисуя Патрика из спанч-боба, чтобы было веселее =)
Вот он, знакомьтесь:
a6d081e01b5647d0abac0a78fe4c4322.png

В реализации поворота очевидно ошибка. Хоть сам поворот и происходит, но иногда с рывками, с разной скоростью.

Немного теории
Ясно, что относительно начала координат поворот достигается умножением Матрицы Поворота(МП)
6d8465ea169c0ff442a4b60070e07564.png на вектор координат
|x|
|y|
|z|

Теперь к вопросу о реализации
Vertex Shader:
#version 400\n 
		 layout(location = 0) in vec3 vertex_position; 
		 layout(location = 1) in vec3 vertex_colour; 
		 layout(location = 2) in vec3 modifier_pos; 
		 layout(location = 3) in int angle; 
		 in vec3 vp; 
		 smooth out vec3 colour; 
		 void main () { 
		 	colour = vertex_colour; 
		 	vec3 rot1 = vec3(cos(radians(angle)), sin(radians(angle)), 0); 
		 	vec3 rot2 = vec3(-sin(radians(angle)), cos(radians(angle)), 0); 
		 	vec3 rot3 = vec3(0, 0, 1); 
		 	mat3 rot = mat3(rot1, rot2, rot3); 
		 	gl_Position = vec4 ( ((vertex_position + modifier_pos) * rot), 1.0); 
		 } ;

Идеология следующая:
  • vertex_position -- задаётся один раз до первой отрисовки
  • vertex_colour -- цвет вершины
  • modifier_pos -- некий offset для перемещения объекта по осям
  • три вестора rot1, rot2, rot3 -- столбцы МП
  • mat3 -- сама МП
В коде реализовано следующим образом: (почему-то побилась табуляция)
При отрисовке каждого фрейма стоит условие на клавишу поворота ("R")
if (glfwGetKey(window, GLFW_KEY_R)) {
			std::cout << "detected R btn" << std::endl;
			for (int i = 0; i < modelLoader.vertexs_counter; i++) {	
				if (rotArray[i] == 360) {
					rotArray[i] = 0;
				}
				rotArray[i] += 1;
			}
			glBindBuffer(GL_ARRAY_BUFFER, uiVBO[4]);
			glBufferData(GL_ARRAY_BUFFER, modelLoader.vertexs_counter * sizeof(float), &rotArray[0], GL_STATIC_DRAW);
			glEnableVertexAttribArray(3);
			glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, 0);
		}

vertexs_counter здесь на самом деле не честное количество вершин, а честное количество компонент (x, y, z), т.е. домноженное на три.

Правильно ли выбрано место для поворота, и сама его реализация?

В общем и целом он поворачивается, не бьётся при этом. Но поворачивается рывками, на малых углах очень быстро, на углах около 300 градусов начинает поворачиваться медленнее, затем по сбросу угла снова быстро. Рывками я назвал резкие скачки на примерно 90 градусов в сторону, противоположную повороту. Таких рывков я замечаю два на полный оборот.

Вот результат вращения Патрика напоследок:
cbc020e2d5754c45b8b801e02f29bc5a.pngP.S. В голове у меня таится мысль о том, что я не понял сути использования vbo, а как следствие, использую неправильный подход к отрисовке и/или изменению объекта.
Спасибо, что дочитали. Совету опытных и не очень людей буду рад.
  • Вопрос задан
  • 3659 просмотров
Пригласить эксперта
Ответы на вопрос 1
SHVV
@SHVV
VBO для того и сделано, чтобы загружать его в GPU один раз и больше не трогать.
То что для поворота вы фактически модифицируете вершины - абсолютно не верно.
Для передачи матрицы трансформации в шейдер нужно использовать Uniform-ы.
Тут простенький урок с вращающимся кубиком и использованием VBO.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы