我的目标是通过按箭头键移动对象。为此,我在回调中创建了一些偏移量的转换矩阵并将其乘以世界矩阵。但是它不起作用-按下键不能移动立方体。我还注意到直接使用带有设置偏移量的glTranslate()效果很好,但看起来像拐杖。我的意思是,任何模型转换都应仅使用转换矩阵。 我的代码中的问题出在哪里?如何解决?为什么glTranslate()可以正常工作? 最小的代码示例:
glm::mat4 mWorldMatrix;
glm::mat4 mViewMatrix;
glm::mat4 mProjMatrix;
void onKeyCallback(GLFWwindow*, int key, int scan, int action, int mods)
{
switch (key)
{
case GLFW_KEY_UP:
{
auto translationMatrix = glm::translate(glm::mat4{}, glm::vec3{ 0, 1, 0 });
mWorldMatrix = mWorldMatrix * translationMatrix;
break;
}
case GLFW_KEY_DOWN:
{
auto translationMatrix = glm::translate(glm::mat4{}, glm::vec3{ 0, -1, 0 });
mWorldMatrix = mWorldMatrix * translationMatrix;
break;
}
case GLFW_KEY_LEFT:
{
auto translationMatrix = glm::translate(glm::mat4{}, glm::vec3{ -1, 0, 0 });
mWorldMatrix = mWorldMatrix * translationMatrix;
break;
}
case GLFW_KEY_RIGHT:
{
auto translationMatrix = glm::translate(glm::mat4{}, glm::vec3{ 1, 0, 0 });
mWorldMatrix = mWorldMatrix * translationMatrix;
break;
}
}
}
int main()
{
glfwInit();
const int weight = 640;
const int height = 480;
auto mWindow = glfwCreateWindow(weight, height, "TesT", nullptr, nullptr);
glfwMakeContextCurrent(mWindow);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
mWorldMatrix = glm::mat4{ 1.0f };
mViewMatrix = glm::lookAt(glm::vec3{ 0, 0, -1 },
glm::vec3{ 0, 0, 0 },
glm::vec3{ 0, 1, 0 });
mProjMatrix = glm::perspective(glm::radians(45.0f),
static_cast<float>(weight) / height,
0.1f,
100.0f);
glfwSetKeyCallback(mWindow, onKeyCallback);
while (!glfwWindowShouldClose(mWindow)) {
glClearColor(0.5, 0.5, 0.5, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0, weight, height);
auto modelViewMatrix = mViewMatrix * mWorldMatrix;
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(static_cast<const float*>(glm::value_ptr(modelViewMatrix)));
glMatrixMode(GL_PROJECTION_MATRIX);
glLoadMatrixf(static_cast<const float*>(glm::value_ptr(mProjMatrix)));
Cube cube{ glm::vec3{0.5, 0.5, 0.5}, 1 }; //cube with center in {0.5} and side length 1
auto vertices = cube.soup(); //vector of vertex
glTranslatef(0 /* + offset.x*/, 0/* + offset.y*/, -5); //Setting offset here is work good
glBegin(GL_TRIANGLES);
for (const auto& vertex : vertices)
{
glColor3f(vertex.position.x, vertex.position.y, vertex.position.z);
glVertex3f(vertex.position.x, vertex.position.y, vertex.position.z);
}
glEnd();
glfwSwapBuffers(mWindow);
glfwWaitEvents();
}
glfwTerminate();
return 0;
}
答案 0 :(得分:1)
请注意,由glBegin
/glEnd
序列绘制的图以及固定函数矩阵堆栈和固定函数。请参见Fixed Function Pipeline和Legacy OpenGL。
了解有关Vertex Specification和Shader的最新渲染方式。
应该将投影矩阵应用于投影矩阵堆栈,并将模型视图矩阵应用于模型视图矩阵堆栈。
有2个问题。
GL_PROJECTION_MATRIX
不是glMatrixMode
的有效枚举常量,并且会导致GL_INVALID_ENUM
错误。投影矩阵模式的有效枚举常量为GL_PROJECTION
。 GL_PROJECTION_MATRIX
将被glGetFloatv
用来读取当前的投影矩阵。
如果要对模型应用其他变换,则必须先选择GL_MODELVIEW
矩阵。如果GL_PROJECTION
矩阵被“选中”,则此状态将一直保留,直到再次明确更改为止。
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(static_cast<const float*>(glm::value_ptr(modelViewMatrix)));
glMatrixMode(GL_PROJECTION); // <----- `GL_PROJECTION` instead of `GL_PROJECTION_MATRIX`
glLoadMatrixf(static_cast<const float*>(glm::value_ptr(mProjMatrix)));
// [...]
glMatrixMode(GL_MODELVIEW); // <-------- specify `GL_MODELVIEW`
glTranslatef(0 /* + offset.x*/, 0/* + offset.y*/, -5); //Setting offset here is work good
答案 1 :(得分:0)
因为在每个循环中,您都将多维数据集设置为原始位置。您应该在循环之外定义这些对象。然后,您可以在while循环中对其进行变异。
在大学的openGL课程中,我非常喜欢“ The Cherno”的youtube系列。他做了openGL course。