程序示例精选
C++ VS OpenGL绘制教室三维立体旋转图像
如需安装运行环境或远程调试,可点击 博主头像进入个人主页查看博主联系方式,由专业技术人员远程协助!
前言
这篇博客针对《C++ VS OpenGL绘制教室三维立体旋转图像》编写代码,代码整洁,规则,易读。 学习与应用推荐首选。运行结果
文章目录
一、所需工具软件二、使用步骤
1. 主要代码
2. 运行结果
三、在线协助
一、所需工具软件
1. VS2019, C++2. Yolov8, OpenCV
二、使用步骤
代码如下(示例):
#include<windows.h>
#include<math.h>
#include<time.h>
#pragma warning(disable:4996)
/*******************************定义程序中所用的常数变量******************************************/
GLfloat light_position1[] = {
0,28,0,1.0 };
GLfloat model_ambient[] = {
0.05f,0.05f,0.05f,1.0f };
GLfloat mat_specular[] = {
0.8,1.0,1.0,1.0 };
GLfloat mat_shininess[] = {
5.0 };
GLfloat mat_ambient[] = {
0.1,0.1,0.1,1 };
GLfloat white_light[] = {
1.0,1.0,1.0,1.0 };
GLfloat light[] = {
1.0,1.0,1.0,1 };
GLfloat light_position0[] = {
0,28,20,1.0 };
GLUquadricObj* qobj;
int fantheta = 0;
BOOL TurnOn = FALSE;
// 当前时间,时 分 秒
float h = 0.0f;
float m = 0.0f;
float s = 0.0f;
const GLfloat PI = 3.141592653f;
/************************定义视点结构*********************************************************/
typedef struct EyePoint
{
GLfloat x;
GLfloat y;
GLfloat z;
}EyePoint;
EyePoint myEye;
EyePoint vPoint;
EyePoint up;
GLfloat pro_up_down = 29.0f;
GLfloat vAngle = 0;
/****************************载入位图作为纹理的相关函数************************************/
#define BMP_Header_Length 54
int power_of_two(int n)
{
if (n <= 0)
return 0;
return (n & (n - 1)) == 0;
}
/****************************载入一副位图作为纹理,返回的是纹理编号**********************************************/
GLuint load_texture(const char* file_name)
{
// 读取文件中图象的宽度和高度
fseek(pFile, 0x0012, SEEK_SET);
fread(&width, 4, 1, pFile);
fread(&height, 4, 1, pFile);
fseek(pFile, BMP_Header_Length, SEEK_SET);
// 计算每行像素所占字节数,并根据此数据计算总像素字节数
{
GLint line_bytes = width * 3;
while (line_bytes % 4 != 0)
++line_bytes;
total_bytes = line_bytes * height;
}
// 根据总像素字节数分配内存
pixels = (GLubyte*)malloc(total_bytes);
if (pixels == 0)
{
fclose(pFile);
return 0;
}
// 读取像素数据
if (fread(pixels, total_bytes, 1, pFile) <= 0)
GLint max;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);//获得OpenGL所支持的最大纹理
if (!power_of_two(width) || !power_of_two(height) || width > max || height > max)
{
const GLint new_width = 256;
const GLint new_height = 256; // 规定缩放后新的大小为边长的正方形
GLint new_line_bytes, new_total_bytes;
GLubyte* new_pixels = 0;
// 计算每行需要的字节数和总字节数
new_line_bytes = new_width * 3;
while (new_line_bytes % 4 != 0)
++new_line_bytes;
new_total_bytes = new_line_bytes * new_height;
// 分配内存
new_pixels = (GLubyte*)malloc(new_total_bytes);
if (new_pixels == 0)
{
free(pixels);
fclose(pFile);
return 0;
}
// 进行像素缩放
gluScaleImage(GL_RGB, width, height, GL_UNSIGNED_BYTE, pixels, new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);
// 释放原来的像素数据,把 pixels 指向新的像素数据,并重新设置 width 和 height
free(pixels);
pixels = new_pixels;
width = new_width;
height = new_height;
}
}
/**********************************定义各个纹理对象的名称************************************/
GLuint texblackboard, texwindow, texdesk, texsound;
GLuint texceiling, texdoor, texfloor, texbackwall, texpole;
GLuint texairfro, texairback, texhighland, texsdesk, texclock;
/*******************************绘制相关函数**************************************************/
//绘制教室这个大场景
void drawscence()
{
//设置材质相关参数
/*指定材质对漫射光的反射率,第一个参数决定该材质运用于图元的正面还是反面
第二个参数表示对何种光进行设置,GL_AMBIENT(环境光)、GL_DIFFUSE(漫射光)、
GL_AMBIENT_AND_DIFFUSE(环境光和漫射光)、GL_SPECULAR(平行/镜面光,
第三个参数是一个四维数组,这个数组描述了反光率的RGBA值,每一项取值都为0-1之间*/
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse1);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
//首先绘制天花板
glEnable(GL_TEXTURE_2D);//开启2D纹理功能
glBindTexture(GL_TEXTURE_2D, texceiling);//绑定纹理
//glColor3f(0.3, 0.3, 0.3);//设置颜色,黑色
//glColor3f(255, 255, 255);
glBegin(GL_QUADS);//画四边形
glNormal3f(0.0f, -1.0f, 0.0f);//用于定义法线向量
/*glTexCoord2f绘制图形时指定纹理的坐标,第一个是X轴坐标,0.0是纹理的左侧,0.5是纹理的中点,1.0是纹理的右侧,
第二个是Y轴坐标,0.0是纹理的底部,0.5是纹理的中点,1.0是纹理的顶部,
为了将纹理正确的映射到四边形上,您必须将纹理的右上角映射到四边形的右上角,纹理的左上角映射到四边形的左上角,
纹理的右下角映射到四边形的右下角,纹理的左下角映射到四边形的左下角,纹理的左上坐标是X:0.0,Y:1.0f,四边形的左上顶点是X:-1.0,Y:1.0。*/
glTexCoord2f(0.0f, 0.0f); glVertex3f(-40.0f, 30.0f, 30.0f);//四边形的点
glTexCoord2f(0.0f, 3.0f); glVertex3f(-40.0f, 30.0f, -30.0f);
glTexCoord2f(6.0f, 3.0f); glVertex3f(40.0f, 30.0f, -30.0f);
glTexCoord2f(6.0f, 0.0f); glVertex3f(40.0f, 30.0f, 30.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
//................................风扇................................................//
GLuint m = 0;
qobj = gluNewQuadric();//初始化二次曲面并创建一个指向二次曲面的指针
//...............................右边的风扇.............................//
glPushMatrix();//压入堆栈,保证此处坐标变换不影响外部大环境
glTranslatef(20.0, 5.0, -10.0 - 40 * m); //风扇的位置
if (TurnOn == TRUE) //如果TurnOn为1
{
fantheta += 10; //风扇转过的角度fantheta不断增加
}
glRotatef(fantheta, 0, 1, 0); //风扇旋转
glPushMatrix();//压入堆栈
glColor3f(0.7, 0.7, 0.7);
glTranslatef(0, 20, 0.0);//平移变换
glScalef(1, 0.05, 1);//缩放变换
glRotatef(240, 0, 1, 0);//绕y周旋转240度
gluCylinder(qobj, 1, 3, 10, 20, 20);//绘制一个底面圆半径为1、顶面圆半径为2、高为10的圆锥体
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);//定义材质光照
glPopMatrix();//弹出堆栈
//.............风扇的杆...........................//
glPushMatrix();//压入堆栈
glTranslatef(0, 33, 0.0);//平移变换
glRotatef(90, 1, 0, 0);//缩放变换
gluCylinder(qobj, 0.5, 0.5, 13, 10, 10);//绘制一个半径为0.5、高为13的圆锥体
glPopMatrix();//弹出堆栈
glPopMatrix();//弹出堆栈
//................左边的风扇...........................................//
glPushMatrix();
glTranslatef(-20.0, 5.0, -10.0 - 40 * m);
if (TurnOn == TRUE)
{
fantheta += 10;
}
glRotatef(fantheta, 0, 1, 0);
//..........风扇中间的扁圆形....................//
glPushMatrix();//风扇中间的扁圆形
glColor3f(0.7, 0.7, 0.7);
glTranslatef(0.0, 20.0, 0.0);
glScalef(1, 0.3, 1);
gluSphere(qobj, 2, 20, 20);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
glPopMatrix();
//............风扇旋转120度的扇叶...............//
glPushMatrix();//风扇旋转120度的扇叶
glColor3f(0.7, 0.7, 0.7);
glTranslatef(0, 20, 0.0);
glScalef(1, 0.05, 1);
glRotatef(120, 0, 1, 0);
gluCylinder(qobj, 1, 3, 10, 20, 20);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
glPopMatrix();
//............风扇不做旋转的扇叶.................//
glPushMatrix();//风扇不做旋转的扇叶
glColor3f(0.7, 0.7, 0.7);
glTranslatef(0, 20, 0.0);
glScalef(1, 0.05, 1);
gluCylinder(qobj, 1, 3, 10, 20, 20);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
glPopMatrix();
//.............风扇旋转240度的扇叶...............//
glPushMatrix();//风扇旋转240度的扇叶
glColor3f(0.7, 0.7, 0.7);
glTranslatef(0, 20, 0.0);
glScalef(1, 0.05, 1);
glRotatef(240, 0, 1, 0);
gluCylinder(qobj, 1, 3, 10, 20, 20);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
glPopMatrix();
//.............风扇的杆...........................//
glPushMatrix();
glTranslatef(0, 33, 0.0);
glRotatef(90, 1, 0, 0);
gluCylinder(qobj, 0.5, 0.5, 13, 10, 10);
glPopMatrix();
glPopMatrix();
//绘制黑板
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texblackboard);
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f); //用于定义法线向量
glTexCoord2f(0.0f, 0.0f); glVertex3f(-20.0, 8.0f, -29.9f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-20.0, 18.0f, -29.9f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(20.0, 18.0f, -29.9f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(20.0, 8.0f, -29.9f);
glEnd();
glDisable(GL_TEXTURE_2D);
//画黑板上方的灯
GLfloat blacklight[] = {
0.9,0.9,0.9,1 };//颜色(R,G,B,A),A仅用于颜色混合函数激活之后
glColor3f(1.0f, 1.0f, 1.0f);
//glColor3f(255, 255, 255);
glPushMatrix();//把当前的模型视图矩阵压入堆栈中保存下来
glTranslatef(-15, 20.4, -29.5);//平移函数,参数含义:位移
glScalef(8.0f, 0.8, 1.0f);//缩放函数,参数含义:倍数
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blacklight);
glutSolidCube(1.0f);//绘制边长为1的实心立方体,立方体的中心位于原点
glPopMatrix();
glPushMatrix();
glTranslatef(12, 20.4, -29.5);
glScalef(8.0f, 0.8, 1.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blacklight);
glutSolidCube(1.0f);
glPopMatrix();
//绘制教室前边一块高地并贴纹理
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texhighland);
//贴上面
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f); //用于定义法线向量
glTexCoord2f(0.0f, 0.0f); glVertex3f(-30.0f, 1.5f, -22.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -30.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(30.0f, 1.5f, -30.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(30.0f, 1.5f, -22.0f);
glEnd();
//贴左边
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f); //用于定义法线向量
glTexCoord2f(0.0f, 0.0f); glVertex3f(-30.0f, 0, -22.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -22.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -30.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-30.0f, 0, -30.0f);
glEnd();
//贴前边
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f); //用于定义法线向量
glTexCoord2f(0.0f, 0.0f); glVertex3f(-30.0f, 0, -22.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -22.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(30.0f, 1.5f, -22.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(30.0f, 0, -22.0f);
glEnd();
//glColor3f(255, 255, 255);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texdoor);
glBegin(GL_QUADS);
glNormal3f(-1.0f, 0.0f, 0.0f); //用于定义法线向量
glTexCoord2f(0.0f, 0.0f); glVertex3f(39.9f, 0.0f, -25.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(39.9f, 14.0f, -25.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(39.9f, 14.0f, -19.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(39.9f, 0.0f, -19.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
//绘制音响
glColor3f(0.0f, 0.0f, 0.0f);
//glColor3f(255, 255, 255);
glPushMatrix();
glTranslatef(-37.5, 26.25f, -5.5f);
glScalef(1.0f, 1.5f, 1.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sound);
glutSolidCube(1.0f);
glPopMatrix();
glPushMatrix();
glTranslatef(37.5, 26.25f, -5.5f);
glScalef(1.0f, 1.5f, 1.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sound);
glutSolidCube(1.0f);
glPopMatrix();
}
/**************************************绘制投影仪***********************************************/
void drawprojector()
{
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glNormal3f(1.0f, 0.0f, 1.0f); //用于定义法线向量
glVertex3f(-40.0f, 30.0f, -30.0 + 10 * sqrt(2));
glVertex3f(-40.0 + 10 * sqrt(2), 30.0f, -30.0f);//固定的两个点
glVertex3f(-40.0 + 10 * sqrt(2), pro_up_down, -30.0f);
glVertex3f(-40.0f, pro_up_down, -30.0 + 10 * sqrt(2));//下降或升起时改变的点
glEnd();
glColor3f(0.0f, 0.0f, 0.0f);
glLineWidth(4.0f);
glBegin(GL_LINES);
glVertex3f(-25.0f, 30.0f, -15.0f);
glVertex3f(-25.0f, 25.0f, -15.0f);
glEnd();
glColor3f(0.5f, 0.5f, 0.5f);
glPushMatrix();
glTranslatef(-25.0f, 24.0f, -15.0f);
glScalef(4.0f, 2.0f, 2.0f);
glutSolidCube(1.0f);
glPopMatrix();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINE_LOOP);//给出的点会绘制为一个环(所有的点首尾相接)
glVertex3f(-40.0f, 30.0f, -30.0 + 10 * sqrt(2));
glVertex3f(-40.0 + 10 * sqrt(2), 30.0f, -30.0f);
}
}
//绘制椅子
void drawchairs()
{
GLfloat chair[] = {
1.0f, 1.0f, 0.45f, 1.0f };// { 0.1, 0.67, 0.62 };
for (int j = 0; j <= 4; j++)
{
for (int i = 0; i <= 1; i++)
{
//画椅子底部
glColor3f(0.1, 0.67, 0.62);
glPushMatrix();
glTranslatef(-20 + i * 40, 3.1, -14.5 + j * 8);
glScalef(10, 0.2, 3);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, chair);
glutSolidCube(1.0f);
glPopMatrix();
//画椅子靠背
glColor3f(0.1, 0.67, 0.62);
glPushMatrix();
glTranslatef(-20 + i * 40, 5, -13 + j * 8);
glScalef(10, 4, 0.2);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, chair);
glutSolidCube(1.0f);
glPopMatrix();
//画椅子腿
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
glLineWidth(3.0f);
glVertex3f(-25 + i * 40, 3.0f, -13 + j * 8);
glVertex3f(-25 + i * 40, 0.0f, -13 + j * 8);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
glLineWidth(3.0f);
glVertex3f(-15.0 + i * 40, 3.0f, -13 + j * 8);
glVertex3f(-15.0 + i * 40, 0.0f, -13 + j * 8);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
glLineWidth(3.0f);
glVertex3f(-25.0 + i * 40, 0.0f, -12.5 + j * 8);
glVertex3f(-25 + i * 40, 0.0f, -13.5 + j * 8);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
glLineWidth(3.0f);
glVertex3f(-15 + i * 40, 0.0f, -12.5 + j * 8);
glVertex3f(-15 + i * 40, 0.0f, -13.5 + j * 8);
glEnd();
/*******************************************响应普通键盘操作,w,s,a,d以及退出esc键*******************************/
GLvoid OnKeyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 97://a 向左
myEye.x -= 0.5;
vPoint.x -= 0.5;
if (myEye.x <= -38)
myEye.x = -38;
break;
case 100://d 向右
myEye.x += 0.5;
vPoint.x += 0.5;
if (myEye.x >= 38)
myEye.x = 38;
break;
case 119://w 向前
myEye.z -= 0.5;
if (myEye.z <= -28)
myEye.z = -28;
break;
case 115://s 向后
myEye.z += 0.5;
if (myEye.z >= 28)
myEye.z = 28;
break;
case 27://esc
exit(0);
}
reshape(WinWidth, WinHeight);//窗口刷新
glutPostRedisplay();
}
/****************************************响应特殊键盘操作******************************************************/
GLvoid OnSpecial(int key, int x, int y)//上下左右
{
switch (key)
{
case GLUT_KEY_LEFT:
vAngle -= 0.05;
break;
case GLUT_KEY_RIGHT:
vAngle += 0.05;
break;
case GLUT_KEY_UP:
myEye.y += 0.05;
if (myEye.y >= 30)
myEye.y = 30;
break;
case GLUT_KEY_DOWN:
myEye.y -= 0.5;
if (myEye.y <= 0)
myEye.y = 30;
break;
case GLUT_KEY_PAGE_DOWN://PageDown键
myEye.z += 0.5;
if (myEye.z >= 30)
myEye.z = 30;
break;
case GLUT_KEY_PAGE_UP://PageUp键
myEye.z -= 0.5;
if (myEye.z <= -30)
myEye.z = -30;
break;
case GLUT_KEY_F1:
projectup();
break;
case GLUT_KEY_F2:
projectdown();
break;
case GLUT_KEY_F3:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_LIGHT1);
break;
case GLUT_KEY_F4:
//glDisable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_LIGHT1);
break;
case GLUT_KEY_F5:
TurnOn = true;
break;
case GLUT_KEY_F6:
TurnOn = false;
break;
}
reshape(WinWidth, WinHeight);
glutPostRedisplay();
}
GLvoid OnIdle()
{
glutPostRedisplay();// 重画
//当回调函数处理完键盘事件后,显示函数会自动被调用,屏幕会被重绘.这样,GLUT程序会过于频繁的调用显示函数,抢占cpu资源
//选择性的告诉GLUT去调用显示函数(glutPostRedisplay函数会标记当前窗体来重新显示)
//目的:节省cpu资源,保持我们的GLUT程序的占用行为不生效.
}
/*************************************初始化函数,对各项参数进行初始化*********************************************/
void initial()
{
glClearColor(0, 0, 0, 0);
glEnable(GL_TEXTURE_2D);
/*设置纹理跟材质的融合方式,这里是只是用纹理,覆盖模型的材质*/
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
/*********************************************对灯光进行初始化****************************************************/
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model_ambient);//将背景光设定为全局值
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);//把无限远的观察点改为局部观察点
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);//指定物体前面镜面反射的颜色
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);//指定物体前面镜面反射的指数
/*设置点光源*/
/*GL_POSITION指定光源位置,GL_AMBIENT表示各种光线照射到该材质上,经过很多次反射后最终遗留在环境中的光线强度(颜色),
对背景(环境)光有贡献。GL_DIFFUSE表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色)。
GL_SPECULAR表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜色)。通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,
可以达到比较真实的效果。使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性。*/
/*glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
glLightfv(GL_LIGHT0, GL_AMBIENT, mat_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light);
glLightfv(GL_LIGHT0, GL_SPECULAR, light);*/
/*设置平行光源*/
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
glLightfv(GL_LIGHT1, GL_AMBIENT, mat_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white_light);
glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glEnable(GL_COLOR_MATERIAL);//激活
/**********************************************************************************************/
/*glShadeModel函数用于控制opengl中绘制指定两点间其他点颜色的过渡模式,
GL_SMOOTH(默认)将制定的两点颜色进行插值,绘制之间的其他点*/
glShadeModel(GL_SMOOTH);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); //指定材料着色的面
//glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); //指定材料对镜面光的反射
glEnable(GL_DEPTH_TEST);//
}
void print()
{
printf("**************************************************** \n");
printf(" \n");
printf("操作按键信息提示: \n");
printf("上键和下键分别控制视角向下和向上 \n");
printf("左键和右键分别控制向左环视和向右环视 \n");
printf("w,s,a,d键分别表示向前,后,左,右,进行平移(注意键盘大小写)\n");
printf("pgup和pgdn分别控制向前漫游和向后漫游 \n");
printf("F5、F6键分别控制风扇的开、关 \n");
printf("F3、F4键分别控制开灯、关灯 \n");
printf("F1、F2键分别控制投影仪放下和收起 \n");
printf("ESC键退出窗口 \n");
printf(" \n");
}
int main(int argc, char* argv[])
{
myEye.x = 0;
myEye.y = 15;
myEye.z = 25;
vPoint.x = 0;
vPoint.y = 15;
vPoint.z = -30;
up.x = 0;
up.y = 1;
up.z = 0;
vAngle = 0;
/*启用了之后,OpenGL在绘制的时候就会检查,当前像素前面是否有别的像素,
如果别的像素挡道了它,那它就不会绘制,也就是说,OpenGL就只绘制最前面的一层。*/
glEnable(GL_DEPTH_TEST);
glutInit(&argc, argv);
/*定义显示方式,GLUT_RGBA指定一个RGBA窗口,GLUT_SINGLE.单缓冲区窗口*/
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutInitWindowPosition(400, 0);//设置初始窗口的位置(窗口左上角相对于桌面坐标(x,y))
glutInitWindowSize(800, 600);//设置窗口大小
glutCreateWindow("classroom");
initial();//创建显示窗口
SetupRC();//(2)
glutDisplayFunc(&myDisplay);
glutTimerFunc(1000, timerFunc, 1);//(1)
//glutDisplayFunc(&myDisplay);//注册显示回调函数,包含重绘场景所需的所有代码
glutReshapeFunc(reshape);//注册窗口改变回调函数
glutKeyboardFunc(OnKeyboard);//注册键盘响应事件
//对键盘上特殊的4个方向按键的响应函数
glutSpecialFunc(OnSpecial);
glutIdleFunc(OnIdle);//注册闲置响应函数,该函数调用放在主程序main()中,通常利用它可实现简单动画。
///***************************************设置纹理***********************************************/
texblackboard = load_texture("blackboard.bmp");
texwindow = load_texture("window.bmp");
texsound = load_texture("sound.bmp");
texceiling = load_texture("ceiling.bmp");
texdoor = load_texture("door.bmp");
texfloor = load_texture("floor.bmp");
texbackwall = load_texture("backwall.bmp");
texpole = load_texture("pole.bmp");
texairfro = load_texture("airconditionfront.bmp");
texairback = load_texture("airconditionback.bmp");
texhighland = load_texture("gaodi.bmp");
texsdesk = load_texture("sdesk.bmp");
texclock = load_texture("clock.bmp");
///************************************************************************************************/
print();
//开始显示
glutMainLoop();//进入事件处理循环
return 0;
}
运行结果
三、在线协助:
如需安装运行环境或远程调试,可点击博主头像,进入个人主页查看博主联系方式,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Visual Studio, Qt, C++, Python编程语言入门指导
3)界面美化
4)软件制作
博主个人主页:https://developer.aliyun.com/profile/expert/rfnzgp3sk3ahc
博主所有文章点这里:https://developer.aliyun.com/profile/expert/rfnzgp3sk3ahc
博主联系方式点这里:https://developer.aliyun.com/profile/expert/rfnzgp3sk3ahc