OpenGL学习小例子

——基于旋转,拾取,缩放,着色的实现

要求:根据OpenGL提供的直线,多边形绘制算法(橡皮筋效果),实现基于鼠标交互的卡通人物和其他环境物体的设计与绘制。使用颜色填充与反走样技术对卡通人物外貌以及衣着进行绘制,其他物体的绘制。实现对卡通人物或物体轮廓的交互控制,点击鼠标左键可以对人物或者物体进行拖拽移动调整。按“↑”按键能够实现卡通人物绕坐标原点(或指定点)进行旋转,按“z”键可实现对选中的人物或者物体进行放缩。 附加要求:选中其中的一个多边形区域,点击鼠标右键,弹出一个菜单,可以对该区域进行不同颜色的选择。可以设计发型、衣服的模版,当作文件进行存储,可以在窗口最右边设计一个模板库,显示保存的发型与衣服,拖拽到卡通人物上可以为卡通人物进行发型或者衣服的替换。

过程解析:

1.绘制身体的各个部分:脸、耳朵、眉毛等的单独函数;而且有些部位是可以移动的,所以把坐标传入作为函数的参数

2.绘制函数 drawObjects(GLenum mode),参数是模式,选择模式或者是绘制模式。当模式是绘制时,选择对应部位的颜色,并且把部位绘制出来;当模式是选择时,把部位的标号加载到名字栈中。然后在着色,绘制各个部位

3.绘制的最终回调函数myDisplay,作为glutDisplayFunc的回调函数,即最终绘制时所调用的函数,在本函数里面,先清除颜色缓存,然后转化为单位阵,在将旋转中心转移到中心,否则就是围绕着左下角的坐标原点旋转,写好旋转的函数之后,只需要根据上下的按键来改变theta的值,再然后重绘一次旋转的图形,就做到按键控制图形的旋转,再在渲染模式下绘制图形drawObjects(GL_RENDER);

4.myinit方法是把背景颜色设定成黑色

5.myReshape是为了在改变窗口的时候而设定的,首先调用函数glViewport函数来定义视口,然后进行窗口的裁剪,之后再开启反走样,保证视图变化之后的效果较好

6.myReshape是为了在改变窗口的时候而设定的,首先调用函数glViewport函数来定义视口,然后进行窗口的裁剪,之后再开启反走样,保证视图变化之后的效果较好

7.processHits方法是配合名字栈来使用,名字栈内存储着五官的标号,buffer即为名字栈,name代表着五官的标号,里面有两个for循环,第一个循环,hits代表转移到缓冲区中已命中的记录数,即已命中的记录条数

8.myMouseMove,首先是根据鼠标指定的位置选中区域,然后利用脸的颜色重绘原器官的位置,之后再在鼠标停留的位置调glutPostRedisplay函数重新绘制一次全图,造成一种移动的感官

9.myMouse把selectBuf作为拾取缓冲区,每一条命中记录都会存在这个缓冲区中,开启选择模式,初始化名字栈,并且在透视投影的条件下对图元进行操作,把矩阵保存,在初始化一个新的矩阵,这样做为了避免对矩阵操作之后对以后的矩阵变化造成困难,gluPickMatrix函数根据鼠标坐标x,y并圈定一块区域来进行操作,选择该区域的图元,drawObjects(GL_SELECT)函数,在选择模式下调用,把名字压栈并且绘制一次

10.创建菜单,根据glutAddMenuEntry函数来给菜单添加条目,第二个参数value的作用是,当你选择一项时,该值就会返回给glutCreateMenu里调用的函数。而在函数main_menu里面,选择的颜色参数传进去,在根据拾取图元的标记,把相应的颜色赋值给五官的颜色变量,最后调用重绘函数glutPostRedisplay,从而达到改变颜色的目的

代码

#include "stdafx.h"

//隐藏控制台
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

//五官的标记
#define FACE 1  
#define EARS 2 
#define BROW 3
#define LEFT_EYE 4
#define RIGHT_EYE 5
#define NOSE 6
#define MOUTH 7
#define HAIR 8  
#define CROWN 9
#define CAP 10

//给个部位的颜色
static int FACE_COLOR = 7;
static int EARS_COLOR = 5;
static int BROW_COLOR = 0;
static int EYES_COLOR = 0;
static int NOSE_COLOR = 6;
static int MOUTH_COLOR = 1;
static int HAIR_COLOR = 3;
static int CROWN_COLOR = 6;
static int CAP_COLOR = 4;

static GLfloat theta = 0;//旋转的角度

static GLfloat scaleX = 1.0;
static GLfloat scaleY = 1.0;
static GLfloat scaleZ = 1.0;//缩放的尺寸

int select_part = 0; //点击时选中区域

static GLfloat colors[8][3] = {
    { 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 },
    { 0.0, 1.0, 1.0 }, { 1.0, 0.0, 1.0 }, { 1.0, 1.0, 0.0 }, { 1.0, 1.0, 1.0 } };
//黑色0  红色1  绿色2  蓝色3  青色4  紫色5  黄色6  白色7 
#define SIZE 512 
#define WIN_WIDTH 700  
#define WIN_HEIGHT 500  //裁剪窗口的大小
#define VIEW_WIDTH 700  
#define VIEW_HEIGHT 500  //视图窗口的大小,单位是像素

//画脸
void drawFace(){
    glBegin(GL_POLYGON);
    glVertex2f(150, 300);
    for (int i = 150; i <= 350; i = i + 1)
        glVertex2f(i, 0.008*(i - 250)*(i - 250) + 120);
    glVertex2f(350, 300);
    glEnd();
}
//画耳朵
void drawEars(){
    //right ear
    glBegin(GL_POLYGON);
    glVertex2f(150, 270);
    glVertex2f(140, 280);
    glVertex2f(
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值