Opengl 旋转不起作用

Opengl rotation doesn't work

我尝试理解 opengl,但我有很多简单的问题...我尝试旋转我的对象,我正在这样做:

glBindVertexArray(VAOs[1]);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glUniform1i(glGetUniformLocation(theProgram.get_programID(), "Texture1"), 1);

glMatrixMode(GL_MODELVIEW_MATRIX);
glPushMatrix();
glRotatef(10.0f, 0.0f, 0.0f, -0.1f);
glDrawElements(GL_TRIANGLES, _countof(tableIndices2), GL_UNSIGNED_INT, 0);
glPopMatrix();

而我的对象仍然在同一个位置。 怎么了?

您的代码存在的问题是您将旧的固定函数调用(如 glPushMatrix())与较新的着色器调用(如 glUniform())混合在一起。像 glPushMatrix() 这样的函数假设你让 OpenGL 驱动程序对显卡有更多的控制权(换句话说,这些函数会为你处理一些较新的 OpenGL 并发症),这意味着使用较新的函数调用,比如 glUniform() 可以导致随机结果(因为您不知道是否干扰了 OpenGL 驱动程序的代码)。

基本上所有老的固定函数调用都可以在这里找到(这里其实是OpenGL ES,也就是opengl for embedded systems, or phones, or other than it is practically as opengl on the电脑):Fixed-Function Calls.

我建议您开始学习 OpenGL ES 2 函数,可在此处找到:OpenGL ES 2 (Shader Function Calls)

我认为这是一个学习 OpenGL ES 2 的好网站(即使您没有使用 OpenGL ES,该网站也很好地教授了这些概念)。本站也使用Java,所以忽略第一个教程中的所有缓冲区信息(不要与顶点和纹理缓冲区混淆,它们实际上是OpenGL,而不是Java细节):Learn OpenGL Concepts

首先

glMatrixMode(GL_MODELVIEW); // don't change to GL_MODELVIEW_MATRIX
glLoadIdentity(); // good habit to initialize matrix by identity.
glPushMatrix();

你的函数调用

glRotatef(10.0f, 0.0f, 0.0f, -0.1f);

应该与

相同
glRotatef(10.0f, 0.0f, 0.0f, -1f);

表示 z 轴十度。 根据 glRotatef(angle, x, y, z) 的文档-向量 (x, y, z) 被归一化为大小 1(如果大小不是 1)。

应该可以。 10度真的很重要吗?尝试做一些可移动的东西。

glRotatef(rotZ, 0.0f, 0.0f, -1f);
rotZ += 5;
if (rotZ > 360) rotZ -= 360;

glRotate 等函数是已弃用的 Fixed Function Pipeline 的一部分。此函数不影响由着色器程序处理的顶点。

参见Khronos wiki - Legacy OpenGL

In 2008, version 3.0 of the OpenGL specification was released. With this revision, the Fixed Function Pipeline as well as most of the related OpenGL functions and constants were declared deprecated. These deprecated elements and concepts are now commonly referred to as legacy OpenGL. ...

参见Khronos wiki - Fixed Function Pipeline

OpenGL 3.0 was the last revision of the specification which fully supported both fixed and programmable functionality. Even so, most hardware since the OpenGL 2.0 generation lacked the actual fixed-function hardware. Instead, fixed-function processes are emulated with shaders built by the system. ...


在现代 OpenGL 中,您必须自己完成这些工作。

如果您从 Fixed Function Pipeline 切换到今天的 OpenGL(在 C++ 中),那么我建议使用像 glm OpenGL Mathematics 这样的库来进行矩阵运算。

首先你必须创建一个具有统一矩阵的顶点着色器,你必须在顶点着色器中对顶点坐标和模型矩阵进行乘法运算:

in vec3 vert_pos;

uniform mat4 model_matrix;

void main()
{
    gl_Position = model * vec4(vert_pos.xyz, 1.0);
}

当然你可以声明更多的矩阵,比如投影矩阵和视图矩阵:

in vec3 vert_pos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(vert_pos.xyz, 1.0);
}

在 C++ 代码中你必须设置矩阵并且你必须设置矩阵统一:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> // glm::rotate
#include <glm/gtc/type_ptr.hpp>         // glm::value_ptr


glm::mat4 modelMat = glm::rotate(
    glm::mat4(1.0f),
    glm::radians(10.0f),
    glm::vec3(0.0f, 0.0f, -1.0f) );

GLint model_loc = glGetUniformLocation(theProgram.get_programID(), "model");

glUniformMatrix4fv(model_loc, 1, GL_FALSE, glm::value_ptr(modelMat)); 

另请参阅 glm matrix transformations 的文档。