上篇上手实践
运行结果
实现代码
#include <windows.h>
#include <GL/glut.h>
#define GLUT_DISABLE_ATEXIT_HACK //处理不同系统宏
//星状结构函数,添加了几何中心坐标,半径,叶片宽度占比,叶片数量 --------------------------------
// 绘制内部星状结构基本元素的函数 其中 k —叶片宽度占整个半径的比例 默认值 k = 0.25
void DrawElement(GLfloat Xo, GLfloat Yo, GLfloat R, GLfloat k=0.25) {
//由两个三角形组成
glBegin(GL_TRIANGLES);
// 第一个三角形
glVertex2f(Xo, Yo); // 叶片中心点
glVertex2f(Xo, Yo+ R); // 上角点
glVertex2f(Xo + k*R , Yo + k*R); // 右角点
glEnd() ;
glBegin(GL_TRIANGLES);
// 第二个三角形
glVertex2f(Xo, Yo);
glVertex2f(Xo, Yo + R);
glVertex2f(Xo - k*R , Yo + k*R);
glEnd();
}
// 绘制部星状结构基本元素几何变换及数量的函数 默认值 elementNum = 0.25
void DrawStar(GLfloat Xo, GLfloat Yo, GLfloat R, GLfloat k, int elementNum = 4) {
float angleStep = 360.0 / elementNum;
for (int i = 0; i < elementNum; ++i) {
glPushMatrix();// 保存当前矩阵状态
glTranslatef(Xo, Yo, 0.0); // 移动至当前叶片的位置
glRotatef(i * angleStep, 0.0, 0.0, 1.0); //旋转相应角度
glTranslatef(-Xo, -Yo, 0.0); //移动到原点
DrawElement(Xo, Yo, R, k); // 绘制元素
glPopMatrix();// 恢复矩阵状态
}
}
// 显示函数
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和缓存区
glColor3f(0.0, 0.0, 0.0); // 设置绘图颜色
DrawStar(750.0, 700.0, 550.0, 0.25, 5); //函数参数依次为几何中心坐标,半径,叶片宽度占比,叶片数量
glColor3f(1.0, 1.0, 1.0); // 设置绘图颜色
DrawStar(750.0, 700.0, 400.0, 0.30, 5);
glColor3f(0.0, 0.0, 0.0); // 设置绘图颜色
DrawStar(750.0, 700.0, 300.0, 0.30, 5);
glFlush(); // 刷新OpenGL命令缓冲区
}
// 初始化OpenGL环境
void init() {
glClearColor(1.0, 1.0, 1.0, 1.0); // 设置背景颜色
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 1500.0, 0.0, 1500.0); // 设置正交投影
}
int main(int argc, char** argv) {
glutInit(&argc, argv); // 初始化GLUT库
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // 设置显示模式
glutInitWindowPosition(800, 200); // 窗口位置
glutInitWindowSize(1500, 1500); // 设置窗口大小
glutCreateWindow("OpenGL_Draw_Design_Star"); // 创建窗口
init(); // 调用初始化函数
glutDisplayFunc(display); // 注册显示回调函数
glutMainLoop(); // 进入GLUT事件处理循环
return 0;
}
功能简单介绍
这段代码通过OpenGL和GLUT库在Windows系统中创建了一个图形窗口,并在其中绘制了一个多层次的星形图案。代码的核心在于两个绘图函数:DrawElement
负责绘制单个星形叶片,它由两个相连的三角形构成;而DrawStar
函数则负责将这个基本元素重复绘制并旋转,形成一个完整的星形。在display
函数中,我们看到了三次调用DrawStar
,分别绘制了三个大小和形状略有不同的星形,组成复合图案。
本次实验项目
要求
用线条描绘图片中的别墅
运行结果
图形代码
#include <windows.h>
#define GLUT_DISABLE_ATEXIT_HACK //处理不同系统的配置问题的宏
#include <GL/glut.h>
#include <stdio.h>
//定义二维数组,其第二维含有两个元素
//调用glVertex2i(houseline[i][0][Winheight-houseline[i][1])
int house_outline[][2]={
{290,1040},{290,1000},{380,870},{470,870},{470,730},{405,730},{405,680},
{455,680},{455,530},{365,525},{365,500},{500,375},{530,375},{700,240},
{730,240},{850,275},{850,190},{880,180},{900,190},{935,175},{980,190},
{980,335},{1080,440},{1080,560},{1200,640},{1200,665},{1150,665},{1150,1040},
{925,1040},{680,1040},{450,1040},{450,1000},{530,890},{620,890},{620,520},
{640,520},{640,480},{685,485},{685,525},{640,520},{640,480},{500,375},{600,380},
{700,490},{685,485},{640,480},{640,520},{620,520},{500,455},{405,525},{455,530},{530,465}
};
int house_chimney[][2]={
{670,520},{670,560},{680,560},{680,1040},{680,560},{730,560},{730,240},{730,560},{765,560},
{765,495},{765,520},{925,630},{925,1040},{925,630},{935,640},{1150,660},{1150,1040},{1150,660},
{1200,665},{1200,640},{935,615},{935,640},{935,615},{765,495},{880,510},{880,180},{880,350},
{850,350},{850,275},{850,350},{730,320},{880,510},{900,513},{900,190},{935,175},{935,520},
{900,513},{935,520},{980,535},{980,335},{980,535},{1080,560}
};
int house_door[][2]={
{405,680},{585,680},{585,730},{470,730},{585,730},{585,890},{500,890},{500,730},{550,730},
{550,800},{540,800},{540,780},{540,840},{540,820},{550,820},{550,800},{550,890},{560,890},
{560,730}
};
int house_stairs1[][2]={
{550,890},{470,890},{470,870},{410,870},{320,1000},{425,1000},{510,890}
};
int house_stairs2[][2]={
{290,1040},{600,1040},{500,905},{420,905},{420,905},{420,930},{480,930},{400,930},{400,930},
{400,955},{460,955},{380,955},{380,955},{380,980},{440,980},{360,980},{360,980},{360,1000}
};
int house_windows1[][2]={
{660,310},{660,380},{700,375},{700,305},{660,310},{680,307},{680,377}
};
int house_windows2[][2]={
{470,530},{470,680},{585,680},{585,530},{470,530},{527,530},{527,680}
};
int house_windows3[][2]={
{880,735},{880,910},{730,910},{730,735},{880,735},{880,823},{730,823},
{805,823},{805,735},{805,910}
};
int house_windows4[][2]={
{830,570},{770,570},{770,670},{830,670},{830,570},{800,570},{800,610},
{810,610},{810,630},{810,610},{800,610},{800,670}
};
int house_windows5[][2]={
{950,735},{1120,735},{1150,850},{1120,850},{1120,910},{950,910},{950,735},
{1120,735},{1150,850},{1080,850},{1080,910},{1080,850},{1010,850},{1010,910},
{1010,850},{970,850},{950,735}
};
//自定义划线函数,方便后续重复调用,减少工作量
void DrawLine(float x=1.0,float y=1.0,float z=1.0){
//程序健壮性
if((x||y||z)>1.0 && (x||y||z)<0.0){
printf("ERROR:函数实参范围为[0.0<=(x||y||z)<=1.0]\n");
x=0.0;
y=1.0;
z=1.0;
}
//房子外部轮廓
glBegin(GL_LINE_STRIP);
glColor3f(x, y, z); // 设置线条颜色
for(int i=0;i<52;i++){
glVertex2i(house_outline[i][0],1271-house_outline[i][1]);}
glEnd();
//右侧墙壁和烟囱
glBegin(GL_LINE_STRIP );
glColor3f(x, y, z); // 设置线条颜色
for(int i=0;i<42;i++){
glVertex2i(house_chimney[i][0],1271-house_chimney[i][1]);}
glEnd();
//房子门
glBegin(GL_LINE_STRIP);
glColor3f(x, y, z); // 设置线条颜色
for(int i=0;i<19;i++){
glVertex2i(house_door[i][0],1271-house_door[i][1]);}
glEnd();
//楼梯
glBegin(GL_LINE_STRIP);
glColor3f(x, y, z); // 设置线条颜色
for(int i=0;i<7;i++){
glVertex2i(house_stairs1[i][0],1271-house_stairs1[i][1]);}
glEnd();
glBegin(GL_LINES);
glColor3f(x, y, z); // 设置线条颜色
for(int i=0;i<18;i++){
glVertex2i(house_stairs2[i][0],1271-house_stairs2[i][1]);}
glEnd();
//窗户
glColor3f(x, y, z);// 设置线条颜色
//最上面小窗户
glBegin(GL_LINE_STRIP);
for(int i=0;i<7;i++){
glVertex2i(house_windows1[i][0],1271-house_windows1[i][1]);}
glEnd();
//阳台窗户
glBegin(GL_LINE_STRIP);
for(int i=0;i<7;i++){
glVertex2i(house_windows2[i][0],1271-house_windows2[i][1]);}
glEnd();
//中间大窗户
glBegin(GL_LINE_STRIP);
for(int i=0;i<10;i++){
glVertex2i(house_windows3[i][0],1271-house_windows3[i][1]);}
glEnd();
//中间小窗户
glBegin(GL_LINE_STRIP);
for(int i=0;i<12;i++){
glVertex2i(house_windows4[i][0],1271-house_windows4[i][1]);}
glEnd();
//最右侧窗户
glBegin(GL_LINE_STRIP);
for(int i=0;i<17;i++){
glVertex2i(house_windows5[i][0],1271-house_windows5[i][1]);}
glEnd();
}
void drawHouse(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和缓存区
glLineWidth(5);//画笔宽度
DrawLine();
glFlush();
}
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0); // 设置背景色为黑色
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 1458.0, 0.0, 1271.0); // 设置二维正交投影
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(200, 50); //绘图窗口与电脑桌面左上角的位置关系
glutInitWindowSize(1458, 1271); // 使用更合适的窗口大小
glutCreateWindow("House Drawing");
init();
glutDisplayFunc(drawHouse);
glutMainLoop();
return 0;
}
功能简单介绍
首先,代码通过定义多个二维数组,如house_outline、house_chimney等,分别存储房屋不同部分的坐标,模块化设计,便于维护和扩展。使得房屋的各个部分可以独立修改,增加了代码的灵活性。 其次,自定义的DrawLine函数简化了绘图过程,通过循环遍历坐标数组,绘制出房屋的各个部分,减少了代码重复,提高了效率。函数还包含了错误处理,确保颜色参数在合理范围内,增强了程序的健壮性。 此外,代码中不仅绘制了房屋的外部轮廓,还细致地绘制了烟囱、门、楼梯和多个窗户,展现了房屋的细节,使绘图更加真实和完整。 在初始化设置方面,init函数设置了黑色背景和二维正交投影,为绘图提供了合适的环境,确保了绘图的准确性和美观性。
上手实践
各位学有余力的先生和女生,如有兴趣的话,不妨参照上面内容,动手绘制平移,旋转,缩放变换后下面图片项目,祝你马到成功!
标签:850,openGL,int,0.0,图形学,DEV,730,house,680 From: https://blog.csdn.net/2303_77716250/article/details/143468191