OpenGL 基础
如果对动态链接库、静态链接库、头文件等C++知识有比较熟悉的了解,就不难上手。OpenGL有五个文件,一个头文件、两个动态链接库、两个静态链接库;
动态链接库放在windows/system32 或者是SOW64这个文件夹下
头文件放在/VC/include/GL 文件夹下,如果没有就自己动手创建。
静态链接库放在与include 文件夹同级目录的lib文件夹下,这样基本的环境就配置好了。
编写程序时,需要包含头文件 即:#include <gl\glut.h>
下面言归正传,说一下OpenGL基础入门知识,有些知识自己也是模糊不清,所以以下所写也未必正确:
OpenGL是跨平台的,因此不能调用windows API创建窗体,而是使用自己的方法创建窗体,(可能不对???)
1、首先是初始化OpenGL
glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); //双缓冲 rgb颜色模式 深度模式
第一句中的两个参数是main函数入口的两个参数,第一个表示字符串的个数,第二个是字符串指针
2、接下来就是创建OpenGL 窗体

// Create the window glutInitWindowSize(1024, 768); glutInitWindowPosition(100, 150); glutCreateWindow("BOGLGP Chapter 1"); //窗口标题
3、接下来就应该是绘图场景的初始化(这块就不太确定了是不是这个意思)

void Initialize() { // set up the only meny int mainMenu; mainMenu = glutCreateMenu(MainMenuHandler); glutSetMenu(mainMenu); glutAddMenuEntry("Exit", 0); glutAttachMenu(GLUT_RIGHT_BUTTON); glEnable(GL_DEPTH_TEST); } // end void MainMenuHandler(int option) //参数目前不明白是什么意思 { switch (option) { case 0: { exit(0); } break; default: break; } glutPostRedisplay(); } // end MainMenuHandler()
4、接下来就是绘图工作

glutDisplayFunc(Display); //其中 Display函数时绘图函数 如下: void Display() { // set up the camera glLoadIdentity(); gluLookAt(0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw a triangle glBegin(GL_TRIANGLES); glColor3f(0.0, 0.0, 0.0); glVertex3f(2.0, 2.5, -1.0); glColor3f(0.0, 1.0, 0.0); glVertex3f(-3.5, -2.5, -1.0); glColor3f(1.0, 1.0, 1.0); glVertex3f(2.0, -4.0, 0.0); glEnd(); // draw a polygon glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); glVertex3f(-1.0, 2.0, 0.0); glColor3f(1.0, 1.0, 0.0); glVertex3f(-3.0, -0.5, 0.0); glColor3f(0.0, 1.0, 1.0); glVertex3f(-1.5, -3.0, 0.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -2.0, 0.0); glColor3f(1.0, 0.0, 1.0); glVertex3f(1.0, 1.0, 0.0); glEnd(); // draw everything and swap the display buffer glutSwapBuffers(); } // end Display()
在这里解释一下glutSwapBuffers();函数,首先说明一下双缓冲机制:就是说设置两个内存缓冲区,前台缓冲、后台缓冲;屏幕显示的数据是从前台缓冲获取的,然而图的绘制工作是在后台缓冲进行的,绘制完成后再传递给前台缓冲,这样给用户的感觉就是同时绘制的。这个函数的作用就是交换两个缓冲区的指针。
5、接下来就是当窗体改变是 程序应该做什么
glutReshapeFunc(Reshape); void Reshape(int width, int height) { if (height == 0) return; //定义视口矩形区域 默认的视口区域与窗口大小相同当为了选择一个更小的绘图区域时可以调用此函数 也可以利用此函数实现一个窗口内多个视口 glViewport(0, 0, (GLsizei)width, (GLsizei)height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.0, width / height, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); } // end Reshape
6、之后是设置鼠标、键盘的一些输入 在此就不提了
下面解释以下函数:
glutPostRedisplay();
此函数是标记当前窗口需要重新绘制,当通过glutMainLoop进行下一次循环时就会重新绘制;
glutMainLoop();
这个函数时使得一个OpenGL程序进入无限的事件循环,一个程序中这个方法被调用一次,并且不会有返回值,直到程序结束。
gluPerspective();
函数原型:
第一个程序就分析到这儿了,下面附上完整的源代码

#include<stdlib.h> #include <gl\glut.h> void Initialize(); void MouseHandler(int button, int state, int x, int y); void KeyboardHandler(unsigned char key, int x, int y); void MainMenuHandler(int option); void Animate(); void Reshape(int width, int height); void Display(); /**************************************************************************** main() Setup GLUT and OpenGL, drop into the event loop *****************************************************************************/ int main(int argc, char **argv) { // Setup the basic GLUT stuff glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Create the window glutInitWindowSize(1024, 768); glutInitWindowPosition(100, 150); glutCreateWindow("BOGLGP Chapter 1"); Initialize(); // Register the event callback functions glutDisplayFunc(Display); glutReshapeFunc(Reshape); glutMouseFunc(MouseHandler); glutKeyboardFunc(KeyboardHandler); glutIdleFunc(Animate); // At this point, control is relinquished to the GLUT event handler. // Control is returned as events occur, via the callback functions. glutMainLoop(); return 0; } // end main() /**************************************************************************** Initialize() One time setup, including creating menus, creating a light, setting the shading mode and clear color, and loading textures. *****************************************************************************/ void Initialize() { // set up the only meny int mainMenu; mainMenu = glutCreateMenu(MainMenuHandler); glutSetMenu(mainMenu); glutAddMenuEntry("Exit", 0); glutAttachMenu(GLUT_RIGHT_BUTTON); glEnable(GL_DEPTH_TEST); } // end Initialize() /**************************************************************************** MouseHandler() Handle mouse events. For this simple demo, just exit on a left click. *****************************************************************************/ void MouseHandler(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: { exit(0); } break; default: break; } // force a screen redraw glutPostRedisplay(); } // end MouseHandler() /**************************************************************************** KeyboardHandler() Keyboard handler. Again, we'll just exit when q is pressed. *****************************************************************************/ void KeyboardHandler(unsigned char key, int x, int y) { switch (key) { case 'q': // exit { exit(0); } break; default: { } break; } glutPostRedisplay(); } // end KeyboardHandler() /**************************************************************************** MainMenuHandler() Main menu callback. *****************************************************************************/ void MainMenuHandler(int option) { switch (option) { case 0: { exit(0); } break; default: break; } glutPostRedisplay(); } // end MainMenuHandler() /**************************************************************************** Animate() Rotate the cube by 4 degrees and force a redisplay. *****************************************************************************/ void Animate() { glutPostRedisplay(); } // end Animate() /**************************************************************************** Reshape() Reset the viewport for window changes *****************************************************************************/ void Reshape(int width, int height) { if (height == 0) return; glViewport(0, 0, (GLsizei)width, (GLsizei)height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.0, width / height, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); } // end Reshape /**************************************************************************** Display() Clear and redraw the scene. *****************************************************************************/ void Display() { // set up the camera glLoadIdentity(); gluLookAt(0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw a triangle glBegin(GL_TRIANGLES); glColor3f(0.0, 0.0, 0.0); glVertex3f(2.0, 2.5, -1.0); glColor3f(0.0, 1.0, 0.0); glVertex3f(-3.5, -2.5, -1.0); glColor3f(1.0, 1.0, 1.0); glVertex3f(2.0, -4.0, 0.0); glEnd(); // draw a polygon glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); glVertex3f(-1.0, 2.0, 0.0); glColor3f(1.0, 1.0, 0.0); glVertex3f(-3.0, -0.5, 0.0); glColor3f(0.0, 1.0, 1.0); glVertex3f(-1.5, -3.0, 0.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -2.0, 0.0); glColor3f(1.0, 0.0, 1.0); glVertex3f(1.0, 1.0, 0.0); glEnd(); // draw everything and swap the display buffer glutSwapBuffers(); } // end Display()