opengl各种变换应用

计算机图形学opengl3D
vczhfans GEEK之路 6月5日

环境:VS2010

编程语言:C语言

调用API:glut库


原文地址:https://mp.weixin.qq.com/s/duQEXHu4v_z2xxP64BSUCw
作者:vczhfans

实现功能:

三维坐标建立;

opengl文本显示鼠标当前位置;

点画线,这个没有自己用算法实现,用的opengl中GL_LINES加两顶点画

线画面

面画体

键盘控制自己画的体,wasd前后左右    space上  c下

简单动画,画的魔方自己通过定时器旋转,angle增

效果: 3D .gif
在这里插入图片描述

1.点画线
weixin

2.线画面

wei

3.面画体
wei

4.坐标文本显示

调用的别人写好的opengl显示文本

然后我与要做的就是,鼠标事件,获取鼠标坐标,记录,移动操作点,送进字符串char*,显示就OK了

opengl3D用户交互

    glutKeyboardFunc(keyboard);    //响应键盘

glutMouseFunc(myMouse);        //响应鼠标

glutTimerFunc(1000,timerFunc,1);    //定时器 

                                                            (sleep,*Func,ID)

主程序:

思路雷同2D吧,无非2D坐标变3D坐标

收获:int转char,char送进char*

        对旋转平移有了更深的认识

        opengl旋转右手坐标系:

        glRotatef(angle,dx,dy,dz);

                            0.当前模型中心点为参考点

                            1.握住旋转向量

                            2.拇指指向向量正方向

                            3.其余手指指向即为旋转方向

                            4.angle必须为int

        opengl平移:

         glTranslatef(dx,dy,dz);

                            当前模型中心点为参考点

                            表示xyz分量各移动多少
//需要引入glut库
#include "stdafx.h"  // 最前面
#include "stdlib.h"
#include "conio.h"
#include "math.h"
#include "glut.h" // C函数原型, 其中包括 gl.h 和 glu.h, 200多个函数, 状态变量
#include <windows.h>

// ASCII字符总共只有0到127,一共128种字符
#define MAX_CHAR        128


//
// 3D图形变换基本柜架演示
//

// 全局变量
GLsizei ww = 500, hh = 500; // 放当前窗口宽和高(像素数), 有size表示是只取正值

int button_x = 0;
int button_y = 0;
int angle = 0;
float key_dx = 0.0f;
float key_dy = 0.0f;
float key_dz = 0.0f;
/



显示字用来调用

void drawString(const char* str) {
    static int isFirstCall = 1;
    static GLuint lists;

    if( isFirstCall ) { // 如果是第一次调用,执行初始化
                         // 为每一个ASCII字符产生一个显示列表
         isFirstCall = 0;

         // 申请MAX_CHAR个连续的显示列表编号
         lists = glGenLists(MAX_CHAR);

         // 把每个字符的绘制命令都装到对应的显示列表中
         wglUseFontBitmaps(wglGetCurrentDC(), 0, MAX_CHAR, lists);
     }
     // 调用每个字符对应的显示列表,绘制每个字符
    for(; *str!='\0'; ++str)
         glCallList(lists + *str);
}


//所有文本内容显示

void body_DrawString()
{
	glPushMatrix();
	glRasterPos3f(0.0f, 0.0f,0.0f);
	drawString("(0,0,0)");
	glRasterPos3f(2.14f, 0.0f, 0.0f);
	drawString("X");
	glRasterPos3f(0.0f, 2.14f,0.0f);
	drawString("Y");
	glRasterPos3f(0.0f, 0.0f,2.14f);
	drawString("Z");
	glPopMatrix();
}

void display_body_DrawString(float dx, float dy, float dz, char* d_body)
{
	glPushMatrix();
	glRasterPos3f(dx, dy, dz);
	drawString(d_body);
	glPopMatrix();
}


//
//用来画一个坐标轴的函数,z轴

void axis(float length)
{ 
    glPushMatrix();
    glBegin(GL_LINES);
    glVertex3d(0.0, 0.0, 0.0);
    glVertex3d(0.0, 0.0, length);
    glEnd();
    //将当前操作点移到指定位置
    glTranslated(0.0, 0.0, length - 0.2);
    glColor3f(1.0, 0.0, 0.0);
    glutWireCone(0.04, 0.3, 8, 8);
    glPopMatrix();
}


void x_y_z_lines(float length)
{
	//画Z轴
	glPushMatrix();
	glColor3f(1.0f, 0.0f, 0.0f);
	axis(length);
	glPopMatrix();

	//画Y轴
	glPushMatrix();
	glColor3f(0.0f, 1.0f, 0.0f);
    glRotated(-90.0, 1.0, 0.0, 0);//绕x轴正方向旋转-90度
    axis(length);
    glPopMatrix();

	//画X轴
    glPushMatrix();
	glColor3f(0.0f, 0.0f, 1.0f);
    glRotated(90.0, 0.0, 1.0, 0.0);//绕y轴方向旋转90
    axis(length);
	glPopMatrix();
}
//
//画单网格面,yoz
//后面需要旋转就行

void yoz_face_lines(float length)
{
	glPushMatrix();

	glBegin(GL_LINES);
	for(int i = 0;length>0;++i)
	{
    glVertex3d(0.0, length, 0.0);
    glVertex3d(0.0, length, 2.0);
	glVertex3d(0.0, 0.0, length);
    glVertex3d(0.0, 2.0, length);
	length -= 0.2;
	}
    glEnd();
	glPopMatrix();
}


///
//画所有网格面,yoz,xoz,xoy
//通过yoz单面旋转
/坐标轴网格//
/
void xoz_yoz_xoz_face_lines(void)
{	
	glPushMatrix();
	glColor3f(1.0f, 1.0f, 0.0f);
	yoz_face_lines(2);
	glPopMatrix();

	glPushMatrix();
	glColor3f(0.0f, 1.0f, 0.0f);
    glRotated(90.0, 0, 1.0, 0);//绕y轴正方向旋转90度
	yoz_face_lines(2);
	glPopMatrix();

	glPushMatrix();
	glColor3f(1.0f, 1.0f, 1.0f);
    glRotated(-90.0, 0.0, 0.0, 1.0);
	yoz_face_lines(2);
	glPopMatrix();
}

//z轴画线
void Draw_a_line(float length)
{
	glPushMatrix();
	glBegin(GL_LINES);
	glVertex3d(0.0f, 0.0f, 0.0f);
    glVertex3d(0.0f, 0.0f, length);
	glEnd();
	glPopMatrix();
}

//xoz平面画面
void Draw_a_face(float length)
{
	//oz下			1
	glPushMatrix();
	Draw_a_line(length);
	glPopMatrix();
	//oz下对面		2
	glPushMatrix();
	glTranslatef(length, 0.0f, 0.0f);
	Draw_a_line(length);
	glPopMatrix();
	//ox下			3
	glPushMatrix();
	glRotated(90.0, 0, 1.0, 0);
	Draw_a_line(length);
	glPopMatrix();
	//ox下对面		4
	glPushMatrix();
	glTranslatef(0.0f, 0.0f, length);
	glRotated(90.0, 0, 1.0, 0);
	Draw_a_line(length);
	glPopMatrix();
}

//xyz正半轴体
void six_face_body(float length)
{
	//xoz下	底部	1
	glPushMatrix();
	glColor3f(1.0f, 0.0f, 0.0f);
	Draw_a_face(length);
	glPopMatrix();
	
	//xoz上	顶部	2
	glPushMatrix();
	glColor3f(1.0f, 0.0f, 0.0f);
	glTranslatef( 0.0f, length, 0.0f );
	Draw_a_face(length);
	glPopMatrix();
	

	//yoz左	左侧	3
	glPushMatrix();
	glColor3f(0.0f, 1.0f, 0.0f);
	glRotated(90.0, 0.0f, 0.0f, 1.0f);
	Draw_a_face(length);
	glPopMatrix();

	//yoz右	右侧	4
	glPushMatrix();
	glColor3f(0.0f, 1.0f, 0.0f);
    glTranslatef( length, 0.0f, 0.0f );
	glRotated(90.0, 0.0f, 0.0f, 1.0f);
	Draw_a_face(length);
	glPopMatrix();

	//xoy后 后面	5
	glPushMatrix();
	glColor3f(0.0f, 0.0f, 1.0f);
    glRotated(-90.0, 1.0f, 0.0f, 0.0f);
	Draw_a_face(length);
	glPopMatrix();

	//xoy前	前面	6
	glPushMatrix();
	glColor3f(0.0f, 0.0f, 1.0f);
	glTranslatef( 0.0f, 0.0f, length );
    glRotated(-90.0, 1.0f, 0.0f, 0.0f);
	Draw_a_face(length);
	glPopMatrix();

	

	//正面
	glPushMatrix();
	glColor3f(1.0f, 0.3f, 1.0f);
	glTranslatef(0.0f , 0.0f, length );//向z轴正方向平移length
    glRotated(90.0, 0, 1.0, 0);//绕y轴正方向旋转90度
	Draw_a_face(length);
	glPopMatrix();

	

	
}

void move_six_face_body(float dx, float dy, float dz,float length)
{	
	glPushMatrix();
	glTranslatef( dx, dy, dz );
	six_face_body(length);
	glPopMatrix();
}

void x_y_move_six_face_body_2X2(float dx, float dy, float dz, float length )
{

	move_six_face_body( dx,  dy,  dz, length);
	move_six_face_body( dx+length,  dy,  dz, length);
	move_six_face_body( dx,  dy+length,  dz, length);
	move_six_face_body( dx+length,  dy+length,  dz, length);
}


void x_y_z_move_six_face_body_2X2(float dx, float dy, float dz, float length)
{
			x_y_move_six_face_body_2X2(dx, dy, dz, length);
			glPushMatrix();
			glTranslatef( 0.0f, 0.0f, length );
			x_y_move_six_face_body_2X2(dx, dy, dz, length);
			glPopMatrix();
}


void draw_button_site(int button_x, int button_y)
{

	char *button_siteX= "(0";
	char *button_siteY= ",0)";
	char Cbutton_x[20];
	char Cbutton_y[20];
	itoa(button_x,Cbutton_x,10); // itoa(int,char,要转换的进制数)
	itoa(button_y,Cbutton_y,10); // itoa(int,char,要转换的进制数)
	

	button_siteX = Cbutton_x;
	button_siteY = Cbutton_y;

	display_body_DrawString(1.0f, 2.0f, 2.0f,"button site now: ");
	display_body_DrawString(1.1f, 1.9f, 2.0f,button_siteX);
	display_body_DrawString(1.3f, 1.9f, 2.0f,button_siteY);
	glutPostRedisplay();
}


// 功能: 显示程序, 重画消息回调函数
void display()
{	
	glClearColor(0.0f,0.0,0.0f,1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	glPushMatrix();
	glTranslatef( -1.8, -1.8, -1.8 );      // T2, T = T X T2
	glScalef( 1.5, 1.5, 1.5 );          // T3, T = T X T3
	//glRotatef( -90, 0.0, 1.0,0.0  );     // T4, T = T X T4 
	glColor3f(1.0, 0.5, 0.5 );
	

	glColor3f(1.0,1.0,1.0);
	draw_button_site(button_x, button_y);
	


	glPushMatrix();
	glTranslatef( 2.0f, 0.0f, 2.0f ); 
	glRotatef( angle+30, 0.0f, 0.0,0.0f  );
	six_face_body(0.2);
	six_face_body(0.3);
	glPopMatrix();



	glPushMatrix();
	glTranslatef( key_dx, key_dy, key_dz ); 
	glTranslatef( 0.0f, 2.0f, 0.0f ); 
	glTranslatef( 2.0, 0.0, 0.0 ); 
	glRotatef( angle+30, 0.0f, 30.0f,0.0f  );
	six_face_body(0.5);
	six_face_body(0.7);
	glPopMatrix();

	glPushMatrix();
	glTranslatef( 2.0, 0.0, 0.0 ); 
	glRotatef( angle+30, 1.0f, 30.0f,0.0f  );
	glTranslatef( -2.0, 0.0, 0.0 ); 
	x_y_z_move_six_face_body_2X2(0.0f,0.0f,0.0f,0.3);
	glPopMatrix();
	
	//
	///site场景坐标

	
	x_y_z_lines(2.5);		//xyz坐标轴
	
	xoz_yoz_xoz_face_lines();		//坐标轴网格

	body_DrawString();			//文字内容

	glPopMatrix();

	glFlush();;//glutSwapBuffers();	// 立即把上面生成的图形, 即图形缓冲区中图像, 显示在屏幕上
}

// 功能: 窗口消息回调函数, 投影变换: 投影、截剪、窗口与视口变换
void reshape( GLsizei w, GLsizei h )
{
	glMatrixMode( GL_PROJECTION );   // 当前选投影变换矩阵, 分二种: 正交投影和透视投影   
    glLoadIdentity();                                // T11 = I, 置为单位矩阵
    glViewport( 0, 0, (GLsizei)ww, (GLsizei)hh );  // T12, 窗口->视口变换,  glViewport(x, y, width, height),
 	glFrustum( -1.0, 1.0, -1.0, 1.0, 1.5, 20.0 );    // T11 设置透视投影变换矩阵值, 

	glMatrixMode( GL_MODELVIEW );     // 当前选模型视图变换矩阵, 内部矩阵T: 4X4矩阵
    glLoadIdentity();                 // T = I 设为单位矩阵
	
	// 视图(View)变换矩阵, 世界坐标系上的点 变换到 观察坐标系的点
	gluLookAt( 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // T1, T = T X T1 
}

// 功能: 初始化
// 说明: 一般把与图形无关的投影变换放在这里
void init()
{
	// 清窗口(颜色缓冲区中位清0)
	glClear( GL_COLOR_BUFFER_BIT ); 
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
}




void myMouse(int button, int state, int x, int y){
	button_x = x;
	button_y = y;
    if (state == GLUT_DOWN){
		
		printf("坐标:%d,%d\n\n",button_x,button_y);
        if (button == GLUT_LEFT_BUTTON){
           
        }
        else if (button == GLUT_RIGHT_BUTTON){
            glFlush();
        }
    }
    return;
}

void keyboard (unsigned char key, int x, int y)
{
	switch (key){
	case 'Q':
		//glutPostRedisplay();
	break;
	case 'q':
		//glutPostRedisplay();
	break;
	case 'r':
		key_dx = 1.0f;
		key_dy = 1.0f;
		key_dz = 0.0f;
		glutPostRedisplay();
	break;
	case 32:
		key_dy +=0.1;
		glutPostRedisplay();
	break;
	case 'c':
		key_dy -=0.1;
		glutPostRedisplay();
	break;

	case 'w':
		key_dz -=0.1;
		glutPostRedisplay();
	break;

	case 'a':
		key_dx -=0.1;
		glutPostRedisplay();
	break;

	case 's':
		key_dz +=0.1;
		glutPostRedisplay();
	break;

	case 'd':
		key_dx +=0.1;
		glutPostRedisplay();
	break;
 
	case 27:
 
	exit(0);
 
	break;
 
	default:
 
	break;
	}
}

//定时器
void timerFunc(int nTimerID)
{
    switch(nTimerID)
    {
        case 1:
			angle=(angle+10)%360;
			printf("角度:%d\n",angle);
            glutPostRedisplay();
            glutTimerFunc(1000,timerFunc,1);
        break;
    }
}

// 功能: 程序入口
int main( int argc, char** argv )
{
	glutInit( &argc, argv );	         // 初始化模式并在屏幕左上角打开一个窗口
	glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );

	glutInitWindowSize( ww, hh );	     // 窗口大小和窗口左上角在屏幕上位置
	glutInitWindowPosition( 0, 0 );
	glutCreateWindow( "Add3D交互" );	 // 置窗口标题 
	init();	// 初始化

	///
	glutDisplayFunc( display );     // 注册重画消息回调函数
	glutReshapeFunc( reshape );	    // 注册窗口消息回调函数
	///
	glutKeyboardFunc(keyboard);
	glutMouseFunc(myMouse);
	glutTimerFunc(1000,timerFunc,1);
	glutMainLoop();	  // 无限循环, 完成消息检测与调用
	return 0;
}




                                                                        wanle

下一个:

    opengl3D灯光与材质设置与显示,纹理,等
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值