`
xuela_net
  • 浏览: 495555 次
文章分类
社区版块
存档分类
最新评论

VS2012下基于Glut glRotatef glTranslatef示例程序:

 
阅读更多

Demo使用glRotatef ,glTranslatef来实现一个太阳、地球、月亮运动的3D图形。

1.glTranslatef() ——模型变换函数移动

voidglTranslatef(GLfloatx, GLfloaty, GLfloatz);

这个函数表示模型是怎样移动的。举个例子:

glTranslatef(-1.0,0.0,-2.0);//表示物体沿x负方向移动1.0,沿z轴负方向移动2.0。

2.glRotatef()——模型变换函数旋转

voidglRotatef(GLfloatangle, GLfloatx, GLfloaty, GLfloatz);

angle表示旋转的角度(注意单位不是弧度),(x,y,z)表示转轴。举个例子:

glRotatef(45.0, 0.0, 0.0, 1.0);//表示模型沿着(0,0,1)这个轴旋转45°。

3.glPerspective() ——投影变换函数透视投影

voidgluPerspective(GLdoublefovy, GLdoubleaspect, GLdoublezNear, GLdoublezFar);

glPerspective函数的相关参数代表的意义参看下图:

fovy视角宽度

aspect:w/h


平移、旋转、以及缩放效果:

正交投影以及透视投影:


正交投影下显示效果:


右击鼠标右键菜单选择是否显示坐标轴以及透视和正交投影模式:


透视投影:


源代码:

// GlutSolarDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <gl/glut.h>
#include <math.h>
//圆周率宏
#define GL_PI 3.1415f
//获取屏幕的宽度
GLint SCREEN_WIDTH=0;
GLint SCREEN_HEIGHT=0;
//设置程序的窗口大小
GLint windowWidth=400;
GLint windowHeight=300;
//绕x轴旋转角度
GLfloat xRotAngle=0.0f;
//绕y轴旋转角度
GLfloat yRotAngle=0.0f;
//受支持的点大小范围
GLfloat sizes[2];
//受支持的点大小增量
GLfloat step;
//最大的投影矩阵堆栈深度
GLint iMaxProjectionStackDepth;
//最大的模型视图矩阵堆栈深度
GLint iMaxModeviewStackDepth;
//最大的纹理矩阵堆栈深度
GLint iMaxTextureStackDepth;

GLfloat  whiteLight[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat  sourceLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat	 lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };

GLint iCoordinateaxis=2;
GLint iProjectionMode=1;
void changSize(GLint w,GLint h);
//菜单回调函数
void processMenu(int value){
	switch(value){
		case 1:
			iCoordinateaxis=1;
			break;
		case 2:
			iCoordinateaxis=2;
			break;
		case 3:
			iProjectionMode=1;
			//强制调用窗口大小变化回调函数,更改投影模式为正交投影
			changSize(glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
			break;
		case 4:
			iProjectionMode=2;
			//强制调用窗口大小变化回调函数,更改投影模式为透视投影
			changSize(glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
			break;
		default:
			break;
	}
	//重新绘制
	glutPostRedisplay();
}
//显示回调函数
void renderScreen(void){
	static float fMoonRot = 0.0f;
	static float fEarthRot = 0.0f;
	//将窗口颜色清理为黑色
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    //把整个窗口清理为当前清理颜色:黑色;清除深度缓冲区。
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    //将当前Matrix状态入栈
    glPushMatrix();
	if(2==iProjectionMode)
		glTranslatef(0.0f, 0.0f, -250.0f);	//透视投影为便于观察整个坐标系往内移动250个单位
    //坐标系绕x轴旋转xRotAngle
    glRotatef(xRotAngle,1.0f,0.0f,0.0f);
    //坐标系绕y轴旋转yRotAngle
    glRotatef(yRotAngle,0.0f,1.0f,0.0f);
	//进行平滑处理 
	glEnable(GL_POINT_SMOOTH);
	glHint(GL_POINT_SMOOTH,GL_NICEST);
	glEnable(GL_LINE_SMOOTH);
	glHint(GL_LINE_SMOOTH,GL_NICEST);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

	//白色绘制坐标系
	if(1==iCoordinateaxis){
		glColor3f(1.0f,1.0f,1.0f);
		glBegin(GL_LINES);
			glVertex3f(-90.0f,00.0f,0.0f);
			glVertex3f(90.0f,0.0f,0.0f);
			glVertex3f(0.0f,-90.0f,0.0f);
			glVertex3f(0.0f,90.0f,0.0f);
			glVertex3f(0.0f,0.0f,-90.0f);
			glVertex3f(0.0f,0.0f,90.0f);
		glEnd();

		glPushMatrix();
		glTranslatef(90.0f,0.0f,0.0f);
		glRotatef(90.0f,0.0f,1.0f,0.0f);
		glutSolidCone(3,6,10,10);
		glPopMatrix();

		glPushMatrix();
		glTranslatef(0.0f,90.0f,0.0f);
		glRotatef(-90.0f,1.0f,0.0f,0.0f);
		glutSolidCone(3,6,10,10);
		glPopMatrix();

		glPushMatrix();
		glTranslatef(0.0f,0.0f,90.0f);
		glRotatef(70.0f,0.0f,0.0f,1.0f);
		glutSolidCone(3,6,10,10);
		glPopMatrix();
	}

	glPushMatrix();

	glDisable(GL_LIGHTING);
	//Draw sun at(0.0f,0.0f,0.0f)
	glColor3ub(255, 255, 0);
	glutSolidSphere(15.0f, 30, 17);
	glEnable(GL_LIGHTING);

	//Move the light after we draw the sun!
	glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

	//Rotate coordinate system
	glColor3ub(0,0,255);
	glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);
	fEarthRot += 5.0f;
	if(fEarthRot > 360.0f)
		fEarthRot = 0.0f;
	glTranslatef(105.0f,0.0f,0.0f);
	//Draw the Earth
	glutSolidSphere(15.0f, 30, 17);

	//Rotate from Earth based coordinates and draw Moon
	glColor3ub(200,200,200);
	glRotatef(fMoonRot,0.0f, 1.0f, 0.0f);
	fMoonRot+= 15.0f;
	if(fMoonRot > 360.0f)
		fMoonRot = 0.0f;
	glTranslatef(30.0f, 0.0f, 0.0f);
	glutSolidSphere(6.0f, 30, 17);

	glPopMatrix();


    //恢复压入栈的Matrix
    glPopMatrix();
    //交换两个缓冲区的指针
    glutSwapBuffers();
}
//设置Redering State 
void setupRederingState(void){
	
	// Enable lighting
    glEnable(GL_LIGHTING);
    // Setup and enable light 0
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);
    // Enable color tracking
    glEnable(GL_COLOR_MATERIAL);
    // Set Material properties to follow glColor values
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	
    glEnable(GL_DEPTH_TEST);	//使能深度测试
    glFrontFace(GL_CCW);		//多边形正面为逆时针方向
    glEnable(GL_CULL_FACE);		//不显示背面

    //设置清理颜色为黑色
    glClearColor(0.0f,0.0,0.0,1.0f);
    //设置绘画颜色为绿色
    glColor3f(1.0f,1.0f,0.0f);
	//使能深度测试
	glEnable(GL_DEPTH_TEST);
	//获取受支持的点大小范围
	glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
	//获取受支持的点大小增量
	glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);
	//获取最大的投影矩阵堆栈深度
	glGetIntegerv( GL_MAX_PROJECTION_STACK_DEPTH,&iMaxProjectionStackDepth);
	//获取最大的模型视图矩阵堆栈深度
	glGetIntegerv( GL_MAX_MODELVIEW_STACK_DEPTH,&iMaxModeviewStackDepth);
	//获取最大的纹理矩阵堆栈深度
	glGetIntegerv( GL_MAX_TEXTURE_STACK_DEPTH,&iMaxTextureStackDepth);
	printf("point size range:%f-%f\n",sizes[0],sizes[1]);
	printf("point step:%f\n",step);
	printf("iMaxProjectionStackDepth=%d\n",iMaxProjectionStackDepth);
	printf("iMaxModeviewStackDepth=%d\n",iMaxModeviewStackDepth);
	printf("iMaxTextureStackDepth=%d\n",iMaxTextureStackDepth);
}
//窗口大小变化回调函数
void changSize(GLint w,GLint h){
    //横宽比率
    GLfloat ratio;
    //设置坐标系为x(-100.0f,100.0f)、y(-100.0f,100.0f)、z(-100.0f,100.0f)
    GLfloat coordinatesize=120.0f;
    //窗口宽高为零直接返回
    if((w==0)||(h==0))
        return;
    //设置视口和窗口大小一致
    glViewport(0,0,w,h);
    //对投影矩阵应用随后的矩阵操作
    glMatrixMode(GL_PROJECTION);
    //重置当前指定的矩阵为单位矩阵 
    glLoadIdentity();
    ratio=(GLfloat)w/(GLfloat)h;
    //正交投影
	if(1==iProjectionMode){
		printf("glOrtho\n");
		if(w<h)
			glOrtho(-coordinatesize,coordinatesize,-coordinatesize/ratio,coordinatesize/ratio,-coordinatesize*2.0f,coordinatesize*2.0f);
		else
			glOrtho(-coordinatesize*ratio,coordinatesize*ratio,-coordinatesize,coordinatesize,-coordinatesize*2.0f,coordinatesize*2.0f);
		//当前矩阵设置为模型视图矩阵
		glMatrixMode(GL_MODELVIEW);
		//重置当前指定的矩阵为单位矩阵 
		glLoadIdentity();
	}
	else{
		printf("gluPerspective\n");
		gluPerspective(45,ratio,10.0f,500.0f);
		//当前矩阵设置为模型视图矩阵
		glMatrixMode(GL_MODELVIEW);
		//重置当前指定的矩阵为单位矩阵 
		glLoadIdentity();
	}

}

//按键输入处理回调函数
void specialKey(int key,int x,int y){

    if(key==GLUT_KEY_UP){
        xRotAngle-=5.0f;
    }
    else if(key==GLUT_KEY_DOWN){
        xRotAngle+=5.0f;
    }
    else if(key==GLUT_KEY_LEFT){
        yRotAngle-=5.0f;
    }
    else if(key==GLUT_KEY_RIGHT){
        yRotAngle+=5.0f;
    }
    //重新绘制
    glutPostRedisplay();
}

void timerFunc(int value)
{
	glutPostRedisplay();
	glutTimerFunc(100, timerFunc, 1);
}

int main(int argc, char* argv[])
{
	//菜单
	GLint iMainMenu;
	GLint iCoordinateaxisMenu;
	GLint iOrthoOrPerspectMenu;
	//初始化glut 
    glutInit(&argc,argv);
    //使用双缓冲区、深度缓冲区。
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
    //获取系统的宽像素
    SCREEN_WIDTH=glutGet(GLUT_SCREEN_WIDTH);
    //获取系统的高像素
    SCREEN_HEIGHT=glutGet(GLUT_SCREEN_HEIGHT);
	//创建窗口,窗口名字为OpenGL Solar Demo
    glutCreateWindow("OpenGL Solar Demo");
    //设置窗口大小
    glutReshapeWindow(windowWidth,windowHeight);
    //窗口居中显示
    glutPositionWindow((SCREEN_WIDTH-windowWidth)/2,(SCREEN_HEIGHT-windowHeight)/2);
    //窗口大小变化时的处理函数
    glutReshapeFunc(changSize);
    //设置显示回调函数 
    glutDisplayFunc(renderScreen);
    //设置按键输入处理回调函数
    glutSpecialFunc(specialKey);
	//菜单回调函数
	iCoordinateaxisMenu=glutCreateMenu(processMenu);
	//添加菜单
	glutAddMenuEntry("Display coordinate axis",1);
	glutAddMenuEntry("Don't dispaly coordinate axis",2);
	iOrthoOrPerspectMenu=glutCreateMenu(processMenu);
	glutAddMenuEntry("Ortho",3);
	glutAddMenuEntry("Perspect",4);
	iMainMenu=glutCreateMenu(processMenu);
	glutAddSubMenu("Display or hide coordinate axis",iCoordinateaxisMenu);
	glutAddSubMenu("Ortho Or Perspect",iOrthoOrPerspectMenu);
	//将菜单榜定到鼠标右键上
	glutAttachMenu(GLUT_RIGHT_BUTTON);
	glutTimerFunc(250,timerFunc, 1);
    //设置全局渲染参数
    setupRederingState();
    glutMainLoop();
    return 0;
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics