CR的代码文本

all for learning about the world
  订阅 订阅  :: 管理

用GLUT库开始玩儿OpenGL

Posted on 2011-06-20 14:41  mumuliang  阅读(2454)  评论(0编辑  收藏  举报

《OpenGL2.0精髓》第一章的sample

 

1.引用的库包括:glut.lib glu.lib opengl.lib

2.可能会报一个exit(0)重定义的错。需要在c/c++预处理器中增加定义GLUT_BUILDING_LIB

error C2381: 'exit' : redefinition; __declspec(noreturn) differs 

 

// OPENGL头文件
#include <GL/glut.h>
#include 
<GL/glu.h>
#include 
<GL/gl.h>

#include 
<string>
#include 
<sstream>
#include 
<assert.h>
#define _USE_MATH_DEFINES
#include 
<math.h>

//////////////////////////////////////////////////////////////////////////
// 关于GLUT的部分
//////////////////////////////////////////////////////////////////////////


// 窗口参数
const int gWinWidth = 1024;
const int gWinHeight = 768;
const char* gWinTitile = "glut beginning!";
float eye_z;  // 视点和原点位置的z差

// “退出”菜单ID
static const int QUIT_VALUE = 99;
// 显示列表ID
GLuint listID;
// VBO ID
GLuint vboID;

// 重要回调1:显示回调,GLUT调用它完成重绘。
static void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    
// 将模型矩阵往后退4f,即向屏幕里移动4f
    glLoadIdentity();
    glTranslatef(
0.f,0.f,-eye_z);

    
// 绘制显示列表的内容
    glCallList(listID);

    
// 交换缓存,即将后缓存中的内容刷新到帧缓存,
    
// 帧缓存中的内容会被显示设备即刻显示出来。
    glutSwapBuffers();

    assert(glGetError() 
== GL_NO_ERROR);
}




// 重要回调2:重塑回调。
// 在窗口size发成变化时,GLUT会调用它。类同c#中窗体的sizechanged()
static void reshape(int w, int h)
{
    
// 更新视口
    glViewport(0,0,w,h);

    
// 更新投影矩阵和屏幕纵横比
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    eye_z 
= (h/2/ atanf(M_PI*50./180.);
    gluPerspective(
50., (double)w/(double)h, 1., 10000.);

    
// 矩阵状态置为模型变换
    glMatrixMode(GL_MODELVIEW);

    assert(glGetError() 
== GL_NO_ERROR);
}

// 重要回调3:GLUT菜单回调。类同c#中menuitem::clicked()
static void mainMenuCB(int value)
{
    
if (value == QUIT_VALUE)
        exit(
0);
}

// 一些重要的初始化
static void initGLUT(void)
{
    
// 关闭抖动。
    
// 抖动是色位不够的时候用较少的颜色来模拟缺少的颜色的一种方法
    glDisable(GL_DITHER);

    
// 获得GL版本
    
// getGetString()
    std::string ver((const char*) glGetString(GL_VERSION));
    assert(
!ver.empty());
    std::istringstream verStream(ver);

    
// 分解版本号,major.minor.xx, 最后的xx没有取出
    int major, minor ;
    
char dummySep;
    verStream 
>> major >> dummySep >> minor;

    
// 即OpenGL1.1以上才支持定点数组,但原先的判断方法貌似有问题
    
//const bool useVertexArrays = ( (major >= 1) && (minor >= 1) );  //原先的
    const bool useVertexArrays =  ((major*10+minor) >= 11);
    
//// 1.5以上支持缓存对象
    //const bool useBufferObjects =  ((major*10+minor) >= 15);

    
const GLfloat data[] = {
        
-100.f, -100.f, 0.f,
        
100.f, -100.f, 0.f,
        
0.f, 100.f, 0.f};

    
const GLfloat color[] = {
        
1.f, 1.f, 0.f, 1.f,
        
1.f, 0.f, 0.f, 1.f,
        
0.f, 1.f, 0.f, 1.f};

    
// 使用顶点数组
    if (useVertexArrays)
    {
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(
3, GL_FLOAT, 0, data);
        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(
4, GL_FLOAT, 0, color);
        
//glNormalPointer()
        
//glTexCoordPointer()
    }

    
// 创建显示列表ID
    listID = glGenLists(1);
    
// 编译显示列表
    
//(即从这里开始到glEndList为止的gl代码都会被编译成一系列指令直接存储在GPU的显存内)
    glNewList(listID, GL_COMPILE);

    
if (useVertexArrays)
    {
        glDrawArrays(GL_TRIANGLES, 
03);
    }
    
else
    {
        glBegin( GL_TRIANGLES );
        glColor4fv(
&color[0]);
        glVertex3fv( 
&data[0] );
        glColor4fv(
&color[4]);
        glVertex3fv( 
&data[3] );
        glColor4fv(
&color[8]);
        glVertex3fv( 
&data[6] );
        glEnd();
    }
    
// 显示列表结束
    glEndList();



    assert(glGetError() 
== GL_NO_ERROR);

    
// 绑定显示回调和重塑回调
    
// Tips: F12转到定义查看更多GLUT回调
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    
// 创建右键菜单,参数是回调函数
    int mainMenu = glutCreateMenu(mainMenuCB);
    glutAddMenuEntry(
"退出", QUIT_VALUE);
    glutAttachMenu(GLUT_RIGHT_BUTTON);

}


//////////////////////////////////////////////////////////////////////////
// 程序入口
//////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
    
// 1.glutInit
    glutInit(&argc, argv);

    
// 2.创建GLUT窗口
    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
    glutInitWindowSize(gWinWidth,gWinHeight);
    glutCreateWindow(gWinTitile);

    
// 3.一系列对glut的初始化工作
    initGLUT();

    
// 4.开始仿真循环
    glutMainLoop();

    
return 0;