openGL实现可以动的木头人

这篇博客记录了作者初次接触计算机图形学,通过OpenGL完成第二个project的经历。主要内容包括理解OpenGL作为图形处理库的功能,学习并应用纹理映射和光照等技术,以及分享了用于学习的OpenGL教程资源。最终,作者展示了如何在OpenGL中创建一个能转动的3D木偶模型。
摘要由CSDN通过智能技术生成

     这是我们计算机图形学的第二个project,刚刚接触计算机图形学,openGL什么都不懂,废了很长时间才如期交了项目。下面就将整个过程记录下来。

     openGL是基于C语言的,我个人认为,它就是一个处理和玩耍图形的函数库。这些函数都是大牛们研究发明出来的,老师给我们讲texture讲了四节课,你使用的话只要几行代码就完成了。如果让我们写个texture映射的函数,或者写个光照函数,那就呵呵了。在此推荐一个openGL很火很有用的教程:

http://users.polytech.unice.fr/~buffa/cours/synthese_image/DOCS/Tutoriaux/Nehe/opengl.htm

这是英文的,不要怕,这只是用来装逼的,有人进行了原版翻译,就在下面:

http://www.yakergong.net/nehe/

熟悉熟悉openGL就开始干了,摸索摸索。

先看main()方法:

int main(int argc, char **argv) 
{  
  
  glutInit(&argc, argv);  
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);  
  /* get a 640 x 480 window */
  glutInitWindowSize(640, 480);  
  /* the window starts at the upper left corner of the screen */
  glutInitWindowPosition(0, 0);  
  /* Open a window */  
  window = glutCreateWindow("STICK PERSON");  
  /* Register the function to do all our OpenGL drawing. */
  glutDisplayFunc(&DrawGLScene);  
  /* Go fullscreen.  This is as soon as possible. */
  glutFullScreen();
  /* Even if there are no events, redraw our gl scene. */
  glutIdleFunc(&DrawGLScene);
  /* Register the function called when our window is resized. */
  glutReshapeFunc(&ReSizeGLScene);
  /* Register the function called when the keyboard is pressed. */
  glutKeyboardFunc(&keyPressed);
  /* Initialize our window. */
  InitGL(640, 480);  
  /* Start Event Processing Engine */  
  glutMainLoop();  
  return 1;
}
尽管每行都有注释,其实我一行也不懂。这些都是一个教程源码里的,main()方法大多是做了一些初始化。你的工作大部分都在DrawGLScense上,这个就是画的函数。我做这个实验的时候就是从一个教程上的源码改起,利用他的框架和初始化,我只在DrawGLScense()方法里活动。听上去比较猥琐,但是对于急着赶着交的同学还是比较实在的。下面介绍的就是DrawGLScense()方法:

void DrawGLScene()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
			
 
  glLoadIdentity();
  glTranslatef(0.0f,0.0f,-40.0f);
  glRotatef(angle,0,1,0);
  glPushMatrix();
  glTranslatef(0.0f,0.0f,-20.0f);
  glRotatef(-90,0,1,0);
  glPushMatrix();
  glTranslatef(0.0f,1.2f,0.0f);
  glPushMatrix();
  glTranslatef(0.8,0.0,0.0);
  glTranslatef(0.0,-0.4,0.0);
  glRotatef(angleoflarma,1,0,0);
  glPushMatrix();
  glTranslatef(0.0,-0.8,0.0);
  glTranslatef(0.0,-0.4,0.0);
  glRotatef(-90,1,0,0);
  DrawArmA();
  glPopMatrix();
  DrawArmB();
  glPopMatrix();
  
  glPushMatrix();
  glTranslatef(-0.8,0.0,0.0);
  glTranslatef(0.0,-0.4,0.0);
  glRotatef(angleofrarma,1,0,0);
  glPushMatrix();
  glTranslatef(0.0,-0.8,0.0);
  glTranslatef(0.0,-0.4,0.0);
  glRotatef(-90,1,0,0);
  DrawArmA();
  glPopMatrix();
  DrawArmB();
  glPopMatrix();
  //return shoulder
  glPushMatrix();
  glTranslatef(0.0,0.3,0.0);
  glPushMatrix();
  glTranslatef(0.0,0.7,0.0);
  DrawHead();
  glPopMatrix();
  DrawNick();
  glPopMatrix();
  DrawShoulder();
  glPopMatrix();
  //return body
  glPushMatrix();
  glTranslatef(0.0f,-1.2f,0.0f);
  glPushMatrix();
  glTranslatef(0.4,0.0,0.0);
  glTranslatef(0.0,-0.4,0.0);
  glRotatef(angleoflleg,1,0,0);
  DrawLeg();
  glPopMatrix();
  glPushMatrix();
  glTranslatef(-0.4,0.0,0.0);
  glTranslatef(0.0,-0.4,0.0);
  glRotatef(angleofrleg,1,0,0);
  DrawLeg();
  glPopMatrix();
  DrawWaise();
  glPopMatrix();
  DrawBody();
  glPopMatrix();
  glPopMatrix();
  angleoflarma += a;
  angleofrarma -= a;
  angleoflleg -= b;
  angleofrleg += b;
  angle += 0.1;
  
  if(angleoflarma > 50){
  		a = -1.0;
  		b = -0.5;
  	}
  if(angleoflarma < -50){
  		a = 1.0;
  		b = 0.5;
  	}			
  glutSwapBuffers();
}

/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y) 
{
    /* avoid thrashing this procedure */
    usleep(100);
    /* If escape is pressed, kill everything. */
    if (key == ESCAPE) 
    { 
	/* shut down our window */
	glutDestroyWindow(window); 	
	/* exit the program...normal termination. */
	exit(0);                   
    }
}
这是有点长,让我理一理,因为我们要画成一个木头人,必然有胳膊有腿,而且是三维的。代码中drawBody(),drawArm()等方法就是画长方体的。现在该说一下画的流程了。在此之前还应该说一下glPopMatrix()和glPushMatrix(),因为人是有关节的。小胳膊活动的时候必须以大胳膊的下面为中心,而大胳膊又得以肩膀为中心。这听上去很复杂,当大胳膊动了,小胳膊咋办?这时就得靠层次来解决了。pop和push就是来体现层次的。

我们先调整一下当前的原点,

glLoadIdentity();

将原点置于屏幕中央。为了便于小人转圈活动,

  glTranslatef(0.0f,0.0f,-40.0f);
  glRotatef(angl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值