OpenGL7-2-快速绘制   
               添加时间:2013-7-16 点击量: 
 
              
#include CELLWinApp.hpp
#include <gl/GLU.h>
#include <assert.h>
#include <math.h>
#pragma comment(lib,opengl32.lib)
#pragma comment(lib,glu32.lib)
#pragma comment(lib,winmm.lib)
/
   这个例子介绍如何应用 
    glEnableClientState,
    glVertexPointer.
    glColorPointer,
    glTexCoordPointer,
    glDrawArrays
    函数进行绘制
    接上一个例子,上一个例子中应用了三个缓冲区,定点缓冲区,纹理缓冲区,色彩缓冲
       缓冲区多了今后灵活度增长了,然则经管却很麻烦。
    OpenGL也支撑一个零丁的缓冲区
/
struct Vertex
{
    float x, y, z;
    float u,v;
    float r, g, b;
};
Vertex g_cubeVertices[] =
{
    { -1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 0.0f },
    {  1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 0.0f, 0.0f },
    {  1.0f, 1.0f, 1.0f,1.0f, 1.0f,1.0f, 0.0f, 0.0f },
    { -1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 0.0f },
    { -1.0f,-1.0f,-1.0f,1.0f, 0.0f,0.0f, 1.0f, 0.0f },
    { -1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 1.0f, 0.0f },
    {  1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 0.0f },
    { -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 0.0f, 1.0f },
    { -1.0f, 1.0f, 1.0f,0.0f, 0.0f,0.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f, 1.0f,1.0f, 0.0f,0.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 0.0f, 1.0f },
    { -1.0f,-1.0f,-1.0f,1.0f, 1.0f,1.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f,-1.0f,0.0f, 1.0f,1.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 1.0f, 0.0f },
    { -1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f,-1.0f,1.0f, 0.0f,1.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f,-1.0f,1.0f, 1.0f,1.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 1.0f },
    {  1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 1.0f },
    { -1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 1.0f },
    { -1.0f,-1.0f, 1.0f,1.0f, 0.0f,0.0f, 1.0f, 1.0f },
    { -1.0f, 1.0f, 1.0f,1.0f, 1.0f,0.0f, 1.0f, 1.0f },
    { -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 1.0f }
};
class   Tutorial7 :public  CELL::Graphy::CELLWinApp
{
public:
    Tutorial7(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 );
            glEnableClientState( GL_VERTEX_ARRAY );
            glEnableClientState( GL_COLOR_ARRAY );
            glEnableClientState( GL_TEXTURE_COORD_ARRAY );
            /
               这里大师可以慢慢领会
            /
            float   addrVertex     =   (float)g_cubeVertices;
            float   uvAddress      =   (float)&g_cubeVertices[0].u;
            float   colorAddress   =   (float)&g_cubeVertices[0].r;
            //--------------元素个数---元素类型---元素之间的内存偏移---数据地址
            //OpenGL按照元素之间的内存偏移来策画下一个元素的地位。
            glVertexPointer( 3,         GL_FLOAT, sizeof(Vertex),   addrVertex );
            glColorPointer( 3, GL_FLOAT, sizeof(Vertex),  colorAddress);
            glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), uvAddress );
            glDrawArrays( GL_QUADS, 0, 24 );
            glDisableClientState( GL_VERTEX_ARRAY );
            glDisableClientState( GL_COLOR_ARRAY );
            glDisableClientState( GL_TEXTURE_COORD_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_TEXTURE_2D); 启动纹理,支撑纹理贴图,如许才可以绘制纹理出来
        /
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
        /
           读一个bmp
        /
        HBITMAP hBmp    =   (HBITMAP)LoadImageA(0,1.bmp,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
        /
           获取的大小
        /
        BITMAP bmpInf = {0};
        GetObject(hBmp,sizeof(bmpInf),&bmpInf);
        /
           获取的色彩数据(r,g,b)
        /
        int     size    =   bmpInf.bmHeight  bmpInf.bmWidth  3;
        char   data    =   new char[size];
        BITMAPINFO bi;   
        bi.bmiHeader.biSize     =   sizeof(bi.bmiHeader);   
        bi.bmiHeader.biWidth    =   bmpInf.bmWidth;   
        bi.bmiHeader.biHeight   =   bmpInf.bmHeight;   
        bi.bmiHeader.biPlanes   =   1;   
        bi.bmiHeader.biBitCount =   24;    
        bi.bmiHeader.biCompression  =   BI_RGB;    
        bi.bmiHeader.biSizeImage    =   size; 
        bi.bmiHeader.biClrUsed      =   0;   
        bi.bmiHeader.biClrImportant =   0;   
      
        /
           获取rgb数据
        /
        int idata = GetDIBits(_hDC,hBmp,0,bi.bmiHeader.biHeight,data,&bi,DIB_RGB_COLORS);
        /
           产生一个纹理Id,可以认为是纹理句柄,后面的操纵将书用这个纹理id
        /
        glGenTextures( 1, &_textureId );
        /
           应用这个纹理id,或者叫绑定(接洽关系)
        /
        glBindTexture( GL_TEXTURE_2D, _textureId );
        /
           指定纹理的放大,缩小滤波,应用线性体式格式,即当放大的时辰插值体式格式 
        /
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        /
           将的rgb数据上传给opengl.
        /
        glTexImage2D( 
            GL_TEXTURE_2D,      //! 指定是二维
            0,                  //! 指定为第一级别,纹理可以做mipmap,即lod,离近的就采取级别大的,远则应用较小的纹理
            GL_RGB,             //! 纹理的应用的存储格局
            bmpInf.bmWidth,     //! 宽度,老一点的显卡,不支撑不规矩的纹理,即宽度和高度不是2^n。
            bmpInf.bmHeight,    //! 宽度,老一点的显卡,不支撑不规矩的纹理,即宽度和高度不是2^n。
            0,                  //! 是否的边
            GL_BGR_EXT,         //! 数据的格局,bmp中,windows,操纵体系中存储的数据是bgr格局
            GL_UNSIGNED_BYTE,   //! 数据是8bit数据
            data
            );
         []data;
        /
           删除
        /
        DeleteObject(hBmp);
        
    }
    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:
    unsigned    _primitiveType;
    /
       保存纹理Id
    /
    unsigned    _textureId;
    float       _fSpinX ;
    float       _fSpinY;
    POINT       _mousePos;
    bool        _lbtnDownFlag;
};
int CALLBACK _tWinMain(
                       HINSTANCE hInstance, 
                       HINSTANCE hPrevInstance, 
                       LPTSTR lpCmdLine, 
                       int nShowCmd 
                       )
{
    (void)hInstance;
    (void)hPrevInstance;
    (void)lpCmdLine;
    (void)nShowCmd;
    Tutorial7 winApp(hInstance);
    winApp.start(640,480);
    return  0;
}
无论对感情还是对生活,“只要甜不要苦”都是任性而孩子气的,因为我们也不完美,我们也会伤害人。正因为我们都不完美,也因为生活从不是事事如意,所以对这些“瑕疵”的收纳才让我们对生活、对他人的爱变得日益真实而具体。—— 汪冰《世界再亏欠你,也要敢于拥抱幸福》
                     
                  
     
  
 
    
    

#include CELLWinApp.hpp
#include <gl/GLU.h>
#include <assert.h>
#include <math.h>
#pragma comment(lib,opengl32.lib)
#pragma comment(lib,glu32.lib)
#pragma comment(lib,winmm.lib)
/
   这个例子介绍如何应用 
    glEnableClientState,
    glVertexPointer.
    glColorPointer,
    glTexCoordPointer,
    glDrawArrays
    函数进行绘制
    接上一个例子,上一个例子中应用了三个缓冲区,定点缓冲区,纹理缓冲区,色彩缓冲
       缓冲区多了今后灵活度增长了,然则经管却很麻烦。
    OpenGL也支撑一个零丁的缓冲区
/
struct Vertex
{
    float x, y, z;
    float u,v;
    float r, g, b;
};
Vertex g_cubeVertices[] =
{
    { -1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 0.0f },
    {  1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 0.0f, 0.0f },
    {  1.0f, 1.0f, 1.0f,1.0f, 1.0f,1.0f, 0.0f, 0.0f },
    { -1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 0.0f },
    { -1.0f,-1.0f,-1.0f,1.0f, 0.0f,0.0f, 1.0f, 0.0f },
    { -1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 1.0f, 0.0f },
    {  1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 0.0f },
    { -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 0.0f, 1.0f },
    { -1.0f, 1.0f, 1.0f,0.0f, 0.0f,0.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f, 1.0f,1.0f, 0.0f,0.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 0.0f, 1.0f },
    { -1.0f,-1.0f,-1.0f,1.0f, 1.0f,1.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f,-1.0f,0.0f, 1.0f,1.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 1.0f, 0.0f },
    { -1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 1.0f, 0.0f },
    {  1.0f,-1.0f,-1.0f,1.0f, 0.0f,1.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f,-1.0f,1.0f, 1.0f,1.0f, 0.0f, 1.0f },
    {  1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 1.0f },
    {  1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 1.0f },
    { -1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 1.0f },
    { -1.0f,-1.0f, 1.0f,1.0f, 0.0f,0.0f, 1.0f, 1.0f },
    { -1.0f, 1.0f, 1.0f,1.0f, 1.0f,0.0f, 1.0f, 1.0f },
    { -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 1.0f }
};
class   Tutorial7 :public  CELL::Graphy::CELLWinApp
{
public:
    Tutorial7(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 );
            glEnableClientState( GL_VERTEX_ARRAY );
            glEnableClientState( GL_COLOR_ARRAY );
            glEnableClientState( GL_TEXTURE_COORD_ARRAY );
            /
               这里大师可以慢慢领会
            /
            float   addrVertex     =   (float)g_cubeVertices;
            float   uvAddress      =   (float)&g_cubeVertices[0].u;
float colorAddress = (float)&g_cubeVertices[0].r;
            //--------------元素个数---元素类型---元素之间的内存偏移---数据地址
            //OpenGL按照元素之间的内存偏移来策画下一个元素的地位。
            glVertexPointer( 3,         GL_FLOAT, sizeof(Vertex),   addrVertex );
            glColorPointer( 3, GL_FLOAT, sizeof(Vertex),  colorAddress);
            glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), uvAddress );
glDrawArrays( GL_QUADS, 0, 24 );
            glDisableClientState( GL_VERTEX_ARRAY );
            glDisableClientState( GL_COLOR_ARRAY );
            glDisableClientState( GL_TEXTURE_COORD_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_TEXTURE_2D); 启动纹理,支撑纹理贴图,如许才可以绘制纹理出来
        /
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
        /
           读一个bmp
        /
        HBITMAP hBmp    =   (HBITMAP)LoadImageA(0,1.bmp,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
        /
           获取的大小
        /
        BITMAP bmpInf = {0};
        GetObject(hBmp,sizeof(bmpInf),&bmpInf);
        /
           获取的色彩数据(r,g,b)
        /
        int     size    =   bmpInf.bmHeight  bmpInf.bmWidth  3;
        char   data    =   new char[size];
        BITMAPINFO bi;   
        bi.bmiHeader.biSize     =   sizeof(bi.bmiHeader);   
        bi.bmiHeader.biWidth    =   bmpInf.bmWidth;   
        bi.bmiHeader.biHeight   =   bmpInf.bmHeight;   
        bi.bmiHeader.biPlanes   =   1;   
        bi.bmiHeader.biBitCount =   24;    
        bi.bmiHeader.biCompression  =   BI_RGB;    
        bi.bmiHeader.biSizeImage    =   size; 
        bi.bmiHeader.biClrUsed      =   0;   
        bi.bmiHeader.biClrImportant =   0;   
      
        /
           获取rgb数据
        /
        int idata = GetDIBits(_hDC,hBmp,0,bi.bmiHeader.biHeight,data,&bi,DIB_RGB_COLORS);
        /
           产生一个纹理Id,可以认为是纹理句柄,后面的操纵将书用这个纹理id
        /
        glGenTextures( 1, &_textureId );
        /
           应用这个纹理id,或者叫绑定(接洽关系)
        /
        glBindTexture( GL_TEXTURE_2D, _textureId );
        /
           指定纹理的放大,缩小滤波,应用线性体式格式,即当放大的时辰插值体式格式 
        /
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        /
           将的rgb数据上传给opengl.
        /
        glTexImage2D( 
            GL_TEXTURE_2D,      //! 指定是二维
            0,                  //! 指定为第一级别,纹理可以做mipmap,即lod,离近的就采取级别大的,远则应用较小的纹理
            GL_RGB,             //! 纹理的应用的存储格局
            bmpInf.bmWidth,     //! 宽度,老一点的显卡,不支撑不规矩的纹理,即宽度和高度不是2^n。
            bmpInf.bmHeight,    //! 宽度,老一点的显卡,不支撑不规矩的纹理,即宽度和高度不是2^n。
            0,                  //! 是否的边
            GL_BGR_EXT,         //! 数据的格局,bmp中,windows,操纵体系中存储的数据是bgr格局
            GL_UNSIGNED_BYTE,   //! 数据是8bit数据
            data
            );
         []data;
        /
           删除
        /
        DeleteObject(hBmp);
        
    }
    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:
    unsigned    _primitiveType;
    /
       保存纹理Id
    /
    unsigned    _textureId;
    float       _fSpinX ;
    float       _fSpinY;
    POINT       _mousePos;
    bool        _lbtnDownFlag;
};
int CALLBACK _tWinMain(
                       HINSTANCE hInstance, 
                       HINSTANCE hPrevInstance, 
                       LPTSTR lpCmdLine, 
                       int nShowCmd 
                       )
{
    (void)hInstance;
    (void)hPrevInstance;
    (void)lpCmdLine;
    (void)nShowCmd;
    Tutorial7 winApp(hInstance);
    winApp.start(640,480);
    return  0;
}




