zoukankan      html  css  js  c++  java
  • 用GLUT库开始玩儿OpenGL

    《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;

  • 相关阅读:
    前端多媒体(7)—— 在浏览器中实现rtmp推流
    Canvas drawImage
    png8 png24 png32
    前端多媒体(6)—— 视音频编解码技术基础
    Meta viewport 学习整理
    前端多媒体(5)—— 图片滤镜的实现
    前端多媒体(4)—— video标签全面分析
    前端多媒体(3)—— 处理二进制数据
    前端多媒体(2)—— xhr异步接收处理二进制数据
    babel-runtime 和 babel-polyfill
  • 原文地址:https://www.cnblogs.com/mumuliang/p/2085227.html
Copyright © 2011-2022 走看看