c - 如何在 openGL 中使用 glTranslatef、glScalef、glRotatef

标签 c opengl coordinate-transformation

我只想要像这个视频这样的东西:https://youtu.be/dGWtdYlryQQ 它显示了如何在 OpenGL 中使用 glTranslateglRotategluOrtho2d,但它没有指导我任何事情

在我的例子中,我画了一个菱形而不是三角形,这是我的条件

条件:

  1. 当我在键盘上按 r 或 R 时,菱形会顺时针旋转
  2. 当我在键盘上按 t 或 T 时,菱形会移动到右侧
  3. 当我在键盘上按 + 时,菱形会变大

这是我的代码:

#include <stdlib.h>
#include <windows.h>
#include <GL/glut.h>
#include <iostream>
using namespace std;

float angle = 0;
float t,s=0.5,m=0;

void myinit(void){
    glClearColor(1.0,1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
}
void keyboard(unsigned char key, int x, int y){
        if(key==27)
        {
            exit(0);

        }else if(key == 82 || key == 114){
            angle-=0.1;

            glRotatef(angle,0,0,1);
            glutPostRedisplay();

        }else if(key == 84 || key == 116 )
        {
             t+=0.01;
             glTranslatef(t,0,0);
             glutPostRedisplay();
        }else if(key == 43){
                 s+=0.01;

               //  m-=0.1;
               //  glTranslatef(m,m,0.0);
                 glScalef(s,s,0);
                 glutPostRedisplay();
        }
        (void)(x);
        (void)(y);
}
void hut(void){

    glClear(GL_COLOR_BUFFER_BIT);

        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.5,0.4,0.0);
        glVertex3f(0.42,0.5,0.0);    // GREEN
        glVertex3f(0.44,0.5,0.0);
    glColor3f(1.5,1.0,0.0);
        glVertex3f(0.46,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.57,0.5,0.0);
        glEnd();
    glFlush();

    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.44,0.55,0.0);
        glVertex3f(0.42,0.5,0.0);
        glVertex3f(0.46,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.48,0.55,0.0);
        glEnd();

    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.48,0.55,0.0);
        glVertex3f(0.46,0.5,0.0);
        glVertex3f(0.50,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.52,0.55,0.0);
        glEnd();

    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.52,0.55,0.0);
        glVertex3f(0.50,0.5,0.0);
        glVertex3f(0.54,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.56,0.55,0.0);
        glEnd();
    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.56,0.55,0.0);
        glVertex3f(0.54,0.5,0.0);
        glVertex3f(0.57,0.5,0.0);
        glEnd();
    glFlush();

}
int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(640,480);
    glutCreateWindow("Polygon with viewport");
    myinit();
    glutDisplayFunc(hut);

    glutKeyboardFunc(keyboard);
    glutMainLoop();
}

这是我的输出:https://drive.google.com/file/d/14HHRiCbOHK9ZSZtDOqSl4GP4aSy7UQLh/view?usp=sharing 它与此不相似 https://youtu.be/dGWtdYlryQQ

最佳答案

矩阵栈上的操作是相互依存的。每个操作的引用系统是当前转换。

请参阅 glTranslate 的文档:

glTranslate produces a translation by x y z . The current matrix (see glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix, [...]

并查看 glRotate 的文档:

glRotate produces a rotation of angle degrees around the vector x y z . The current matrix (see glMatrixMode) is multiplied by a rotation matrix with the product replacing the current matrix.

这意味着 glRotate 围绕当前本地系统的原点进行旋转。

虽然 glRotatetf 后跟 glTranslatef 结果:

enter image description here

glTranslatef 后跟 glRotatef 结果:

enter image description here


因为你的对象被置换了,你必须以这种方式翻译它,旋转点被放置在原点:
glTranslatef(-0.5f, -0.5f, 0.0f);

然后你可以旋转它:

glRotatef(angle, 0.0f, 0.0f, 1.0f);

并将其移回:

glTranslatef(0.5f, 0.5f, 0.0f);

请注意,关于 Fixed Function Pipeline stack 你必须以相反的顺序“推”这个操作。此外,您应该使用 GL_MODELVIEW 矩阵堆栈。 (参见 glMatrixMode。)

从函数 keyboard 中删除所有矩阵运算,并将以下内容添加到函数 hut:

void hut(void)
{
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(t, 0.0f, 0.0f);
    glTranslatef(0.5f, 0.5f, 0.0f);
    glRotatef(angle, 0.0f, 0.0f, 1.0f);
    glScalef(s, s, 0.0f);
    glTranslatef(-0.5f, -0.5f, 0.0f);

    .....

此外,您的对象会被 View 的纵横比破坏。这可以通过在设置投影矩阵时注意纵横比来解决:
float w = 640.0f;
float h = 480.0f;
glOrtho(0.0,w/h,0.0,1.0,-1.0,1.0); 

关于c - 如何在 openGL 中使用 glTranslatef、glScalef、glRotatef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48236120/

相关文章:

c++ - 如何在程序本身中打印存储在 char[] 或字符串中的值

c - OpenGL 库的描述以及所有函数的作用

qt - Qt 5 中的 OpenGL 与 QOpenGL/QtOpenGL : differences and limitations?

java - 在 Android 中将 LatLng 偏移一定量的米

svg - 如何在 SVG 中设置变换原点

c - 在结构列表中搜索字符串

c - 格式化字符串上的 fprintf

java - 如何让对象环绕屏幕?

c - 在游戏中使用按钮逃脱延迟

c++ - 如何在 OpenGL 中使用 GLM?