一、窗口系统和OGL实例
// 窗口系统:窗口系统和OGL2D3D图形图像渲染分离的;他们之间的联系由OS窗口系统底层模块都会负责实现OGL实例初始化,控制渲染过程,事件处理;使得他们可以结合起来在不同平台上渲染。
/*
OGL实例初始化:线程,OGL线程只对应一个当前活动的OGL实例,多个OGL实例可以非同时的访问同一个表面(设备表面)。
控制渲染过程:管理或查询,释放OGL环境:管理OGL实例创建。
FB缓冲区(颜色,辅助,深度,模板)配置,交换前后台缓冲。
离屏渲染aglSetOffScreen,全屏渲染aglSetFullScreen。
清理可绘图表面,glXDesctoryWindow().
系统字体显示列表(位图,或轮廓纹理字体).
寻找颜色调色板,把特定的颜色索引平面映射到物理调色板。
同步执行,事件发起请求后会调用glXWaitGL,glFinish,让事件完成后,才继续执行图形渲染。
事件处理:请求接收和查询OGL事件,鼠标,键盘,窗口变化display事件,重新绘制事件,调整窗口大小,
事件绘制在glWait事件处理完才继续渲染图形。
访问依赖于OGL实现的函数(特别是新特性的拓展函数):
char* strFunc = glGetString();
PROC func = (PROC)wglGetProcAddress(strFunc);//通过统一的函数指针接口实现函数查询
*/
// 同一个渲染线程中只有一个活动的OGL渲染环境实例,所以这里创建会失败,每个绘图窗口都会关联一个渲染实例。
// 多个OGL实例可以非同时的访问同一个表面(设备表面)。一般同一个app用一个OGL渲染环境对象。
/*HDC oglCotenObj;
HGLRC hgl = wglCreateContext(oglCotenObj);*/
// 获取当前的OGL渲染环境实例
HGLRC oglCotent = wglGetCurrentContext();
// 获取当前的设备环境句柄,在窗口系统登记
HDC deviceDC = wglGetCurrentDC();
// 将OGL渲染实例和设备句柄关联
wglMakeCurrent(deviceDC, oglCotent);
/*
OGL实例初始化:线程,OGL线程只对应一个当前活动的OGL实例,多个OGL实例可以非同时的访问同一个表面(设备表面)。
控制渲染过程:管理或查询,释放OGL环境:管理OGL实例创建。
FB缓冲区(颜色,辅助,深度,模板)配置,交换前后台缓冲。
离屏渲染aglSetOffScreen,全屏渲染aglSetFullScreen。
清理可绘图表面,glXDesctoryWindow().
系统字体显示列表(位图,或轮廓纹理字体).
寻找颜色调色板,把特定的颜色索引平面映射到物理调色板。
同步执行,事件发起请求后会调用glXWaitGL,glFinish,让事件完成后,才继续执行图形渲染。
事件处理:请求接收和查询OGL事件,鼠标,键盘,窗口变化display事件,重新绘制事件,调整窗口大小,
事件绘制在glWait事件处理完才继续渲染图形。
访问依赖于OGL实现的函数(特别是新特性的拓展函数):
char* strFunc = glGetString();
PROC func = (PROC)wglGetProcAddress(strFunc);//通过统一的函数指针接口实现函数查询
*/
// 同一个渲染线程中只有一个活动的OGL渲染环境实例,所以这里创建会失败,每个绘图窗口都会关联一个渲染实例。
// 多个OGL实例可以非同时的访问同一个表面(设备表面)。一般同一个app用一个OGL渲染环境对象。
/*HDC oglCotenObj;
HGLRC hgl = wglCreateContext(oglCotenObj);*/
// 获取当前的OGL渲染环境实例
HGLRC oglCotent = wglGetCurrentContext();
// 获取当前的设备环境句柄,在窗口系统登记
HDC deviceDC = wglGetCurrentDC();
// 将OGL渲染实例和设备句柄关联
wglMakeCurrent(deviceDC, oglCotent);
二、freeglut配置
需要windows上编译用CMake freegult即可。
// 绘制的东西都在全局坐标的原点,世界坐标的原点,也就是世界坐标原点是转换到屏幕中心的
glutSolidCube(1.0);
//使用上面的头文件是不行的,需要GLUT的窗口框架,win7 64只能用GL/glut.h
#include <GL/freeglut.h>
#include <stdio.h>
//设置背景颜色和坐标系统
void init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 400.0, 0.0, 550.0);
//gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
typedef struct S2DFPoint//用矩阵比用结构体或类的方式易于初始化
{
GLfloat p[2];
}TwoDFPoint;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
int point1[] = { 10, 10 };
int point2[] = { 350, 530 };
int point3[] = { 380, 40 };
int point4[] = { 160, 500 };
int point5[] = { 20, 350 };
::glBegin(GL_LINES);
::glBegin(GL_LINE_STRIP);
glBegin(GL_LINE_LOOP);
glVertex2iv(point1);
glVertex2iv(point2);
glVertex2iv(point3);
glVertex2iv(point4);
glVertex2iv(point5);
glEnd();
glBegin(GL_TRIANGLES);
glutSolidCube(1.0f);
glEnd();
glFlush();
}
void reshapeWnd(int w, int h)
{
printf("reshapeWnd, w:%d, h:%d",w, h);
}
void keyEvent(unsigned char key, int x, int y)
{
printf("keyEvent, key:%c, x:%d, y:%d", key, x, y);
}
void mouseEvent(int button, int state, int x, int y)
{
printf("mouseEvent, button:%d, state:%d, x:%d, y:%d", button, state, x, y);
}
void dragEvent(int x, int y)
{
printf("dragEvent, x:%d, y:%d", x, y);
}
void loopIdleFunc()
{
printf("loopIdle");
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
//初始化显卡模式
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(900, 550);
//指定使用的Opengl版本号
glutInitContextVersion(3, 1);
glutInitContextFlags(GLUT_CORE_PROFILE); //GLUT_COMPATIBILITY_PROFILE
glutCreateWindow("Hello OpenGL program I am Jeese!");
init();
/* glutMainLoop中每帧重绘的回调函数注册,如果注册了新的函数,那么需要用glutPostRedisplay()来通知glutMainLoop
使用新的回调函数。*/
glutDisplayFunc(display); // 只有
窗口或内容改变会重新绘制才调用,内部会维护每帧调用的drawcall
glutReshapeFunc(reshapeWnd);
glutKeyboardFunc(keyEvent);
glutMouseFunc(mouseEvent);
glutMotionFunc(dragEvent);
glutIdleFunc(loopIdleFunc); //
没有其它事件需要处理时(鼠标键盘改变窗口重绘事件),处理连续动画和背景过程很有用。
glutMainLoop();// 主循环,处理各种事件或绘制
}
//#include <GL/glut.h>
本来OpenGL程序一般还要包含<GL/gl.h>和<GL/glu.h>,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含。
//#pragma comment(lib,"opengl32.lib")
//#pragma comment(lib, "glu32.lib")
//#pragma comment(lib, "glut32.lib")
//
//void myDisplay(void)
//{
// glClear(GL_COLOR_BUFFER_BIT);
// glColor3f(1, 0, 0);
// glRectf(-0.3f, -0.3f, 0.3f, 0.3f);
// glColor3f(0, 1, 0);
// glRectf(-0.3f, -0.5f, 0.3f, -0.3f);
// glFlush();
//}
//int main(int argc, char *argv[])
//{
// glutInit(&argc, argv);
// // GLUT_RGB表示使用RGB颜色,GLUT_INDEX(表示使用索引颜色)
// // GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)
// glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
// glutInitWindowPosition(100, 100);
// glutInitWindowSize(960, 640);
// glutCreateWindow("第一个OpenGL程序");
// // 设置绘制回调函数
// glutDisplayFunc(&myDisplay);
// // 启动整个Opengl状态机,进入绘制
// glutMainLoop();
// return 0;
//}