计算机图形学 实验一:生成彩色立方体(含源代码)
- 格式:doc
- 大小:102.00 KB
- 文档页数:4
计算机图形学实验报告姓名:学号:班级:目录实验一OpenGL程序结构练习 (3)实验二基本图形生成 (6)实验三交互式控制 (9)实验四图形基本变换 (12)实验五三维图形生成及显示 (15)实验六三维图形生成及显示 (19)实验一OpenGL程序结构练习【实验目的】1.熟悉C语言环境下OpenGL的使用方法;2.了解OpenGL程序的基本结构。
【实验原理】绝大多数OpenGL程序具有类似的结构,包含下述函数main():定义回调函数,打开一个或多个具有指定属性的窗口,进入事件循环(最后一条可执行语句)init():设置状态变量、视图、属性、回调、显示函数、输入和窗口函数#include <GL/glut.h> // glut.h includes gl.h and glu.hvoid display(){ ……}void init(){ ……}int main( intargc, char **argv){ ……}【实验内容】1.了解程序中各个结构的功能;2.用OpenGL生成三角形。
【实验步骤及结果】1.导入OpenGL的glut32.lib和glut.h文件:将.lib文件存放到C 语言程序文件夹的Library下,.h文件放到Include下;导入应用程序扩展文件glut32.dll,存放到system文件夹下。
2.打开VC 6.0,新建工程,并命名为text1,如图1.图 13.在工程text1下新建源文件,并命名为text1.cpp。
4.编写代码并编译链接,如图2所示。
图 25.运行,结果如图3所示。
图 3实验二基本图形生成【实验目的】1.熟悉OpenGL的程序结构,并了解各部分的功能。
2.学会应用OpenGL语言绘制出点,线,多边形。
【实验原理】1.GLUT函数glutInit使得应用程序可以获取命令行参数并初始化系统。
glutInitDisplayMode设置窗口的属性、RGB颜色、单缓冲区、属性按照逻辑或组合在一起。
OpenGl绘制⼀个⽴⽅体OpenGl 绘制⼀个⽴⽅体 为了绘制六个正⽅形,我们为每个正⽅形指定四个顶点,最终我们需要指定6*4=24个顶点。
但是我们知道,⼀个⽴⽅体其实总共只有⼋个顶点,要指定24次,就意味着每个顶点其实重复使⽤了三次,这样可不是好的现象。
最起码,像上⾯这样重复烦琐的代码,是很容易出错的。
稍有不慎,即使相同的顶点也可能被指定成不同的顶点了。
如果我们定义⼀个数组,把⼋个顶点都放到数组⾥,然后每次指定顶点都使⽤指针,⽽不是使⽤直接的数据,这样就避免了在指定顶点时考虑⼤量的数据,于是减少了代码出错的可能性。
// 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯ ⽴⽅体的各个顶点的顺序如下图所⽰:1. 定义⽴⽅体的各个顶点数组 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯。
这样在指定顶点时,⽤指针,⽽不⽤直接⽤具体的数据。
1// 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯2static const GLfloat vertex_list[][3] = {3 -0.5f, -0.5f, -0.5f,40.5f, -0.5f, -0.5f,5 -0.5f, 0.5f, -0.5f,60.5f, 0.5f, -0.5f,7 -0.5f, -0.5f, 0.5f,80.5f, -0.5f, 0.5f,9 -0.5f, 0.5f, 0.5f,100.5f, 0.5f, 0.5f,11 }; 使⽤时可以直接采⽤指针绘制。
1 glBegin(GL_QUADS);2 glVertex3fv(vertex_list[0]);3 glVertex3fv(vertex_list[2]);4 glVertex3fv(vertex_list[3]);5 glVertex3fv(vertex_list[1]);67// ...8 glEnd(); 很容易就看出第0, 2, 3, 1这四个顶点构成⼀个正⽅形。
稍稍观察就可以发现,我们使⽤了⼤量的glVertex3fv函数,其实每⼀句都只有其中的顶点序号不⼀样,因此我们可以再定义⼀个序号数组,把所有的序号也放进去。
/**程序功能:cube4光立方彩色版本,实现各种动画效果,配套取模软件*作者:梦嵌工作室*版本:cube V1.0*备注:**/#include <stc12c5a60s2.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define MAX_Delay 8#define MIN_Delay 1sbit S_1 = P1 ^ 1;sbit S_2 = P1 ^ 2;unsigned int pwm;unsigned char TimeDelay = 10;unsigned char Mode = 1;unsigned char code tabP2[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //扫描uchar s=0;void DELAY_MS (uchar i){// unsigned int i;// while( --a != 0){// for(i = 0; i < 600; i++);// }uchar x,j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}void Adc_Delay (uint a){uint i;while( --a != 0){for(i = 0; i < 600; i++);}}void Delay(uint z){uint x,y;for(x=80;x>0;x--)for(y=z;y>0;y--);}void timer1_init(){TMOD |= 0x10;TH1 = 0;TL1 = 0;ET1 = 1;TR1 = 1;EA = 1;}/****************************************************************************** *********************** AD转换函数**************//****************************************************************************** /unsigned char Read (unsigned char CHA){unsigned char AD_FIN=0; //存储A/D转换标志CHA &= 0x07; //选择ADC的8个接口中的一个(0000 0111 清0高5位)ADC_CONTR = 0x00; //ADC转换的速度(0XX0 0000 其中XX控制速度,请根据数据手册设置)_nop_();ADC_CONTR |= CHA; //选择A/D当前通道_nop_();ADC_CONTR |= 0x80; //启动A/D电源Adc_Delay(1); //使输入电压达到稳定(1ms即可)ADC_CONTR |= 0x08; //启动A/D转换(0000 1000 令ADCS = 1)_nop_();_nop_();_nop_();_nop_();while (AD_FIN ==0){ //等待A/D转换结束AD_FIN = (ADC_CONTR & 0x10); //0001 0000测试A/D转换结束否}ADC_CONTR &= 0xE7; //1111 0111 清ADC_FLAG位, 关闭A/D转换,return (ADC_RES); //返回A/D转换结果(8位)}/******************************************************************************************** AD电容式触摸按键检测程序******************//****************************************************************************** ***************///bit 1表示有感应物,0表示没有感应物S1/****************************************************************************** ****************/bit S1(void){unsigned char R,mm=0,i,j,k;bit aa;j=0;k=0;for(i=0;i<10;i++){ //一次采集数据的数量Adc_Delay(3);R=Read(1); //读对应的口,触发对应的触摸按键if(R<0x2f){ //此参数可调整感应灵敏度值在0x01到0x2Fk++;}if(R == 0xFF){j++;}}if(k>1 && j>1){mm++;}else{mm=0;}if(mm>0){aa =1;}else{aa=0;}return(aa);}/****************************************************************************** ***************/// S2/****************************************************************************** ****************/bit S2(void){unsigned char R,mm=0,i,j,k;bit aa;j=0;k=0;for(i=0;i<10;i++){ //一次采集数据的数量Adc_Delay(3);R=Read(2);if(R<0x2F){ //此参数可调整感应灵敏度值在0x01到0x2Fk++;}if(R == 0xFF){j++;}}if(k>1 && j>1){mm++;}else{mm=0;}if(mm>0){aa =1;}else{aa=0;}return(aa);}//结束呼吸灯专用uchar code table[]={0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,1 32,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,};void PwmUp(uint a, uchar c){uchar i;if(c == 1)P3 = 0X00;elseP0 = 0X00;P2 = 0X00;i = table[a];Delay(i);if(c == 1)P3 = 0XFF;elseP0 = 0XFF;P2 = 0X00;Delay(150-i);}void PwmDown(uint a,uchar c){uchar i;if(c == 1)P3 = 0XFF;elseP0 = 0XFF;P2 = 0X00;i = table[a];Delay(i);if(c == 1)P3 = 0X00;elseP0 = 0X00;P2 = 0X00;Delay(150-i);}void PwmAllon(uchar c){int i;for(i = 0; i < 150 ;i++){PwmDown(i,c);}if(c == 1)P3 = 0X00;elseP0 = 0X00;P2 = 0X00;}void PwmOff(uchar c){int i;// P3 = 0XFF;// P2 = 0X00;// Delay(100);for(i = 0; i < 150; i++){PwmUp(i,c);}//P3 = 0X00;}void Allfalloff(uchar c,uchar time) //由全亮到下落关闭只剩一排{unsigned char code tabP0[5][8]={{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},{0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF},{0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<5;j++){for(k=0;k<15;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Randomlight(uchar c,uchar time) //随机亮完{unsigned char code tabP0[38][8]={{0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00},{0x00,0x20,0x00,0x00,0x00,0x00,0x10,0x00},{0x00,0x20,0x00,0x00,0x00,0x02,0x10,0x00}, {0x00,0x20,0x04,0x00,0x00,0x02,0x10,0x00}, {0x00,0xA0,0x04,0x00,0x00,0x02,0x10,0x00}, {0x00,0xA0,0x24,0x10,0x00,0x02,0x10,0x00}, {0x40,0xA0,0x24,0x10,0x00,0x02,0x10,0x00}, {0x40,0xA0,0x24,0x10,0x20,0x02,0x10,0x00}, {0x40,0xA0,0x24,0x10,0x20,0x22,0x10,0x00}, {0x40,0xA0,0x24,0x10,0x20,0x22,0x14,0x42}, {0x40,0xA0,0x24,0x10,0x20,0x26,0x14,0x42}, {0x40,0xA0,0x25,0x10,0x20,0x26,0x14,0x42}, {0x44,0xA0,0x25,0x10,0x20,0x26,0x14,0x42}, {0x44,0xA0,0x25,0x50,0x20,0x26,0x14,0x42}, {0x44,0xA0,0x25,0x50,0xA0,0x26,0x14,0x42}, {0x44,0xA0,0x25,0x50,0xA0,0x27,0x14,0x43}, {0x44,0xA0,0x25,0x50,0xA0,0x27,0x14,0x53}, {0x44,0xA0,0x65,0x50,0xA0,0x27,0x54,0x53}, {0x44,0xA0,0x65,0x50,0xA0,0xA7,0x54,0x53}, {0x44,0xA0,0x65,0x50,0xA8,0xA7,0x54,0x53}, {0x44,0xA0,0x65,0x50,0xA8,0xA7,0x56,0x5B}, {0x46,0xA0,0x67,0x52,0xA8,0xA7,0x56,0x5B}, {0x46,0xA1,0x67,0x52,0xA8,0xA7,0x56,0x5B}, {0x46,0xB1,0x67,0x52,0xA8,0xA7,0x56,0x5B}, {0x46,0xB1,0x67,0x5A,0xA8,0xA7,0x56,0x5B}, {0x56,0xB1,0x67,0x5A,0xA8,0xA7,0x56,0x5B}, {0x56,0xB1,0x67,0x5A,0xA8,0xE7,0x56,0x5B}, {0x56,0xB1,0x67,0x5A,0xAA,0xE7,0x56,0x5F}, {0x56,0xB1,0x67,0x5A,0xAA,0xE7,0x56,0x7F}, {0x56,0xF9,0x67,0x7A,0xAA,0xE7,0x56,0x7F}, {0x56,0xF9,0x67,0x7A,0xAE,0xE7,0x5E,0x7F}, {0x5E,0xFD,0x67,0x7B,0xAE,0xE7,0x5E,0x7F}, {0x5E,0xFD,0x67,0x7B,0xEE,0xE7,0xDE,0xFF}, {0xDE,0xFD,0xE7,0xFB,0xEF,0xE7,0xFF,0xFF}, {0xDE,0xFD,0xF7,0xFB,0xFF,0xF7,0xFF,0xFF}, {0xDE,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF} };int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<38;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];else{P3 = tabP0[j][i];P0=tabP0[j][i];}DELAY_MS(time);}}}}void Randomoff(uchar c,uchar time) //随机灭完{unsigned char code tabP0[23][8]={{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xDF},{0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xED,0xDF},{0xFF,0xF7,0xDD,0xFF,0xFF,0xFF,0xED,0xDF},{0xFF,0xF7,0xDD,0xEF,0xFF,0xDF,0xED,0xDF},{0xFF,0xF7,0x5D,0xAF,0xFD,0xDF,0xED,0xDF},{0xFF,0xF7,0x5C,0xAF,0xDD,0xDF,0xED,0xDF},{0xFF,0xE7,0x5C,0xAF,0xDD,0xDF,0x6D,0xDD},{0xFF,0xE7,0x5C,0x2F,0xDD,0xD7,0x6D,0x9D},{0xFF,0xE5,0x5C,0x2F,0xDD,0xD7,0x69,0x9D},{0xFF,0xA5,0x5C,0x2B,0xDD,0x57,0x69,0x9D},{0xFF,0xA5,0x5C,0x29,0xDD,0x57,0x69,0x8D},{0xBD,0x85,0x5C,0x29,0xDD,0x57,0x69,0x8D},{0xBD,0x85,0x54,0x29,0xDD,0x53,0x48,0x8D},{0x9D,0x85,0x54,0x29,0xDD,0x53,0x08,0x8D},{0x9D,0x81,0x54,0x09,0xDD,0x13,0x08,0x8D},{0x95,0x81,0x54,0x09,0xDD,0x12,0x08,0x85},{0x95,0x01,0x54,0x09,0xC9,0x12,0x08,0x85},{0x95,0x01,0x54,0x01,0x89,0x12,0x08,0x84},{0x95,0x01,0x40,0x01,0x89,0x02,0x08,0x80},{0x95,0x00,0x40,0x01,0x88,0x02,0x08,0x00},{0x94,0x00,0x00,0x00,0x88,0x00,0x08,0x00},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<23;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Righttoleft(uchar c,uchar time) //右面平移到左面{unsigned char code tabP0[4][8]={{0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F},{0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0},{0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00},{0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<4;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];else{P0=tabP0[j][i];P3 = tabP0[j][i];}DELAY_MS(time);}}}}void Lefttoright(uchar c,uchar time) //左面平移到右面{unsigned char code tabP0[4][8]={{0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00},{0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0},{0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<4;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void turnD(uchar c,uchar time) //从右面到下面{unsigned char code tabP0[6][8]={{0x00,0x00,0x00,0x00,0xF0,0x0F,0x0F,0x0F},{0xF0,0x00,0x00,0x00,0x00,0xF0,0x0F,0x0F},{0x0F,0xF0,0x00,0x00,0x00,0x00,0xF0,0x0F},{0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,0xFF},{0x00,0x00,0x0F,0xF0,0x00,0x00,0x00,0xFF},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<6;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Toptofollowing(uchar c,uchar time) //上面平移到下面{unsigned char code tabP0[4][8]={{0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},{0x00,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00},{0x00,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<4;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Followingtotop(uchar c,uchar time) //下面平移到上面{unsigned char code tabP0[4][8]={{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF},{0x00,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00},{0x00,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00},{0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<4;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Alllight(uchar c,uchar time) //右到左全亮{unsigned char code tabP0[4][8]={{0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F},{0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF},{0xF0,0xF0,0xF0,0xF0,0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<4;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Evel(uchar c,uchar time) // 斜面亮{unsigned char code tabP0[7][8]={{0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF7},{0x00,0x00,0x00,0xEC,0x00,0x00,0x00,0x73}, {0x00,0x00,0x00,0x4C,0x00,0x00,0x00,0x23}, {0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x21}, {0x00,0x00,0x48,0x48,0x00,0x00,0x21,0x21}, {0x00,0x48,0x48,0x48,0x00,0x21,0x21,0x21}, {0x48,0x48,0x48,0x48,0x21,0x21,0x21,0x21}, };int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<7;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Followtotop(uchar c,uchar time) //上面转移到后面可以接旋转{unsigned char code tabP0[10][8]={{0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},{0xEE,0x11,0x00,0x00,0xFF,0x00,0x00,0x00},{0xEC,0x12,0x01,0x00,0xFF,0x00,0x00,0x00},{0xC8,0x24,0x12,0x01,0xEF,0x10,0x00,0x00},{0x88,0x48,0x24,0x12,0xCE,0x21,0x10,0x00},{0x88,0x88,0x48,0x24,0x8C,0x42,0x21,0x10},{0x88,0x88,0x88,0x48,0x88,0x84,0x42,0x21},{0x88,0x88,0x88,0x88,0x88,0x88,0x84,0x42},{0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x84},{0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<15;j++){for(k=0;k<10;k++){{// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Spin(uchar c,uchar time) // 旋转{unsigned char code tabP0[8][8]={{0x48,0x48,0x48,0x48,0x21,0x21,0x21,0x21}, {0x44,0x44,0x44,0x44,0x22,0x22,0x22,0x22}, {0x22,0x22,0x22,0x22,0x44,0x44,0x44,0x44}, {0x21,0x21,0x21,0x21,0x48,0x48,0x48,0x48}, {0x31,0x31,0x31,0x31,0xC8,0xC8,0xC8,0xC8}, {0x30,0x30,0x30,0x30,0xC0,0xC0,0xC0,0xC0}, {0xC0,0xC0,0xC0,0xC0,0x30,0x30,0x30,0x30}, {0xC8,0xC8,0xC8,0xC8,0x31,0x31,0x31,0x31}, };int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<8;j++){for(k=0;k<8;k++){{// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Thenthelast(uchar c,uchar time) //接旋转下来到第一排{unsigned char code tabP0[3][8]={{0x00,0x48,0x48,0x48,0x00,0x21,0x21,0x21},{0x00,0x00,0x48,0x48,0x00,0x00,0x21,0x21},{0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x21}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<3;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Thelast(uchar c,uchar time) //接下来一排斜的后4点转到左上1 {unsigned char code tabP0[43][8]={{0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x21},{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x23},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8E},{0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x8C},{0x00,0x00,0x00,0x88,0x00,0x00,0x00,0x88},{0x00,0x00,0x00,0x8C,0x00,0x00,0x00,0x80},{0x00,0x00,0x00,0x8E,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x10},{0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x30},{0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x70},{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x70},{0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60},{0x00,0x00,0x00,0x60,0x00,0x00,0x20,0x40},{0x00,0x00,0x00,0x60,0x00,0x00,0x60,0x00},{0x00,0x00,0x40,0x20,0x00,0x00,0x60,0x00},{0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00},{0x00,0x00,0x60,0x00,0x00,0x20,0x40,0x00},{0x00,0x00,0x60,0x00,0x00,0x60,0x00,0x00},{0x00,0x40,0x20,0x00,0x00,0x60,0x00,0x00},{0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00},{0x00,0x60,0x00,0x00,0x20,0x40,0x00,0x00},{0x00,0x60,0x00,0x00,0x60,0x00,0x00,0x00},{0x40,0x20,0x00,0x00,0x60,0x00,0x00,0x00},{0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00},{0x70,0x00,0x00,0x00,0x40,0x00,0x00,0x00},{0x70,0x00,0x00,0x00,0x10,0x00,0x00,0x00},{0x30,0x00,0x00,0x00,0x11,0x00,0x00,0x00}, {0x10,0x00,0x00,0x00,0x13,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x8E,0x00,0x00,0x00}, {0x80,0x00,0x00,0x00,0x8C,0x00,0x00,0x00}, {0x88,0x00,0x00,0x00,0x88,0x00,0x00,0x00}, {0x8C,0x00,0x00,0x00,0x80,0x00,0x00,0x00}, {0x8E,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<43;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){// P0=0;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Twoidea(uchar c,uchar time) //左上1开始三个走最后底层亮完{unsigned char code tabP0[19][8]={{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00},{0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00},{0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00},{0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x8F,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0xCF,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0xEF,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x10},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x30},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x70},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xF0},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xF8},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFC},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFE},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<19;j++){for(k=0;k<8;k++){for(i=0;i<8;i++){P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Around2(uchar c,uchar time) //从左下第一点贪吃蛇样转到左上第一点{unsigned char code tabP0[27][8]={{0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x10},{0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x11},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E},{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0C},{0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x08},{0x00,0x00,0x88,0x00,0x00,0x00,0x80,0x00},{0x00,0x00,0x8C,0x00,0x00,0x00,0x00,0x00},{0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00},{0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00},{0x00,0x10,0x03,0x00,0x00,0x00,0x00,0x00},{0x00,0x10,0x01,0x00,0x00,0x10,0x00,0x00},{0x00,0x10,0x00,0x00,0x00,0x11,0x00,0x00},{0x00,0x00,0x00,0x00,0x00,0x13,0x00,0x00},{0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00},{0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00},{0x00,0x00,0x00,0x00,0x80,0x0C,0x00,0x00},{0x80,0x00,0x00,0x00,0x80,0x08,0x00,0x00},{0x88,0x00,0x00,0x00,0x80,0x00,0x00,0x00},{0x8C,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<3;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Spread(uchar c,uchar time) //从左上1扩散全部一次最后回到右上1 {unsigned char code tabP0[42][8]={{0x13,0x01,0x00,0x00,0x00,0x00,0x00,0x00},{0x37,0x33,0x01,0x00,0x10,0x00,0x00,0x00},{0x7F,0x37,0x13,0x01,0x31,0x10,0x00,0x00},{0xFF,0x7F,0x37,0x13,0x73,0x31,0x10,0x00},{0xFF,0xFF,0x7F,0x3F,0xFF,0x77,0x33,0x11},{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x77,0x33},{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFE,0xEC,0xFF,0xFF,0xFF,0xFF},{0xFF,0xFE,0xEC,0xC8,0xFF,0xFF,0xFF,0xEF}, {0xFE,0xEC,0xC8,0x80,0xFF,0xFF,0xEF,0xCE}, {0xEC,0xC8,0x80,0x00,0xFF,0xEF,0xCE,0x8C}, {0xC8,0x80,0x00,0x00,0xEF,0xCE,0x8C,0x08}, {0x80,0x00,0x00,0x00,0xCE,0x8C,0x08,0x00}, {0x00,0x00,0x00,0x00,0x8C,0x08,0x00,0x00}, {0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x8C,0x08,0x00,0x00}, {0x80,0x00,0x00,0x00,0xCE,0x8C,0x08,0x00}, {0xC8,0x80,0x00,0x00,0xEF,0xCE,0x8C,0x08}, {0xEC,0xC8,0x80,0x00,0xFF,0xEF,0xCE,0x8C}, {0xFE,0xEC,0xC8,0x80,0xFF,0xFF,0xEF,0xCE}, {0xFF,0xFE,0xEC,0xC8,0xFF,0xFF,0xFF,0xEF}, {0xFF,0xFF,0xFE,0xEC,0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xEC}, {0xFF,0xFF,0xFF,0xEF,0xFF,0xFE,0xEC,0xC8}, {0xFF,0xFF,0xEF,0xCE,0xFE,0xEC,0xC8,0x80}, {0xFF,0xEF,0xCE,0x8C,0xEC,0xC8,0x80,0x00}, {0xEF,0xCE,0x8C,0x08,0xC8,0x80,0x00,0x00}, {0xCE,0x8C,0x08,0x00,0x80,0x00,0x00,0x00}, {0x8C,0x08,0x00,0x00,0x00,0x00,0x00,0x00}, {0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<42;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){;P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Framework(uchar c,uchar time)//从右上第一点延伸框架{unsigned char code tabP0[8][8]={{0x00,0x00,0x00,0x00,0x13,0x01,0x00,0x00},{0x10,0x00,0x00,0x00,0x17,0x01,0x01,0x00},{0x11,0x00,0x00,0x00,0x1F,0x01,0x01,0x01},{0x13,0x01,0x00,0x00,0x9F,0x09,0x01,0x13},{0x97,0x01,0x01,0x10,0x9F,0x09,0x09,0x17},{0x9F,0x01,0x01,0x11,0x9F,0x09,0x09,0x9F},{0x9F,0x09,0x01,0x93,0x9F,0x09,0x09,0x9F},{0x9F,0x09,0x09,0x9F,0x9F,0x09,0x09,0x9F},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<8;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Nextkj1(uchar c,uchar time) //第一种接框架后4个小正方形转动最后全亮{unsigned char code tabP0[32][8]={{0x9F,0x09,0x09,0x9F,0x9F,0x09,0x09,0x9F},{0x06,0x99,0x99,0x06,0x06,0x99,0x99,0x06},{0x00,0x66,0x66,0x00,0x00,0x66,0x66,0x00},{0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00},{0x00,0xC0,0xC0,0x00,0x00,0xC0,0xC0,0x00},{0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0x00},{0x00,0x00,0x00,0x00,0xCC,0xCC,0x00,0x00},{0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x00},{0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00},{0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00},{0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33},{0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66},{0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC},{0x00,0x00,0xC0,0xC0,0x00,0x00,0xC0,0xC0},{0x00,0x00,0xCC,0xCC,0x00,0x00,0x00,0x00},{0x00,0xCC,0xCC,0x00,0x00,0x00,0x00,0x00},{0xCC,0xCC,0x00,0x00,0x00,0x00,0x00,0x00}, {0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00}, {0x33,0x33,0x00,0x00,0x00,0x00,0x00,0x00}, {0x33,0x33,0x33,0x00,0x00,0x00,0x00,0x00}, {0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00}, {0x33,0x33,0x77,0x77,0x00,0x00,0x00,0x00}, {0x33,0x33,0xFF,0xFF,0x00,0x00,0x00,0x00}, {0x33,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xCC,0xCC,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xEE,0xEE,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x33,0x00}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x33,0x33}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x77,0x77}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<32;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Nextkj2(uchar c,uchar time) //第二种接框架后最后上面一排亮{unsigned char code tabP0[10][8]={{0x9F,0x09,0x09,0x9F,0x9F,0x09,0x09,0x9F},{0xF0,0x90,0x90,0xF0,0x9F,0x09,0x09,0x9F},{0x00,0x00,0x00,0x00,0xFF,0x99,0x99,0xFF},{0x00,0x00,0x00,0x00,0x0F,0x09,0x09,0x0F},{0x00,0x00,0x00,0x00,0x0F,0x09,0x09,0x00},{0x00,0x00,0x00,0x00,0x0F,0x09,0x00,0x00},{0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00},{0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},{0xF0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},{0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;P0 = 0XFF;}for(j=0;j<10;j++){for(k=0;k<10;k++){for(i=0;i<8;i++){P2=tabP2[i];if(c == 1)P0=tabP0[j][i];else if(c == 2)P3 = tabP0[j][i];elseP0=tabP0[j][i];DELAY_MS(time);}}}}void Drip(uchar c,uchar time) //接上面全亮的,滴水,最后最下面的一排亮{unsigned char code tabP0[25][8]={{0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},{0xFE,0x01,0x00,0x00,0xFF,0x00,0x00,0x00},{0xFC,0x02,0x01,0x00,0xFF,0x00,0x00,0x00},{0xF8,0x04,0x02,0x01,0xFF,0x00,0x00,0x00},{0xF0,0x08,0x04,0x03,0xFF,0x00,0x00,0x00},{0xF0,0x00,0x08,0x07,0xFF,0x00,0x00,0x00},{0xF0,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00},{0xE0,0x10,0x00,0x0F,0xFF,0x00,0x00,0x00},{0xC0,0x20,0x10,0x0F,0xFF,0x00,0x00,0x00},{0x80,0x40,0x20,0x1F,0xFF,0x00,0x00,0x00},{0x00,0x80,0x40,0x3F,0xFF,0x00,0x00,0x00},{0x00,0x00,0x80,0x7F,0xFF,0x00,0x00,0x00},{0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00},{0x00,0x00,0x00,0xFF,0xEF,0x10,0x00,0x00},{0x00,0x00,0x00,0xFF,0xCF,0x20,0x10,0x00},{0x00,0x00,0x00,0xFF,0x8F,0x40,0x20,0x10},{0x00,0x00,0x00,0xFF,0x0F,0x80,0x40,0x30},{0x00,0x00,0x00,0xFF,0x0F,0x00,0x80,0x70},{0x00,0x00,0x00,0xFF,0x0F,0x00,0x00,0xF0},{0x00,0x00,0x00,0xFF,0x0E,0x01,0x00,0xF0},{0x00,0x00,0x00,0xFF,0x0C,0x02,0x01,0xF0},{0x00,0x00,0x00,0xFF,0x08,0x04,0x02,0xF1},{0x00,0x00,0x00,0xFF,0x00,0x08,0x04,0xF3},{0x00,0x00,0x00,0xFF,0x00,0x00,0x08,0xF7},{0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF},};int j,k,i;if(c==1)P3 = 0X00;else if(c==2)P0 = 0X00;else{P3 = 0XFF;。
计算机图形学作业实验报告计算机图形学实验报告班级:学号:姓名:指导教师:完成日期:实验一:多边形填充1、实验目的了解多边形属性,熟悉相关函数的调用。
二、实验内容步骤和实现:首先进行初始化工作,进行显示模式(单缓冲区)和窗口等设定,主要实现根据两个函数,一个是指定场景绘制函数,glutDisplayFunc(Paint),paint函数中设置了两个三角形,一个填充,一个不填充。
用到了启用多边形点画模式glEnable(GL_POLYGON_STIPPLE)的函数,和指定多边形点画模式(填充)glPolygonStipple(fly)的函数。
另外一个就是循环执行OpenGl命令的glutMainLoop()函数。
三、实验结果四、源程序//POLY_STIPPLE.C#includevoidmakeObject()//定义一个三角形{glBegin(GL_TRIANGLES);//开始定义三角形//按逆时针方向指定三角形的顶点坐标glVertex2f(-0.95,-0.95);glVertex2f(0.95,-0.95);glVertex2f(0,0.95);glEnd() ;//三角形定义结束}voiddisplay(){GLsizeiw=glutGet(GLUT_WINDOW_WIDTH);//程序窗口宽度GLsizeih=glutGet(GLUT_WINDOW_HEIGHT);//程序窗口高度GLubytefly[]=//第二个三角形点画模式的mask值{0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,//0X03,0X80,0X01,0X C0,0X06,0XC0,0X03,0X60,//0X04,0X60,0X06,0X20,0X04,0X30,0X0C,0X20,//0X04,0X18,0X18,0X20,0X04,0X0C,0X30,0X20,//0X04,0X06,0 X60,0X20,0X44,0X03,0XC0,0X22,//0X44,0X01,0X80,0X22,0X44,0X01 ,0X80,0X22,//0X44,0X01,0X80,0X22,0X44,0X01,0X80,0X22,//0X44,0 X01,0X80,0X22,0X44,0X01,0X80,0X22,//0X66,0X01,0X80,0X66,0X33 ,0X01,0X80,0XCC,//0X19,0X81,0X81,0X98,0X0C,0XC1,0X83,0X30,// 0X07,0XE1,0X87,0XE0,0X03,0X3F,0XFC,0XC0,//0X03,0X31,0X8C,0 XC0,0X03,0X33,0XCC,0XC0,//0X06,0X64,0X26,0X60,0X0C,0XCC,0X 33,0X30,//0X18,0XCC,0X33,0X18,0X10,0XC4,0X23,0X08,//0X10,0X6 3,0XC6,0X08,0X10,0X30,0X0C,0X08,//0X10,0X18,0X18,0X08,0X10,0 X00,0X00,0X08};glClear(GL_COLOR_BUFFER_BIT);//清除颜色缓冲区glViewport(0,0,w/2,h);//第一个视口,显示第一个三角形glColor3f(1,1,1);//设置颜色,白色,默认值makeObject();//第一个三角形glViewport(w/2,0,w/2,h);//第二个视口,显示第二个三角形glColor3f(1,0,0);//设置颜色,红色glEnable(GL_POLYGON_STIPPLE);//启用多边形点画模式glPolygonStipple(fly);//指定多边形点画模式(填充)makeObject();//第二个三角形glDisable(GL_POLYGON_STIPPLE);//关闭多边形点画模式glFlush();//强制OpenGL命令序列在有限的时间内完成执行}intmain(){glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA);//设置程序窗口的显示模式(单缓冲区、RGBA颜色模型)glutInitWindowPosition(100,100);//程序窗口的位置glutInitWindowSize(300,150);//程序窗口的大小glutCreateWindow(“一个填充多边形的例子!“);//窗口的标题glutDisplayFunc(display);//指定场景绘制函数glutMainLoop();//开始循环执行OpenGL命令}实验二:基本图元绘制2、实验目的了解OpenGL图形软件包绘制图形的基本过程及其程序框架,并在已有的程序框架中添加代码实现直线和圆的生成算法,演示直线和圆的生成过程,从而加深对直线和圆等基本图形生成算法的理解。
《计算机图形学》实验报告一、实验目的计算机图形学是一门研究如何利用计算机生成、处理和显示图形的学科。
通过本次实验,旨在深入理解计算机图形学的基本原理和算法,掌握图形的生成、变换、渲染等技术,并能够运用所学知识解决实际问题,提高对图形学的应用能力和编程实践能力。
二、实验环境本次实验使用的编程语言为 Python,使用的图形库为 Pygame。
开发环境为 PyCharm。
三、实验内容1、直线的生成算法DDA 算法(Digital Differential Analyzer)Bresenham 算法DDA 算法是通过计算直线的斜率来确定每个像素点的位置。
它的基本思想是根据直线的斜率和起始点的坐标,逐步计算出直线上的每个像素点的坐标。
Bresenham 算法则是一种基于误差的直线生成算法。
它通过比较误差值来决定下一个像素点的位置,从而减少了计算量,提高了效率。
在实验中,我们分别实现了这两种算法,并比较了它们的性能和效果。
2、圆的生成算法中点画圆算法中点画圆算法的核心思想是通过判断中点的位置来确定圆上的像素点。
通过不断迭代计算中点的位置,逐步生成整个圆。
在实现过程中,需要注意边界条件的处理和误差的计算。
3、图形的变换平移变换旋转变换缩放变换平移变换是将图形在平面上沿着指定的方向移动一定的距离。
旋转变换是围绕一个中心点将图形旋转一定的角度。
缩放变换则是改变图形的大小。
通过矩阵运算来实现这些变换,可以方便地对图形进行各种操作。
4、图形的填充种子填充算法扫描线填充算法种子填充算法是从指定的种子点开始,将相邻的具有相同颜色或属性的像素点填充为指定的颜色。
扫描线填充算法则是通过扫描图形的每一行,确定需要填充的区间,然后进行填充。
在实验中,我们对不同形状的图形进行了填充,并比较了两种算法的适用情况。
四、实验步骤1、直线生成算法的实现定义直线的起点和终点坐标。
根据所选的算法(DDA 或Bresenham)计算直线上的像素点坐标。
实验报告《计算机图形学》课题:三维图形的生成指导教师:***2013年5月三维图形的生成一.目的1.加深对计算机图形学的理解。
2.熟悉Visual C++ OpenGL的编程方法。
3.学习用编程方法绘制三维图形。
二.实验原理V oid CALLBACK display(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,1.0,1.0);glLoadIdentity();glTranslatef(0.0,0.0,-5.0);glScalef(1.0,2.0,1.0);auxWireCube(1.0);glFlush();} //画图void CALLBACK stepDisplay(void){r tri+=0.01;d isplay();}void CALLBACK myReshape(GLsizei w,GLsizei h){g lMatrixMode(GL_PROJECTION);g lLoadIdentity();g lFrustum(-1.0,1.0,-1.0,1.0,1.5,20.0);g lMatrixMode(GL_MODELVIEW);g lViewport(0,0,w,h);} //旋转三.实验步骤1.复习OpenGL语言。
2.编写图形生成程序,分析绘制结果。
四.实验内容#include<gl/glaux.h>#pragma comment(lib,"glaux.lib")#pragma comment(lib,"opengl32.lib")#pragma comment(lib,"glu32.lib")GLfloat rtri=0;1void myinit(void){glShadeModel(GL_SMOOTH);}void CALLBACK display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存glLoadIdentity(); // 重置模型观察矩阵glTranslatef(-1.5,0.0,-6.0); // 左移1.5 单位,并移入屏幕6.0 glRotatef(rtri,0.0,1.0,0.0); // 绕Y轴旋转正方体glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面glColor3f(1.0f,0.0f,0.0f); // 红色glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点(前侧面)glColor3f(0.0f,1.0f,0.0f); // 绿色glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的左下顶点(前侧面)glColor3f(0.0f,0.0f,1.0f); // 蓝色glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的右下顶点(前侧面)glColor3f(1.0f,0.0f,0.0f); // 红色glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点(右侧面)glColor3f(0.0f,0.0f,1.0f); // 蓝色glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的左下顶点(右侧面)glColor3f(0.0f,1.0f,0.0f); // 绿色glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的右下顶点(右侧面)glColor3f(1.0f,0.0f,0.0f); // 红色glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点(后侧面)glColor3f(0.0f,1.0f,0.0f); // 绿色glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的左下顶点(后侧面)glColor3f(0.0f,0.0f,1.0f); // 蓝色glVertex3f(-1.0f,-1.0f, -1.0f); // 三角形的右下顶点(后侧面)glColor3f(1.0f,0.0f,0.0f); // 红色glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点(左侧面)glColor3f(0.0f,0.0f,1.0f); // 蓝色glVertex3f(-1.0f,-1.0f,-1.0f); // 三角形的左下顶点(左侧面)glColor3f(0.0f,1.0f,0.0f); // 绿色glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的右下顶点(左侧面)glEnd();2glTranslatef(0.0f,0.0f,-7.0f); // 先右移再移入屏幕glRotatef(rtri,0.0f,1.0f,0.0f); // 在XYZ轴上旋转立方体glBegin(GL_QUADS); // 开始绘制立方体glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(顶面) glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(顶面) glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点(顶面) glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点(顶面)glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面) glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面) glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面) glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面) glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面) glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面) glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面) glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面) glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面) glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面) glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面) glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面) glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面) glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面) glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面) glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)glEnd(); // 立方体绘制结束3glFlush();}void CALLBACK stepDisplay(void){rtri+=0.01;display();}void CALLBACK myReshape(GLsizei w,GLsizei h) {glMatrixMode(GL_PROJECTION); glLoadIdentity();glFrustum(-1.0,1.0,-1.0,1.0,1.5,20.0); glMatrixMode(GL_MODELVIEW);glViewport(0,0,w,h);}int main(int argc,char** argv){auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,500,500);auxInitWindow("bianhuan");myinit();auxReshapeFunc(myReshape);auxIdleFunc(stepDisplay);auxMainLoop(display);}4五.实验结果:六.实验小结:通过这次实验,更深刻的学习了计算机图形学的编程语言,对于OpenGL的了解更一步。
. . . . .. . 优质资料 .. 计算机图形学 (2017年秋季学期)实验 报 告系别:计算机科学与技术 班级: : 学号:实验名称:2-真实感图形绘制2020-11-132/3《计算机图形学》实验报告实验名称真实感图形绘制 实验序号 2实验日期 2017.12.13 实验人 一、实验目的、要求与环境1.目的:通过实验,学生应掌握通过计算机程序进行真实感图形绘制的基本原理,特别是对三维显示对象进行纹理映射的基本方法,将理论和实际应用切实结合起来。
2.要求:对一个三维立方体进行旋转,对其6个不同的面进行6个不同图像的纹理映射,并进行投影变换与显示,分析增强后的视觉效果,提交实验报告。
3.环境:Windows 7操作系统Microsoft Visual Studio 2005OpenGL 函数库4. 自带位图文件(换成你自己的图像文件):总成绩:评语:日期:2020-11-1311/12二、实验容与步骤1. 准备相关图像文件。
2. 进行立方体各面图像与旋转速度的大体设计。
3.在Windows 7 操作系统上,打开Microsoft Visual Studio 2005,编写相关程序,完成程序主体框架结构。
4.编写六面体显示相关的程序代码。
5.编写六面体旋转相关的程序代码。
6.编写深度检测相关的程序代码。
7. 编写纹理载入功能的相关程序代码。
8. 编写纹理参数定义功能的相关程序代码。
9. 编写纹理映射功能的相关程序代码。
10.对程序进行相关调试,修改程序,去除其中的BUG 。
11. 观察纹理映射后的六面体的旋转显示,与预想的结果进行对比,修改相关程序参数。
12.截屏,保留实验结果,进行实验结果分析,并撰写实验报告。
2020-11-13 2/32020-11-13 11/12四、编译过程截图五、实验结果与分析(下面是一个例子,换上你自己的图)实验结果:实验分析程序通过glBindTexture(GL_TEXTURE_2D, lastTextureID);语句,完成了恢复之2020-11-13 2/32020-11-13 11/122020-11-13 2/32020-11-13 11/122020-11-13 2/3。
《计算机图形学》实验报告//圆pDC->SelectObject(&pen2);pDC->Ellipse(50,120,150,220);pDC->SelectObject(&pOldBrush);//椭圆pDC->SelectObject(&pen2);pDC->Ellipse(600, 100, 1025, 325);pDC->SelectObject(&pOldBrush);//多边形pDC->SelectObject(&pen2);pDC->SelectObject(&pen2);CPoint lpPoint[5];lpPoint[0] = CPoint(200,200);lpPoint[1] = CPoint(100, 300);lpPoint[2] = CPoint(150, 400);lpPoint[3] = CPoint(250, 400);lpPoint[4] = CPoint(300, 300);pDC->Polygon(lpPoint,5);//圆弧pDC->SelectObject(&pen2);pDC->SelectObject(&pen2);pDC->Arc(450,200,650,550,50,50,600,900);2、练习使用GDI函数显示图像glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(1000, 1000);glutInitWindowPosition(0, 0);glutCreateWindow("实验一");glutDisplayFunc(&display);glutMainLoop();}茶壶void display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor3f(0.0, 1.0, 0.0);//绿色绘制glEnable(GL_DEPTH_TEST);//深度缓冲区glutWireTeapot(2);//绘制茶壶glFlush();glutSwapBuffers();}void reshape(int w, int h){glViewport(0, 0, w, h); //设置视口glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影模式glLoadIdentity();gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 20); //创建透视投影矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0, 5, 5, 0, 0, 0, 0, 1, 0);//观测点}球void display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor3f(0.0, 1.0, 0.0);//绿色绘制glEnable(GL_DEPTH_TEST);//深度缓冲区glutWireSphere(1, 20, 16);//绘制球体glFlush();glutSwapBuffers();}void reshape(int w, int h){glViewport(0, 0, w, h); //设置视口glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影模式glLoadIdentity();gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 20); //创建透视投影矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0, 3, 3, 0, 0, 0, 1, 1, 0);//观测点}六面体void display(void)。
openGL+VS2010的例程--旋转变⾊⽴⽅体(三维)效果图如上。
步骤:⾸先,变换模型视⾓;然后,改变颜⾊;最后,利⽤顶点数组绘制⽴⽅体。
源代码如下:#include <GL/glut.h>// 绘制⽴⽅体// 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯static const float vertex_list[][3] ={-0.5f, -0.5f, -0.5f,0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,0.5f, 0.5f, -0.5f,-0.5f, -0.5f, 0.5f,0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,};// 将要使⽤的顶点的序号保存到⼀个数组⾥⾯static const GLint index_list[][2] ={{0, 1},{2, 3},{4, 5},{6, 7},{0, 2},{1, 3},{4, 6},{5, 7},{0, 4},{1, 5},{7, 3},{2, 6}};// 绘制⽴⽅体void DrawCube(void){int i,j;glBegin(GL_LINES);for(i=0; i<12; ++i) // 12 条线段{for(j=0; j<2; ++j) // 每条线段 2个顶点{glVertex3fv(vertex_list[index_list[i][j]]);}}glEnd();}static float rotate = 0;static int times = 0;void renderScene(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清理颜⾊缓冲和深度缓冲glMatrixMode(GL_MODELVIEW); // 对模型视景的操作glLoadIdentity(); // 重置当前指定的矩阵为单位矩阵glPushMatrix(); // 压栈//glTranslatef(-0.2, 0, 0); // 平移//glScalef(1, 1, 1); // 缩放times++;if(times > 100){times = 0;}if(times % 100 == 0) // [0, 100){rotate += 0.5; // [0, 20)}glRotatef(rotate, 0, 1, 0); // 旋转glRotatef(rotate, 1, 0, 0);// 动态颜⾊变换--红->绿->蓝->红if(rotate == 0)glColor3f(1, 0, 0);if(rotate ==90)glColor3f(0, 1, 0);if(rotate ==180)glColor3f(0, 0, 1);if(rotate ==270)glColor3f(1, 1, 0);if(rotate ==360)rotate = 0;DrawCube(); // 绘制⽴⽅体glPopMatrix();// 出栈glutSwapBuffers();}int main(int argc, char* argv[]){glutInit(&argc, argv); // 初始化GLUTglutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100, 100); // 显⽰窗⼝在屏幕的相对位置glutInitWindowSize(500, 500); // 设置显⽰窗⼝⼤⼩glutCreateWindow(argv[0]); // 创建窗⼝,附带标题glutDisplayFunc(renderScene); // 注册显⽰⽤的函数glutIdleFunc(renderScene); // 注册空闲⽤的函数glutMainLoop(); // GLUT 状态机return0;}。
Direct3D11学习:(七)绘图基础——彩⾊⽴⽅体的绘制⼀、概述在前⾯的⼏篇⽂章中,我们详细介绍了Direct3D渲染所需要的数学基础和渲染管道理论知识。
从这篇⽂章开始,我们就正式开始Direct3D的绘制学习过程了。
这篇⽂章中,主要讲解Direct3D的绘制基础过程,介绍配置渲染管道,定义顶点和像素着⾊器以及将⼏何图形提交到渲染管道进⾏绘制所需的Direct3DAPI接⼝和⽅法。
本⽂通过绘制⼀个彩⾊⽴⽅体来演⽰Direct3D的渲染过程,这个例⼦本⾝很简单,但是清晰的包含了Direct3D的渲染基本步骤。
因为绘制过程中涉及到Direct3D的API接⼝和⽅法,我们将在学习彩⾊⽴⽅体的绘制过程中详细介绍这些API接⼝和⽅法。
⼆、绘图基础2.1 创建顶点缓冲在D3D中,顶点由空间位置和各种附加属性组成。
定义顶点结构体如下,由空间位置和颜⾊组成,我们这个例⼦中使⽤的结构体就是它:struct Vertex{XMFLOAT3 Pos;XMFLOAT4 Color;};为了让GPU访问顶点数组,我们必须把它放在顶点缓冲(vertex buffer)中,该容器由ID3D11Buffer接⼝表⽰。
要创建⼀个顶点缓冲,我们必须执⾏以下步骤: (1)填写⼀个D3D11_BUFFER_DESC结构体,描述我们所要创建的缓冲区; (2)填写⼀个D3D11_SUBRESOURCE_DATA结构体,为缓冲区指定初始化数据; (3)调⽤ID3D11Device::CreateBuffer⽅法来创建缓冲区。
D3D11_BUFFER_DESC结构体的定义如下:typedef struct D3D11_BUFFER_DESC{UINT ByteWidth; // 将要创建的顶点缓冲区的⼤⼩,单位为字节D3D11_USAGE Usage; // ⼀个⽤于指定缓冲区⽤途的D3D11_USAGE枚举类型成员UINT BindFlags; // 对于顶点缓冲区,该参数应设为D3D11_BIND_VERTEX_BUFFERUINT CPUAccessFlags; // 指定CPU对资源的访问权限UINT MiscFlags; // 不需要为顶点缓冲区指定任何杂项(miscellaneous)标志值,所以该参数设为0UINT StructureByteStride; // 存储在结构化缓冲中的⼀个元素的⼤⼩,以字节为单位。
《计算机图形学程序设计》题目:绘制立方体学生姓名班级学号学生学院学生专业联系电话电子邮件指导教师黄睿指导单位计算机学院日期成绩批阅人日期一、课题名称使用OpenGL3.3以上的版本绘制一个立方体。
二、课题内容和要求内容:初步学习计算机图形学的基础知识,初步学会使用OpenGL,学会编写顶点着色器和片段着色器以及编译和链接,熟悉在三维空间下绘制图形的流程。
要求:使用OpenGL3.3以上的版本绘制图形。
三、课题分析本课题要求绘制一个立方体,本人绘制了一个不同的面呈现红、绿、蓝三色的正方体,绘制的步骤如下。
首先,在主函数开始前,以字符串的形式编写顶点着色器和片段着色器的代码。
其次,在主函数中,设置OpenGL的版本号为3.3,创建一个窗口对象,获取实际像素,并将该窗口对象设置为当前窗口,调用glViewport函数来设置窗口的维度,调用glEnable(GL_DEPTH_TEST)函数开启深度测试。
接着,调用glShaderSource函数获取编写的两个着色器的代码,调用glCompileShader 函数编译两个着色器,并调用glGetShaderiv函数检验是否成功编译,两个着色器编译完毕后调用glAttachShader函数和glLinkProgram函数实现链接,同时也要检验是否连接成功,最后把这两个着色器对象删除。
然后,定义顶点数组和颜色数组(本人将其放在一个数组中),创建并绑定VAO和VBO,调用glBufferData函数,把定义的数组中的数据复制到缓冲的内存中,调用glVertexAttribPointer函数设置顶点属性指针和颜色属性指针。
最后,在while循环中,设置模型矩阵Model、观察矩阵View和投影矩阵Projection,调用glDrawArrays函数画12个三角形。
四、详细设计1、流程图图1 OpenGL绘制立方体流程图2、详细代码#include <iostream>#define GLEW_STATIC#include <GL/glew.h>#include <GLFW/glfw3.h>#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>#define STB_IMAGE_IMPLEMENTATION#include "stb_image.h"using namespace glm;void framebuffer_size_callback(GLFWwindow* window, int width, int height){// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);}void processInput(GLFWwindow *window){if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true);}const GLint WIDTH = 800, HEIGHT = 600;//顶点着色器代码const GLchar *vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 position;\n""layout (location = 1) in vec3 color;\n""out vec3 Color;\n""uniform mat4 MVP;\n""void main(){""gl_Position = MVP * vec4(position, 1.0f);\n""Color = color;""}";//片段着色器代码const GLchar *fragmentShaderSource ="#version 330 core\n""out vec4 FragmentColor;\n""in vec3 Color;\n"//"uniform sampler2D texture1;\n""void main(){""FragmentColor = vec4(Color,1.0f);\n""}";int main(){glfwInit();//设置版本glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);//创建一个窗口对象GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "openglTest1", nullptr, nullptr);if (window == nullptr){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}//获取实际像素int screenWidth, screenHeight;glfwGetFramebufferSize(window, &screenWidth, &screenHeight);// 设为当前glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// Initialize GLEWglewExperimental = GL_TRUE;if (glewInit() != GLEW_OK){std::cout << "Failed to initialize GLEW" << std::endl;return -1;}//调用glViewport函数来设置窗口的维度glViewport(0, 0, screenWidth, screenHeight);//开启深度测试glEnable(GL_DEPTH_TEST);//编译连接两个着色器GLint success;GLchar infoLog[512];GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);glCompileShader(vertexShader);glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);std::cerr << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);glCompileShader(fragmentShader);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);std::cerr << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}GLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(fragmentShader, 512, nullptr, infoLog);std::cerr << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDetachShader(shaderProgram, vertexShader);glDetachShader(shaderProgram, fragmentShader);glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// 定义一个数组存储顶点信息和颜色信息float vertices[] = {-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.5f, -0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f,-0.5f, 0.5f, -0.5f, 1.0f, 0.0f,0.0f,-0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f,-0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f,-0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f,0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,1.0f,0.5f, -0.5f, -0.5f, 0.0f, 0.0f,1.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f,1.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f,1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f,1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f,1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f,1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f,1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f,1.0f, };//画Vertex需要VAO(索引表)//创建顶点缓冲对象VBOGLuint VAO, VBO;glGenBuffers(1, &VBO);//绑定VAOglBindVertexArray(VAO);//使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上glBindBuffer(GL_ARRAY_BUFFER, VBO);//调用glBufferData函数,它会把之前定义的顶点数据复制到缓冲的内存中glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);glEnableVertexAttribArray(0);////设置颜色属性指针glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && !glfwWindowShouldClose(window)){processInput(window);glClearColor(0.2f, 0.2f, 0.2f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glUseProgram(shaderProgram);glm::mat4 View = glm::lookAt(glm::vec3(2, 2, 2),glm::vec3(0, 0, 0),glm::vec3(0, 1, 0));glm::mat4 Projection = glm::perspective(glm::radians(45.0f), (float)screenWidth /(float)screenHeight,0.1f, 100.0f);glm::mat4 Model = glm::mat4(1.0);glm::mat4 MVP = Projection * View * Model;GLint MVPID = glGetUniformLocation(shaderProgram, "MVP");glUniformMatrix4fv(MVPID, 1, GL_FALSE, glm::value_ptr(MVP));glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 12 * 3);glfwSwapBuffers(window);glfwPollEvents();}glDisableVertexAttribArray(0);glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;}五、测试数据及其结果分析运行结果如下图所示。
Qt使⽤QPainter绘制3D⽴⽅体本⽂实例为⼤家分享了使⽤QPainter绘制3D⽴⽅体的具体代码,供⼤家参考,具体内容如下1.实现思路(⽹上有类似的,不过他不是⽤的 Qt ⾃带的矩阵运算类)实现思路有点类似使⽤ OpenGL 画⽴⽅体,先准备顶点数据://⽴⽅体前后四个顶点,从右上⾓开始顺时针vertexArr=QVector<QVector3D>{QVector3D{1,1,1},QVector3D{1,-1,1},QVector3D{-1,-1,1},QVector3D{-1,1,1},QVector3D{1,1,-1},QVector3D{1,-1,-1},QVector3D{-1,-1,-1},QVector3D{-1,1,-1} };//六个⾯,⼀个⾯包含四个顶点elementArr=QVector<QVector<int>>{{0,1,2,3},{4,5,6,7},{0,4,5,1},{1,5,6,2},{2,6,7,3},{3,7,4,0} };然后再和旋转矩阵、透视矩阵进⾏运算,得到 3D 顶点坐标在 2D 平⾯上的 xy 值。
根据顶点 xy 值,得到每个⾯的路径,然后绘制表⾯的路径。
这⾥⾯⽐较⿇烦的是判断哪些是表⾯,单个⽴⽅体还好,可以遍历⽐较 z 值,如果是多个物体运算量就⼤了,还是直接OpenGL 吧,毕竟我这个只是画着玩的。
2.实现代码代码实现效果 GIF 动图:主要代码:#ifndef MYCUBE_H#define MYCUBE_H#include <QWidget>#include <QMouseEvent>#include <QVector3D>#include <QMatrix4x4>class MyCube : public QWidget{Q_OBJECTpublic:explicit MyCube(QWidget *parent = nullptr);protected:void paintEvent(QPaintEvent *event) override;void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override;QPointF getPoint(const QVector3D &vt,int w) const;private:QVector<QVector3D> vertexArr; //⼋个顶点QVector<QVector<int>> elementArr; //六个⾯QMatrix4x4 rotateMat; //旋转矩阵QPoint mousePos; //⿏标位置bool mousePressed=false; //⿏标按下标志位};#endif // MYCUBE_H#include "MyCube.h"#include <QPainter>#include <QtMath>#include <QDebug>MyCube::MyCube(QWidget *parent): QWidget(parent){// 7------------------4// / / |// 3------------------0 |// | | |// | | |// | | |// | | |// | 6 | 5// | | /// 2------------------1//⽴⽅体前后四个顶点,从右上⾓开始顺时针vertexArr=QVector<QVector3D>{QVector3D{1,1,1},QVector3D{1,-1,1},QVector3D{-1,-1,1},QVector3D{-1,1,1},QVector3D{1,1,-1},QVector3D{1,-1,-1},QVector3D{-1,-1,-1},QVector3D{-1,1,-1} };//六个⾯,⼀个⾯包含四个顶点elementArr=QVector<QVector<int>>{{0,1,2,3},{4,5,6,7},{0,4,5,1},{1,5,6,2},{2,6,7,3},{3,7,4,0} };setFocusPolicy(Qt::ClickFocus); //Widget默认没有焦点}void MyCube::paintEvent(QPaintEvent *event){Q_UNUSED(event)QPainter painter(this);//先画⼀个⽩底⿊框painter.fillRect(this->rect(),Qt::white);QPen pen(Qt::black);painter.setPen(pen);painter.drawRect(this->rect().adjusted(0,0,-1,-1)); //右下⾓会超出范围//思路,找到z值最⾼的顶点,然后绘制该顶点相邻的⾯// 根据z值计算,近⼤远⼩//(此外,Qt是屏幕坐标系,原点在左上⾓)//矩形边框参考⼤⼩const int cube_width=(width()>height()?height():width())/4;//投影矩阵//(奇怪,为什么只是平移了z轴,没⽤perspective函数就有远⼩近⼤的效果, //在我的想象中默认不该是正交投影么)QMatrix4x4 perspective_mat;perspective_mat.translate(0.0f,0.0f,-0.1f);//计算顶点变换后坐标,包含z值max点就是正交表⾯可见的,//再计算下远⼩近⼤的透视投影效果齐活了QList<QVector3D> vertex_list; //和矩阵运算后的顶点QList<int> vertex_max_list; //top顶点在arr的位置float vertex_max_value; //top值//根据旋转矩阵计算每个顶点for(int i=0;i<vertexArr.count();i++){QVector3D vertex=vertexArr.at(i)*rotateMat*perspective_mat;vertex_list.push_back(vertex);//找出z值max的顶点if(i==0){vertex_max_list.push_back(0);vertex_max_value=vertex.z();}else{if(vertex.z()>vertex_max_value){vertex_max_list.clear();vertex_max_list.push_back(i);vertex_max_value=vertex.z();}else if(abs(vertex.z()-vertex_max_value)<(1E-7)){vertex_max_list.push_back(i);}}}//把原点移到中间来painter.save();painter.translate(width()/2,height()/2);//绘制front和back六个⾯,先计算路径再绘制QList<QPainterPath> element_path_list; //每个⾯路径QList<float> element_z_values; //每个⾯中⼼点的z值QList<QPointF> element_z_points; //每个⾯中⼼点在平⾯对应xy值QList<int> element_front_list; //elementArr中表⾯的indexfor(int i=0;i<elementArr.count();i++){const QVector3D vt0=vertex_list.at(elementArr.at(i).at(0));const QVector3D vt1=vertex_list.at(elementArr.at(i).at(1));const QVector3D vt2=vertex_list.at(elementArr.at(i).at(2));const QVector3D vt3=vertex_list.at(elementArr.at(i).at(3));//单个⾯的路径QPainterPath element_path;element_path.moveTo(getPoint(vt0,cube_width));element_path.lineTo(getPoint(vt1,cube_width));element_path.lineTo(getPoint(vt2,cube_width));element_path.lineTo(getPoint(vt3,cube_width));element_path.closeSubpath();//包含zmax点的就是正交表⾯可见的bool is_front=true;for(int vertex_index:vertex_max_list){if(!elementArr.at(i).contains(vertex_index)){is_front=false;break;}}if(is_front){element_front_list.push_back(i);}element_path_list.push_back(element_path);element_z_values.push_back((vt0.z()+vt2.z())/2);element_z_points.push_back((getPoint(vt0,cube_width)+getPoint(vt2,cube_width))/2); }//远⼩近⼤,还要把包含max但是被近⼤遮盖的去掉QList<int> element_front_remove;for(int i=0;i<element_front_list.count();i++){for(int j=0;j<element_front_list.count();j++){if(i==j)continue;const int index_i=element_front_list.at(i);const int index_j=element_front_list.at(j);if(element_z_values.at(index_i)>element_z_values.at(index_j)&&element_path_list.at(index_i).contains(element_z_points.at(index_j))){element_front_remove.push_back(index_j);}}}for(int index:element_front_remove){element_front_list.removeOne(index);}//根据计算好的路径绘制painter.setRenderHint(QPainter::Antialiasing,true);//画表⾯for(auto index:element_front_list){painter.fillPath(element_path_list.at(index),Qt::green);}//画被遮盖⾯的边框虚线painter.setPen(QPen(Qt::white,1,Qt::DashLine));for(int i=0;i<element_path_list.count();i++){if(element_front_list.contains(i))continue;painter.drawPath(element_path_list.at(i));}//画表⾯边框painter.setPen(QPen(Qt::black,2));for(auto index:element_front_list){painter.drawPath(element_path_list.at(index));}painter.restore();painter.drawText(20,30,"Drag Moving");}void MyCube::mousePressEvent(QMouseEvent *event){mousePressed=true;mousePos=event->pos();QWidget::mousePressEvent(event);}void MyCube::mouseMoveEvent(QMouseEvent *event){if(mousePressed){const QPoint posOffset=event->pos()-mousePos;mousePos=event->pos();//旋转矩阵 x和y分量//rotateMat.rotate(posOffset.x(),QVector3D(0.0f,-0.5f,0.0f));//rotateMat.rotate(posOffset.y(),QVector3D(0.5f,0.0f,0.0f));rotateMat.rotate(1.1f,QVector3D(0.5f*posOffset.y(),-0.5f*posOffset.x(),0.0f));update();}QWidget::mouseMoveEvent(event);}void MyCube::mouseReleaseEvent(QMouseEvent *event){mousePressed=false;QWidget::mouseReleaseEvent(event);}QPointF MyCube::getPoint(const QVector3D &vt,int w) const{//可以⽤z来⼿动计算远⼩近⼤,也可以矩阵运算//const float z_offset=vt.z()*0.1;//return QPointF{ vt.x()*w*(1+z_offset), vt.y()*w*(1+z_offset) };return QPointF{ vt.x()*w, vt.y()*w };}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
实验一实验目的:生成彩色立方体实验代码://ColorCube1.javaimport java.applet.Applet; //可以插入htmlimport java.awt.BorderLayout; //窗口采用BorderLayout方式布局import com.sun.j3d.utils.applet.MainFrame; //applicationimport com.sun.j3d.utils.geometry.ColorCube;//调用生成ColorCube的Utility import com.sun.j3d.utils.geometry.Primitive;import com.sun.j3d.utils.universe.*; //观测位置的设置import javax.media.j3d.*; //核心类import javax.vecmath.*; //矢量计算import com.sun.j3d.utils.behaviors.mouse.*;public class ColorCube1 extends Applet {public BranchGroup createSceneGraph() {BranchGroup objRoot=new BranchGroup();//BranchGroup的一个对象objRoot(放置背景、灯光)BoundingSphere bounds=new BoundingSphere(newPoint3d(0.0,0.0,0.0),100.0);//有效范围TransformGroup objTrans=new TransformGroup();objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);objRoot.addChild(objTrans);MouseRotate behavior = new MouseRotate();behavior.setTransformGroup(objTrans);objRoot.addChild(behavior);behavior.setSchedulingBounds(bounds);MouseZoom behavior2 = new MouseZoom();behavior2.setTransformGroup(objTrans);objRoot.addChild(behavior2);behavior2.setSchedulingBounds(bounds);MouseTranslate behavior3 = new MouseTranslate();behavior3.setTransformGroup(objTrans);objRoot.addChild(behavior3);behavior3.setSchedulingBounds(bounds);Color3f bgColor=new Color3f(0.0f,0.0f,0.0f);//背景颜色Background bg=new Background(bgColor);bg.setApplicationBounds(bounds);objRoot.addChild(bg);Color3f directionalColor=new Color3f(1.f,1.f,1.f);Vector3f vec=new Vector3f(1.f,1.f,-1.0f);DirectionalLight directionalLight=new DirectionalLight(directionalColor,vec);directionalLight.setInfluencingBounds(bounds);objRoot.addChild(directionalLight);Appearance app=new Appearance();//外观材质Material material=new Material();//圆锥颜色//material.setEmissiveColor(new Color3f(1.0f,1.0f,0.0f));material.setDiffuseColor(new Color3f(1.0f,1.0f,0.0f));//辐射光效果app.setMaterial(material);ColorCube cone=new ColorCube(0.2);objTrans.addChild(cone);//pile();return objRoot;}public ColorCube1() {setLayout(new BorderLayout());Canvas3D c=new Canvas3D(null);add("Center",c);BranchGroup scene=createSceneGraph();SimpleUniverse u=new SimpleUniverse(c);u.getViewingPlatform().setNominalViewingTransform();u.addBranchGraph(scene);}public static void main(String[] args) {new MainFrame(new ColorCube1(),400,300);}}运行截图:。
实验一
实验目的:生成彩色立方体
实验代码://ColorCube1.java
import java.applet.Applet; //可以插入html
import java.awt.BorderLayout; //窗口采用BorderLayout方式布局import com.sun.j3d.utils.applet.MainFrame; //application
import com.sun.j3d.utils.geometry.ColorCube;//调用生成ColorCube的Utility import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.universe.*; //观测位置的设置
import javax.media.j3d.*; //核心类
import javax.vecmath.*; //矢量计算
import com.sun.j3d.utils.behaviors.mouse.*;
public class ColorCube1 extends Applet {
public BranchGroup createSceneGraph() {
BranchGroup objRoot=new BranchGroup();
//BranchGroup的一个对象objRoot(放置背景、灯光)BoundingSphere bounds=new BoundingSphere(new
Point3d(0.0,0.0,0.0),100.0);//有效范围
TransformGroup objTrans=new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
objRoot.addChild(objTrans);
MouseRotate behavior = new MouseRotate();
behavior.setTransformGroup(objTrans);
objRoot.addChild(behavior);
behavior.setSchedulingBounds(bounds);
MouseZoom behavior2 = new MouseZoom();
behavior2.setTransformGroup(objTrans);
objRoot.addChild(behavior2);
behavior2.setSchedulingBounds(bounds);
MouseTranslate behavior3 = new MouseTranslate();
behavior3.setTransformGroup(objTrans);
objRoot.addChild(behavior3);
behavior3.setSchedulingBounds(bounds);
Color3f bgColor=new Color3f(0.0f,0.0f,0.0f);
//背景颜色
Background bg=new Background(bgColor);
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
Color3f directionalColor=new Color3f(1.f,1.f,1.f);
Vector3f vec=new Vector3f(1.f,1.f,-1.0f);
DirectionalLight directionalLight=new DirectionalLight(directionalColor,vec);
directionalLight.setInfluencingBounds(bounds);
objRoot.addChild(directionalLight);
Appearance app=new Appearance();
//外观材质
Material material=new Material();
//圆锥颜色
//material.setEmissiveColor(new Color3f(1.0f,1.0f,0.0f));
material.setDiffuseColor(new Color3f(1.0f,1.0f,0.0f));
//辐射光效果
app.setMaterial(material);
ColorCube cone=new ColorCube(0.2);
objTrans.addChild(cone);
//pile();
return objRoot;
}
public ColorCube1() {
setLayout(new BorderLayout());
Canvas3D c=new Canvas3D(null);
add("Center",c);
BranchGroup scene=createSceneGraph();
SimpleUniverse u=new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new ColorCube1(),400,300);
}
}
运行截图:。