Ну, вам не нужно использовать glLoadMatrix и другие встроенные функции матрицы, потому что это может быть еще сложнее, чем обработка ваших собственных матриц.
Простой пример камеры, не контролируя его, его статическая камера:
glm::mat4x4 view_matrix = glm::lookAt(
cameraPosition,
cameraPosition+directionVector, //or the focus point the camera is pointing to
upVector);
возвращает матрицу 4x4, это вид матрицы.
glm::mat4x4 projection_matrix =
glm::perspective(60.0f, float(screenWidth)/float(screenHeight), 1.0f, 1000.0f);
это матрица проекции
так что теперь у вас есть вид и проекционные матрицы, и вы можете отправить его в шейдер:
gShader->bindShader();
gShader->sendUniform4x4("view_matrix",glm::value_ptr(view_matrix));
gShader->sendUniform4x4("projection_matrix",glm::value_ptr(projection_matrix));
bindshader является простой glUseProgram(shaderprog);
Единая программа -
void sendUniform4x4(const string& name, const float* matrix, bool transpose=false)
{
GLuint location = getUniformLocation(name);
glUniformMatrix4fv(location, 1, transpose, matrix);
}
Ваша матричная модель индивидуальна для каждого из объектов:
glm::mat4x4 model_matrix= glm::mat4(1); //this is the identity matrix, so its static
model_matrix= glm::rotate(model_matrix,
rotationdegree,
vec3(axis)); //same as opengl function.
Это создало модель матрицы, и вы можете отправить его в шейдер слишком
gShader->bindShader();
gShader->sendUniform4x4("model_matrix",glm::value_ptr(model_matrix));
glm::value_ptr(...)
создает 2 одномерный массив вашего матрица.
в вашем шейдерном коде не используются матрицы glModelViewMatrix и gl_ProjectionMatrix, передаются через форму.
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(){
gl_Position = projection_matrix*view_matrix*model_matrix*gl_Vertex;
//i wrote gl_Vertex because of the glutSolidTeapot.
}
Я никогда не использовал эту сборку в сеточной функции, так что я не знаю, как это работает, предположим, что он посылает вершины в шейдер с непосредственным использованием режима gl_Vertex. Если вы создаете свои собственные сетки, используйте VBO vertexattribpointer и drawarrays/elements.
Не забудьте связать шейдер перед отправкой униформы.
Так с полным пример:
glm::mat4x4 view_matrix = glm::lookAt(2,4,2,-1,-1,-1,0,1,0);
glm::mat4x4 projection_matrix =
glm::perspective(60.0f, float(screenWidth)/float(screenHeight), 1.0f, 10.0f);
glm::mat4x4 model_matrix= glm::mat4(1); //this remains unchanged
glm::mat4x4 teapot_model_matrix= glm::rotate(model_matrix, //this is the teapots model matrix, apply transformations to this
45,
glm::vec3(1,1,1));
teapot_model_matrix = glm::scale(teapot_model_matrix,vec3(2,2,2);
gShader->bindShader();
gShader->sendUniform4x4("model_matrix",glm::value_ptr(model_matrix));
gShader->sendUniform4x4("view_matrix",glm::value_ptr(view_matrix));
gShader->sendUniform4x4("projection_matrix",glm::value_ptr(projection_matrix));
glutSolidCube(0.0); //i don't know what the (0.0) stands for :/
glutSwapBuffers();
///////////////////////////////// //
в вашем шейдере:
uniform mat4 projection_matrix; //these are the matrixes you've sent
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(){
gl_Position = projection_matrix*view_matrix*model_matrix*vec4(gl_Vertex.xyz,1);
}
Теперь вы должны иметь камеру, расположенную на 2,4,2, сосредоточившись на -1, -1, -1, а вверх вектор направлен вверх:)
Чайник повернут на 4 5 градусов вокруг (1,1,1) вектора и масштабируется на 2 в каждом направлении.
После изменения матрицы модели отправьте ее в шейдер, так что, если у вас есть больше объектов для рендеринга , отправьте их после каждого, если вы хотите иметь различные преобразования, применяемые к каждой сетке. псевдокод это выглядит следующим образом:
camera.lookat(camerapostion,focuspoint,updirection); //sets the view
camera.project(fov,aspect ratio,near plane, far plane) //and projection matrix
camera.sendviewmatrixtoshader;
camera.sendprojectionmatrixtoshader;
obj1.rotate(45 degrees, 1,1,1); //these functions should transform the model matrix of the object. Make sure each one has its own.
obj1.sendmodelmatrixtoshader;
obj2.scale(2,1,1);
obj2.sendmodelmatrixtoshader;
Если это не работает, попробуйте его с VertexBuffer и простой треугольник или куб, созданный самостоятельно.
Благодарим за подробное описание. Я добавил немного кода для лучшего понимания моей проблемы. Я отправляю данные в шейдер правильно? –
Проблема с вашим кодом заключается в том, что вы смешиваете функции ffp (устаревшие) с вашими собственными, что не является хорошей практикой. Я отправляю еще один ответ. –
Ну, мне удалось просто умножить матрицу трансформации объекта на матрицу сцены и glLoadMatrixf(). Спасибо за интерес. –