1.Opengl的Hello world
最基础的程序,画了个三角形,请确保理解这个程序,核心是opengl是一个状态机。想象opengl是一个几何画板,glBegin(GL_TRIANGLES);
就是点击绘制三角。glColor3f(1.0, 0.0, 0.0);
就是将颜色设置为红色。然后你在三个不同位置点了三个点。glFlush();
就是保存提交给画面。然后你就得到了结果。
#include <gl/glut.h>
//当窗口发生变化(如改变大小)时自动调用
void mydisplay()
{
//清除颜色缓存
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
//二维也可以用glVertex2f
//第一点红色
glColor3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
//第二点绿色
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
//第三点蓝色
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
//初始化窗口名称
glutCreateWindow("A Triangle");
//绑定display函数
glutDisplayFunc(mydisplay);
//开启窗口循环
glutMainLoop();
return 0;
}
2.初始化(调整试图)
手动设置了使用RGB绘制、窗口位置及窗口大小。并且在init函数中加入了glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
将图像变成了图中(x,y,z)分别对应范围(0-1,0-1,0-1)区间。
#include <gl/glut.h>
//当窗口发生变化(如改变大小)时自动调用
void mydisplay()
{
//清除颜色缓存
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
//二维也可以用glVertex2f
//第一点红色
glColor3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
//第二点绿色
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
//第三点蓝色
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glFlush();
}
void init()
{
//全屏颜色变成黑色
glClearColor(0.0, 0.0, 0.0, 1.0);
//改变投影视图,
glMatrixMode(GL_PROJECTION);
//opengl是一个状态机,要先清空之前的变换矩阵数据,所以每次视角操作时都要先变为单位矩阵
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
//GLUT_RGB指使用RGB进行绘制
glutInitDisplayMode(GLUT_RGB);
//初始化窗口大小
glutInitWindowSize(100, 100);
//初始化窗口位置
glutInitWindowPosition(100, 100);
//设置窗口名
glutCreateWindow("A Triangle");
//绑定display函数
glutDisplayFunc(mydisplay);
//设定opengl初始状态
init();
//开启窗口循环
glutMainLoop();
return 0;
}
3.增加Reshape函数
在改变窗口时会调用的函数。默认的reshape函数会直接拉伸图形。
我们希望图像不被拉伸,而是保持原有大小。
#include <gl/glut.h>
//窗口初始大小
int initW = 300;
int initH = 300;
//当窗口发生变化(如改变大小)时自动调用
void mydisplay()
{
//清除颜色缓存
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
//二维也可以用glVertex2f
//第一点红色
glColor3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
//第二点绿色
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
//第三点蓝色
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glFlush();
}
//初始化函数,一般包括视角等
void init()
{
//全屏颜色变成黑色
glClearColor(0.0, 0.0, 0.0, 1.0);
//改变投影视图,
glMatrixMode(GL_PROJECTION);
//opengl是一个状态机,要先清空之前的变换矩阵数据
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
}
//当改变窗口大小时调用的数据
void myReshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(0, 1.0, 0.0, (GLfloat)h / (GLfloat)w * 1.0, 0.0, 1.0);
else
glOrtho(0, (GLfloat)w / (GLfloat)h * 1.0, 0.0, 1.0, 0.0, 1.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
//GLUT_RGB指使用RGB进行绘制
glutInitDisplayMode( GLUT_RGB);
//初始化窗口大小
glutInitWindowSize(initW, initH);
//初始化窗口位置
glutInitWindowPosition(100, 100);
//设置窗口名
glutCreateWindow("A Triangle");
//绑定display函数
glutDisplayFunc(mydisplay);
//设定opengl初始状态
init();
//绑定改变窗口大小时调用的函数
glutReshapeFunc(myReshape);
//开启窗口循环
glutMainLoop();
return 0;
}
3.事件
增加了鼠标左键点击事件mouse,点击时会改变图像亮度并输出点击位置
#include <gl/glut.h>
#include <iostream>
//窗口初始大小
int initW = 300;
int initH = 300;
//颜色亮度
GLfloat brightness = 1.0;
GLfloat increment = -0.1;
//当窗口发生变化(如改变大小)时自动调用
void mydisplay()
{
//清除颜色缓存
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
//二维也可以用glVertex2f
//第一点红色
glColor3f(brightness, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
//第二点绿色
glColor3f(0.0, brightness, 0.0);
glVertex3f(0.0, 1.0, 0.0);
//第三点蓝色
glColor3f(0.0, 0.0, brightness);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glFlush();
}
//初始化函数,一般包括视角等
void init()
{
//全屏颜色变成黑色
glClearColor(0.0, 0.0, 0.0, 1.0);
//改变投影视图,
glMatrixMode(GL_PROJECTION);
//opengl是一个状态机,要先清空之前的变换矩阵数据
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
}
//当改变窗口大小时调用的数据
void myReshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(0, 1.0, 0.0, (GLfloat)h / (GLfloat)w * 1.0, 0.0, 1.0);
else
glOrtho(0, (GLfloat)w / (GLfloat)h * 1.0, 0.0, 1.0, 0.0, 1.0);
}
//鼠标事件
void mouse(int btn, int state, int x, int y)
{
//左击鼠标,调整图像亮度
if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
//输出位置,注意鼠标原点在左上角,图像原点在右下角,所以y是反的
std::cout << "x: " << x << " y: " << y << std::endl;
//改变亮度
brightness += increment;
if (brightness >= 1.0 || brightness <= 0.0)
increment = -increment;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
//GLUT_RGB指使用RGB进行绘制
glutInitDisplayMode( GLUT_RGB);
//初始化窗口大小
glutInitWindowSize(initW, initH);
//初始化窗口位置
glutInitWindowPosition(100, 100);
//设置窗口名
glutCreateWindow("A Triangle");
//绑定display函数
glutDisplayFunc(mydisplay);
//设定opengl初始状态
init();
//绑定改变窗口大小时调用的函数
glutReshapeFunc(myReshape);
//绑定鼠标事件
glutMouseFunc(mouse);
//开启窗口循环
glutMainLoop();
return 0;
}
4.动画
使用定时器的一段动画,图像亮度随时间变化
#include <gl/glut.h>
#include <iostream>
//窗口初始大小
int initW = 300;
int initH = 300;
//颜色亮度
GLfloat brightness = 1.0;
GLfloat increment = -0.1;
//当窗口发生变化(如改变大小)时自动调用
void mydisplay()
{
//清除颜色缓存
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
//二维也可以用glVertex2f
//第一点红色
glColor3f(brightness, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
//第二点绿色
glColor3f(0.0, brightness, 0.0);
glVertex3f(0.0, 1.0, 0.0);
//第三点蓝色
glColor3f(0.0, 0.0, brightness);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
//使用DOUBLE_BUFFER后,使用以下代码来交换前后台内存
glutSwapBuffers();
}
//定时器调用的函数
void changeColor(int x)
{
//改变亮度
brightness += increment;
if (brightness >= 1.0 || brightness <= 0.0)
increment = -increment;
//立刻重新调用display函数,不然图像不会被立刻绘制
glutPostRedisplay();
//设置新的定时器
glutTimerFunc(100, changeColor, 0);
}
//初始化函数,一般包括视角等
void init()
{
//全屏颜色变成黑色
glClearColor(0.0, 0.0, 0.0, 1.0);
//改变投影视图,
glMatrixMode(GL_PROJECTION);
//opengl是一个状态机,要先清空之前的变换矩阵数据
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
//GLUT_DOUBLE双缓存,通常应用于动画中,可以使动画更顺滑
//GLUT_RGB指使用RGB进行绘制
glutInitDisplayMode( GLUT_RGB|GLUT_DOUBLE);
//初始化窗口大小
glutInitWindowSize(initW, initH);
//初始化窗口位置
glutInitWindowPosition(100, 100);
//设置窗口名
glutCreateWindow("A Triangle");
//设置定时函数
glutTimerFunc(10, changeColor, 0);
//绑定display函数
glutDisplayFunc(mydisplay);
//设定opengl初始状态
init();
//开启窗口循环
glutMainLoop();
return 0;
}
文章评论