zoukankan      html  css  js  c++  java
  • OpenGL8-直接分配显存-极速绘制(2)

    视频教程请关注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440
    /**
    * OpenGL8-直接分配显存-极速绘制(Opengl1.5版本才有)例子中展示了如何直接
    分配显存,使用了glBindBuffer(GL_ARRAY_BUFFER_ARB, _vertexBufer)这个例
    子中同样适用该函数分配显卡缓冲区,只是参数有所变化,传递的参数如下所示
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, _element),这样讲影响到
    glDrawElements函数,将缓冲区作为该参数的数据输入数据处理。
    从而提高绘制效率。

    */


    #include "CELLWinApp.hpp"
    #include <gl/GLU.h>
    #include <assert.h>
    #include <math.h>
    #pragma comment(lib,"opengl32.lib")
    #pragma comment(lib,"winmm.lib")

    struct Vertex
    {
    float r, g, b;
    float x, y, z;
    };

    /**
    * 一个立方体有8个顶点
    */

    Vertex g_cubeVertices_indexed[] =
    {
    { 1.0f,0.0f,0.0f, -1.0f,-1.0f, 1.0f }, // 0
    { 0.0f,1.0f,0.0f, 1.0f,-1.0f, 1.0f }, // 1
    { 0.0f,0.0f,1.0f, 1.0f, 1.0f, 1.0f }, // 2
    { 1.0f,1.0f,0.0f, -1.0f, 1.0f, 1.0f }, // 3
    { 1.0f,0.0f,1.0f, -1.0f,-1.0f,-1.0f }, // 4
    { 0.0f,1.0f,1.0f, -1.0f, 1.0f,-1.0f }, // 5
    { 1.0f,1.0f,1.0f, 1.0f, 1.0f,-1.0f }, // 6
    { 1.0f,0.0f,0.0f, 1.0f,-1.0f,-1.0f }, // 7
    };


    /**
    * 对应的索引数据
    */

    GLubyte g_cubeIndices[] =
    {
    0, 1, 2, 3, // Quad 0
    4, 5, 6, 7, // Quad 1
    5, 3, 2, 6, // Quad 2
    4, 7, 1, 0, // Quad 3
    7, 6, 2, 1, // Quad 4
    4, 0, 3, 5 // Quad 5
    };

    class Tutorial8_2 :public CELL::Graphy::CELLWinApp
    {
    public:
    Tutorial8_2(HINSTANCE hInstance)
    :CELL::Graphy::CELLWinApp(hInstance)
    {
    _lbtnDownFlag = false;
    _fSpinY = 0;
    _fSpinX = 0;
    }
    virtual void render()
    {
    do
    {
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);


    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0.0f, 0.0f, -5.0f );

    glRotatef( -_fSpinY, 1.0f, 0.0f, 0.0f );
    glRotatef( -_fSpinX, 0.0f, 1.0f, 0.0f );

    glBindBuffer(GL_ARRAY_BUFFER_ARB,_vertexBufObj);

    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_COLOR_ARRAY );

    //--------------元素个数---元素类型---元素之间的内存偏移---数据地址
    //OpenGL根据元素之间的内存偏移来计算下一个元素的位置。
    glVertexPointer( 3, GL_FLOAT, sizeof(Vertex),(void*)12);
    glColorPointer( 3, GL_FLOAT, sizeof(Vertex), 0);

    /**
    * 使用索引绘制
    */
    //-------------绘制图元的类型,索引的数量, 索引的数据格式, 索引数据内存地址给0
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,_elementBufObj);
    glDrawElements( GL_QUADS, 24, GL_UNSIGNED_BYTE, 0 );


    glDisableClientState( GL_VERTEX_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );


    SwapBuffers( _hDC );
    } while (false);
    }

    /**
    * 生成投影矩阵
    * 后面为了重用性,我们会写一个专门的matrix类,完成矩阵的一系列擦做
    * 这个是很有必须要的,当你对Opengl了解的不断深入,你会发现,很多都是和数学有关的
    */
    void perspective(float fovy,float aspect,float zNear,float zFar,float matrix[4][4])
    {
    assert(aspect != float(0));
    assert(zFar != zNear);
    #define PI 3.14159265358979323f

    float rad = fovy * (PI / 180);

    float halfFovy = tan(rad / float(2));
    matrix[0][0] = float(1) / (aspect * halfFovy);
    matrix[1][1] = float(1) / (halfFovy);
    matrix[2][2] = -(zFar + zNear) / (zFar - zNear);
    matrix[2][3] = -float(1);
    matrix[3][2] = -(float(2) * zFar * zNear) / (zFar - zNear);
    #undef PI
    }
    virtual void onInit()
    {
    /**
    * 调用父类的函数。
    */
    CELL::Graphy::CELLWinApp::onInit();

    glMatrixMode( GL_PROJECTION );

    GLfloat matrix[4][4] =
    {
    0,0,0,0,
    0,0,0,0,
    0,0,0,0,
    0,0,0,0
    };
    perspective(45.0f, (GLfloat)_winWidth / (GLfloat)_winHeight, 0.1f, 100.0f,matrix);
    glLoadMatrixf((float*)matrix);

    glClearColor(0,0,0,1);

    /**
    * 增加如下两句话
    * glEnable(GL_DEPTH_TEST); 启动深度测试,这样,有遮挡计算,被遮盖的将覆盖
    */
    glEnable(GL_DEPTH_TEST);

    /**
    * 初始化扩展库
    */
    glewInit();

    glGenBuffers(1,&_vertexBufObj);
    glBindBuffer(GL_ARRAY_BUFFER_ARB,_vertexBufObj);
    glBufferData(GL_ARRAY_BUFFER_ARB,sizeof(g_cubeVertices_indexed),g_cubeVertices_indexed,GL_STREAM_DRAW_ARB);
    glBindBuffer(GL_ARRAY_BUFFER_ARB,0);


    /**
    * 索引缓冲区
    */
    glGenBuffers(1,&_elementBufObj);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,_elementBufObj);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB,sizeof(g_cubeIndices),g_cubeIndices,GL_STREAM_DRAW_ARB);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);

    }

    virtual int events(unsigned msg, unsigned wParam, unsigned lParam)
    {
    switch(msg)
    {
    case WM_LBUTTONDOWN:
    {
    _mousePos.x = LOWORD (lParam);
    _mousePos.y = HIWORD (lParam);
    _lbtnDownFlag = true;
    SetCapture(_hWnd);
    }
    break;
    case WM_LBUTTONUP:
    {
    _lbtnDownFlag = false;
    ReleaseCapture();
    }
    break;
    case WM_MOUSEMOVE:
    {
    int curX = LOWORD (lParam);
    int curY = HIWORD (lParam);

    if( _lbtnDownFlag )
    {
    _fSpinX -= (curX - _mousePos.x);
    _fSpinY -= (curY - _mousePos.y);
    }

    _mousePos.x = curX;
    _mousePos.y = curY;
    }
    break;
    }
    return __super::events(msg,wParam,lParam);
    }
    protected:

    float _fSpinX ;
    float _fSpinY;
    POINT _mousePos;
    bool _lbtnDownFlag;
    /**
    * 存储定点使用的缓冲区
    */
    unsigned _vertexBufObj;
    /**
    * 存储索引使用的缓冲区
    */
    unsigned _elementBufObj;
    };

    int CALLBACK _tWinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine,
    int nShowCmd
    )
    {
    (void*)hInstance;
    (void*)hPrevInstance;
    (void*)lpCmdLine;
    (void*)nShowCmd;

    Tutorial8_2 winApp(hInstance);
    winApp.start(640,480);
    return 0;
    }

    例程的代码和可执行程序

  • 相关阅读:
    CShop Project 082: 获取分页数据模型并传递到页面上
    CShop Project 08: 展示不同类型的商品
    CShop Project 08: 开发商品分类的查询和展示
    119 类和数据类型
    118 对象的绑定方法
    117 对象的属性查找顺序
    116 定制对象独有特征
    115 类和对象
    114 面向对象编程介绍
    113 面向对象程序设计的由来(了解)
  • 原文地址:https://www.cnblogs.com/zhanglitong/p/3199021.html
Copyright © 2011-2022 走看看