静止的矩形
#include "stdafx.h"
#include<windows.h>
#include<gl/glut.h>
#include<gl/gl.h>
#include<gl/glu.h>
//头文件/表示在gl目录下的.h头文件
//函数用于在窗口中绘制需要的图形
//只是一个场景scene 并不会真正绘制到图形中去。
void RenderScene(void)
{
//用当前清除颜色缓冲区,即设定窗口的背景颜色
// 清除viewport的缓冲区
//大概就是清除下面所要画的区域的缓冲区
glClear(GL_COLOR_BUFFER_BIT);
//设置当前绘图使用的GGB颜色 red
glColor3f(1.0f,0.0f,0.0f);
//使用当前的颜色绘制一个填充的矩形
//绘制矩形,窗口坐标系是左下角(0,0),x向右,y向上
//qt使用的是右上角(0,0)
glRectf(100.0f,150.0f,150.0f,100.0f);
//强制刷新OpenGL命令队列
glFlush();
/*
简单地说glFlush()就是强制刷新,OpenGL是使用一条渲染管线[3] 线性处理命令的,一般情况下,
我们提交给OpenGL的指令并不是马上送到驱动程序[4] 里执行的,而是放到一个缓冲区里面,
等这个缓冲区满了再一次过发到驱动程序里执行;很多时候只有几条指令是填充不满那个缓冲区的,
就是说这些指令根本没有被发送到驱动里,所以我们要调用glFlush来强制把这些指令送到驱动里进行处理。
*/
}
//函数ChangeSize是窗口大小改变时调用的登记函数
//GLsizeiGLsizei 是32位整数
void ChangeSize(GLsizei w, GLsizei h)
{
//窗口的高度y不为0
//去掉调试之后,还没发现有什么区别
if (h == 0)
h = 1;
//定义视区并指明尺寸
//一般是充满整个屏幕
glViewport(0,0,w,h);
/*
glMatrixMode设置当前矩阵模式:
GL_MODELVIEW, 对模型视景矩阵堆栈应用随后的矩阵操作.
GL_PROJECTION, 对投影矩阵应用随后的矩阵操作.
GL_TEXTURE, 对纹理矩阵堆栈应用随后的矩阵操作.
与glLoadIdentity()一同使用
glLoadIdentity():将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作
*/
//重置坐标系统,使投影变换复位
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立修建空间的范围
//glOrtho是在3D笛卡儿坐标空间定义
if (w <= h)
glOrtho(0.0f, 250.0f, 0.0f, 250.0f*h / w, 1.0f, -10.f);
else
glOrtho(0.0f, 250.0*w/h, 0.0f, 250.0f, 1.0f, -1.0f);
//告诉OpenGL将来的所有变换都会影响模型
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//函数setupRC用于初始化,常用来设置场景渲染状态
void SetupRC(void)
{
//这个函数用于设置清除窗口时使用的颜色,即设定窗口内的背景颜色
//最后一个参数是alpha,主要用于混合的特殊效果,如半透明效果等
//其实就是使用某种颜色 清空当前的所有颜色,或者说填充整个窗口
glClearColor(0.0f,1.0f,0.0f,1.0f);
}
//主函数基本都是glut的框架
void main(void )
{
//初始化GLUT库OpenGL窗口的显示模式
//glutInitDisplayMode sets the initial display mode
//创建窗口时使用单缓冲区GLUT_SINGLE并使用RGB颜色模式
//一般双模式GLUT_DOUBLE是用于动画效果的场合
//这是两个默认的参数
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
//创建一个名为GLRect的窗口
glutCreateWindow("GLRect");
//callback
//glutDisplayFunc sets the display callback for the current window
//设置当前窗口的显示回调函数和窗口再整形回调函数
//这样当要绘制窗口,就会调用自定义RenderScene函数 比如添加一个图形
glutDisplayFunc(RenderScene);
//这样改变窗口,就会调用ChangeSize函数 比如放大或者缩小窗口
// glutReshapeFunc(void (*func)(int width, int height));
//The width and height parameters of the callback specify the new window size in pixels
//回调函数会指定对应窗口的大小,然后通过参数传递给width,height. 大概是这个意思吧。
//除了窗口大小改变会调用回调函数之外,当第一次创建窗口的时候,回调函数也会被调用。
glutReshapeFunc(ChangeSize);
//可以通过调式加深对这两个回调函数的理解。
//SetupRC并不是GLUT的框架,是自定义的函数, 其作用是进行OpenGL初始化
//OpenGL的初始化必须在渲染之前执行
SetupRC();
//启动主程序GLUT事件处理循环
//该函数让GLUT框架开始运行,所有设置的回调函数开始工作,
//直到用户终止程序为止
//也就是说,SetupRC是在渲染之前执行的。
glutMainLoop();
}
跳动的矩形
#include "stdafx.h"
#include <gl\glut.h>
#include <gl\GLU.h>
#include <gl\GL.h>
#include <math.h>
const GLfloat PI = 3.141595654f;
const int windowWidth = 400;
const int windowHeight = 400;
GLfloat posX = 100.0f;
GLfloat posY = 200.0f;
GLsizei rsize = 50;
GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;
void myDisplay(void)
{
// 用当前清除色清除颜色缓冲区,即设定窗口的背景色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0, 0);
glRectf(posX, posY, posX + rsize, posY + rsize);
//glFlush();
glutSwapBuffers(); // 双缓冲下使用该函数交换两个缓冲区的内容
}
void timerFunc(int value)
{
if (posX > windowWidth - rsize || posX < 0)
xstep = -xstep;
if (posY > windowHeight - rsize || posY < 0)
ystep = -ystep;
if (posX > windowWidth - rsize)
posX = windowWidth - rsize - 1;
if (posY > windowHeight - rsize)
posY = windowHeight - rsize - 1;
posX += xstep;
posY += ystep;
/*
glutPostRedisplay 标记当前窗口需要重新绘制。
通过glutMainLoop下一次循环时,窗口显示将被回调以重新显示窗口的正常面板。
*/
glutPostRedisplay();
/*
(1)如果用定时器的话,初始的时候注册一个定时器的回调函数,原型是
glutTimerFunc(unsigned int millis, void (*func)(int value), int value);
参数对应关系为:glutTimerFunc(毫秒数, 回调函数指针, 区别值);
(2)写自己的回调函数 void OnTimer(int value);
用value区分是哪个定时器
(3)在函数里改变和位置有关的变量,然后调用glutPostRedisplay();用来重绘
(4)最后再次调用glutTimerFunc,因为glut的定时器是调用一次才产生一次定时,所以如果要持续产生定时的话,
在定时函数末尾再次调用glutTimerFunc
*/
glutTimerFunc(33, timerFunc, 1);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
//glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // 使用双缓冲
glutInitWindowPosition(100, 100);
glutInitWindowSize(windowWidth, windowHeight);
glutCreateWindow("第一个OpenGL程序");
gluOrtho2D(0.0, windowWidth, 0.0, windowHeight);
glutDisplayFunc(&myDisplay);
glutTimerFunc(33, timerFunc, 1);
glutMainLoop();
return 0;
}
说明:这个图是动图,红色矩形可以跳动
地球绕太阳转动_OpenGL
#include <gl/glut.h>
#define WIDTH 400
#define HEIGHT 400
static GLfloat angle = 0.0f;
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 创建透视效果视图
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// 定义太阳光源,它是一种白色的光源
{
GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
// 定义太阳的材质并绘制太阳
{
GLfloat sun_mat_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_diffuse[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_shininess = 0.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, sun_mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular);
glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission);
glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);
glutSolidSphere(2.0, 40, 32);
}
// 定义地球的材质并绘制地球
{
GLfloat earth_mat_ambient[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_diffuse[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f};
GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat earth_mat_shininess = 30.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
glRotatef(angle, 0.0f, -1.0f, 0.0f);
glTranslatef(5.0f, 0.0f, 0.0f);
glutSolidSphere(2.0, 40, 32);
}
glutSwapBuffers();
}
void myIdle(void)
{
angle += 1.0f;
if( angle >= 360.0f )
angle = 0.0f;
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("OpenGL光照演示");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}