如何在 openGL 中使用 glTranslatef、glScalef、glRotatef
how to use glTranslatef,glScalef,glRotatef in openGL
我只想要这样的视频:https://youtu.be/dGWtdYlryQQ
它显示了如何在 OpenGL 中使用 glTranslate
、glRotate
、gluOrtho2d
,但它没有指导我任何事情
在我的例子中,我画了一个菱形而不是三角形,这是我的条件
条件:
- 当我在键盘上按 r 或 R 时,菱形会顺时针旋转
- 当我在键盘上按 t 或 T 时,菱形会移动到右侧
- 当我在键盘上按 + 时,菱形会变大
这是我的代码:
#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
glRotate 围绕原点 (0,0) 旋转。给定您的投影矩阵(您使用 glOrtho 设置)原点最初位于屏幕的左下角,除非您使用 glTranslate。您的钻石不是以原点为中心,而是稍微远离原点。您需要做的是更改 void hut(void) 方法中的顶点值,使菱形以 0,0 为中心。然后使用 glTranslate 将渲染原点(以及菱形)移动到您想要的位置,然后使用 glRotate。
矩阵栈上的操作是相互依存的。每次操作的参考系都是当前的变换。
参见 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
结果:
glTranslatef
后跟 glRotatef
结果:
因为你的对象被置换了,你必须以这种方式翻译它,旋转点被放置在原点:
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 you have to "push" this operations in the reverse order. Further you should use the GL_MODELVIEW
matrix stack. (See 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);
.....
此外,您的对象会被视图的纵横比破坏。这可以通过在设置投影矩阵时注意纵横比来解决:
float w = 640.0f;
float h = 480.0f;
glOrtho(0.0,w/h,0.0,1.0,-1.0,1.0);
我只想要这样的视频:https://youtu.be/dGWtdYlryQQ
它显示了如何在 OpenGL 中使用 glTranslate
、glRotate
、gluOrtho2d
,但它没有指导我任何事情
在我的例子中,我画了一个菱形而不是三角形,这是我的条件
条件:
- 当我在键盘上按 r 或 R 时,菱形会顺时针旋转
- 当我在键盘上按 t 或 T 时,菱形会移动到右侧
- 当我在键盘上按 + 时,菱形会变大
这是我的代码:
#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
glRotate 围绕原点 (0,0) 旋转。给定您的投影矩阵(您使用 glOrtho 设置)原点最初位于屏幕的左下角,除非您使用 glTranslate。您的钻石不是以原点为中心,而是稍微远离原点。您需要做的是更改 void hut(void) 方法中的顶点值,使菱形以 0,0 为中心。然后使用 glTranslate 将渲染原点(以及菱形)移动到您想要的位置,然后使用 glRotate。
矩阵栈上的操作是相互依存的。每次操作的参考系都是当前的变换。
参见 glTranslate
的文档:
glTranslate
produces a translation byx y z
. The current matrix (seeglMatrixMode
) is multiplied by this translation matrix, with the product replacing the current matrix, [...]
并查看 glRotate
的文档:
glRotate
produces a rotation of angle degrees around the vectorx y z
. The current matrix (seeglMatrixMode
) is multiplied by a rotation matrix with the product replacing the current matrix.
这意味着glRotate
围绕当前本地系统的原点旋转。
虽然 glRotatetf
后跟 glTranslatef
结果:
glTranslatef
后跟 glRotatef
结果:
因为你的对象被置换了,你必须以这种方式翻译它,旋转点被放置在原点:
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 you have to "push" this operations in the reverse order. Further you should use the GL_MODELVIEW
matrix stack. (See 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);
.....
此外,您的对象会被视图的纵横比破坏。这可以通过在设置投影矩阵时注意纵横比来解决:
float w = 640.0f;
float h = 480.0f;
glOrtho(0.0,w/h,0.0,1.0,-1.0,1.0);