目录
前言
前几天出去旅游,在路上完成了训练三,现在回家后记录一下
提示:以下是本篇文章正文内容,下面案例可供参考
一、OpenGL中光源的使用
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat AmbientLight0[4] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight0); //设置Light0的环境光颜色
GLfloat DiffuseLight0[4] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight0); //设置Light0的漫反射颜色
GLfloat SpecularLight0[4] = { 1.0,1.0,1.0,1.0 };
glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight0); //设置Light0的高光颜色
GLfloat LightPosition0[4] = { 0,0,0,1 };
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition0); //设置Light0的位置,其中若LightPosition0的第四个参数为-1,则表示灯光在无限远处发射
二、如何在OpenGL中通过回调函数实现简单的动画
glutIdleFunc((void*)()); //实现简单动画的关键回调函数
三、通过设置光源的不同时机,将光源设置在不同的坐标系下
想要将光源设置在不同的坐标系下,最终要的一组函数就是
glPushMatrix();
///各种变换的代码
glPopMatrix();
写在glPushMatrix()和glPopMatrix()中的变换可视为在同一坐标系下进行的变换操作
总结
上这次的完整版代码
#include"glut.h"
#include<cstdio>
#include<cstdlib>
#include<cmath>
GLint Height = 600;
GLint Width = 800;
GLfloat LightPosition0[4] = { 0,0,0,1 };
GLfloat LightPosition1[4] = { -8.0,-6.0,0,1 };
GLfloat LightPosition2[4] = { 0,4.0,0,1 };
int oldX;
int mouseX0;
int mouseX1;
int mouseX2;
bool TeaPotTra[3] = { false,false,false };
struct simpleCamera
{
float camera[3];
float lookat[3];
float cam[3];
};
simpleCamera camera;
GLfloat speed = 0;
void Lighting();
void init()
{
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST); //开启深度测试
Lighting();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 20.0, 0, 0, 0, 0, 1, 0);
glPushMatrix();
glRotatef(speed, 0.0f, 1.0f, 0.0f);
glTranslatef(8.0f, 0.0f, 0.0f);
glDisable(GL_LIGHTING);
glColor3f(1, 1, 1);
glutSolidSphere(0.15, 100, 100);
speed += 0.4;
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition0);
glPopMatrix();
//第一个壶
glPushMatrix();
glTranslatef(-4.0, 0.0, 0.0);
glRotatef(mouseX0, 0.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(4.0, 4.0, -4.0);
glDisable(GL_LIGHTING);
glColor3f(1.0, 0, 0);
glutSolidSphere(0.15, 100, 100);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT2, GL_POSITION, LightPosition2);
glPopMatrix();
glutSolidTeapot(1.0);
glPopMatrix();
//第二个壶
glPushMatrix();
glRotatef(mouseX1, 0.0f, 1.0f, 0.0f);
glutSolidTeapot(1.0);
glPopMatrix();
//第三个壶
glPushMatrix();
glTranslatef(0, -3, 0);
glRotatef(mouseX2, 0.0f, 1.0f, 0.0f);
glutSolidTeapot(1.0);
glPopMatrix();
glDisable(GL_LIGHTING);
glColor3f(0, 1, 0);
glPushMatrix();
glTranslatef(-8.0, -6.0, 0);
glutSolidSphere(0.15, 100, 100);
glPopMatrix();
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition1);
glutSwapBuffers();
}
void MouseFunc(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
oldX = x;
}
}
void MouseMove(int x, int y)
{
if (TeaPotTra[0])
mouseX0 += x - oldX;
else if (TeaPotTra[1])
mouseX1 += x - oldX;
else if (TeaPotTra[2])
mouseX2 += x - oldX;
oldX = x;
}
void KeyboardFunc(unsigned char key, int x, int y)
{
if (key == '1')
{
TeaPotTra[0] = true;
TeaPotTra[1] = false;
TeaPotTra[2] = false;
}
if (key == '2')
{
TeaPotTra[0] = false;
TeaPotTra[1] = true;
TeaPotTra[2] = false;
}
if (key == '3')
{
TeaPotTra[0] = false;
TeaPotTra[1] = false;
TeaPotTra[2] = true;
}
}
void Lighting()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat AmbientLight0[4] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight0);
GLfloat DiffuseLight0[4] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight0);
GLfloat SpecularLight0[4] = { 1.0,1.0,1.0,1.0 };
glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight0);
glEnable(GL_LIGHT1);
GLfloat AmbientLight1[4] = { 0.0, 1.0, 0.0, 1.0 };
glLightfv(GL_LIGHT1, GL_AMBIENT, AmbientLight1);
GLfloat DiffuseLight1[4] = { 0.0, 1.0, 0.0, 1.0 };
glLightfv(GL_LIGHT1, GL_DIFFUSE, DiffuseLight1);
GLfloat SpecularLight1[4] = { 0.0,1.0,0.0,1.0 };
glLightfv(GL_LIGHT1, GL_SPECULAR, SpecularLight1);
glEnable(GL_LIGHT2);
GLfloat AmbientLight2[4] = { 1.0, 0.0, 0.0, 1.0 };
glLightfv(GL_LIGHT2, GL_AMBIENT, AmbientLight2);
GLfloat DiffuseLight2[4] = { 1.0, 0.0, 0.0, 1.0 };
glLightfv(GL_LIGHT2, GL_DIFFUSE, DiffuseLight2);
GLfloat SpecularLight2[4] = { 1.0,0.0,0.0,1.0 };
glLightfv(GL_LIGHT2, GL_SPECULAR, SpecularLight2);
}
void Idle()
{
glutPostRedisplay();
}
void reshape(int w, int h)
{
float aspect = (float)w / ((h) ? h : 1);//平截头体的纵横比,也就是宽度除以高度,(h)?h:1意思是若h=0,则h=1
glViewport(0, 0, w, h);
//进行投影变换前调用下面两个函数,接下来的变换函数将影响投影矩阵
//在窗口改变函数reshape中先用glMatrixMode(GL_PROJECTION)定义视锥,再用glMatrixMode(GL_MODELVIEW)改为模型变换
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, aspect, 1.0f, 100.0f);//
glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(Width, Height);
glutCreateWindow("Test");
init();
glutDisplayFunc(display); //窗口绘制
glutIdleFunc(Idle);
glutReshapeFunc(reshape);
glutMouseFunc(MouseFunc); //注册鼠标点击事件
glutMotionFunc(MouseMove); //注册鼠标拖动事件
glutKeyboardFunc(KeyboardFunc); //注册键盘事件
glutMainLoop();
return 0;
}
以及最终实现的效果