纹理 2D

来源:互联网 发布:java mail ssl 编辑:程序博客网 时间:2024/06/06 17:47

只使用了2d的纹理,纹理贴图就是将一张图片贴到物体的表面
相关函数:

glEnable(GL_TEXTURE_2D);//开启2D纹理glBindTexture(GL_TEXTURE_2D, textures[0]);//绑定纹理,将绘制的纹理glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bmp);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexCoord2f(0, 0);

结果
所有代码: 上键调整纹理模式 T键是否打开纹理

#include <Windows.h>#include <iostream>#include <gl\GL.h>#include <gl\GLU.h>#pragma comment(lib,"opengl32.lib")//opengl相关库#pragma comment(lib,"glu32.lib")/////全局句柄HGLRC hRC;HDC hDC;HWND hWnd;/////全局句柄//全局变量long width;//纹理宽度和高度long height;unsigned char *bmp;//纹理数据GLuint textures[2];int flag_tex = 0;//纹理模式bool b_tex = true;//是否打开纹理const int NUM = 100;//圆等分程度int n = 50;//圆的顶点数GLfloat Circle_vex[NUM];//存放圆顶点void GetBmpByFilePath(char *filepath)//读取bmp位图{    FILE *file = NULL;    fopen_s(&file,filepath, "rb");    if (file == NULL) { MessageBox(NULL,"文件读取失败!","错误",MB_OK); return; }    //读取bmp头    BITMAPFILEHEADER bmpFileHead;    fread(&bmpFileHead, sizeof(BITMAPFILEHEADER), 1, file);    if (bmpFileHead.bfType != 0x4d42)  { MessageBox(NULL,"图像不是bmp格式!", "错误", MB_OK); return; }    DWORD sumNum = bmpFileHead.bfSize;//这个长度是数据长度    DWORD offNum = bmpFileHead.bfOffBits;//数据偏移头部长度    BITMAPINFOHEADER bmpInfoHead;    fread(&bmpInfoHead, sizeof(BITMAPINFOHEADER), 1, file);    if (bmpInfoHead.biCompression != 0){ MessageBox(NULL,"无法处理的bmp压缩格式!", "错误", MB_OK); return; }    if (bmpInfoHead.biBitCount != 24)    {        MessageBox(NULL, "无法处理的bmp格式!", "错误", MB_OK); return;    }    width = bmpInfoHead.biWidth;//宽度必须是4B的倍数    height = bmpInfoHead.biHeight;    width = (width*3 + 3) / 4 * 4;    height = abs(height);    bmp = new unsigned char[height*width];    fread(bmp, 1, height*width, file);    for (int j = 0; j < height; j++)//更换BGR循序为RGB    for (int i = 0; i < width; i++)    {        unsigned char b = bmp[j*width + i];        unsigned char r = bmp[j*width + i + 2];        bmp[j*width + i] = r;        bmp[j*width + i + 2] = b;        i += 2;    }    width /= 3;    fclose(file);}void MakeCircle()//计算圆的坐标并移动位置到左下角{    float ang = 6.18 / n;    int j = 0;    for (int i = 0; i < n;i++)    {        Circle_vex[j++] = sin(i*ang)/2-0.5;        Circle_vex[j++] = cos(i*ang)/2-0.5;    }}void InitGL()//初始化opengl参数{    glClearColor(0.5, 0.5, 0.5, 1);//设置颜色缓存颜色    glEnable(GL_TEXTURE_2D);//开启2D纹理    GetBmpByFilePath("opengl.bmp");//读取纹理    glGenTextures(2, textures);    glBindTexture(GL_TEXTURE_2D, textures[0]);    glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bmp);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//线性滤波    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//线性滤波    glBindTexture(GL_TEXTURE_2D, textures[1]);    glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bmp);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//线性滤波    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//线性滤波    if (bmp) free(bmp);//释放bmp内存    MakeCircle();    glEnableClientState(GL_VERTEX_ARRAY);    glVertexPointer(2, GL_FLOAT, 0, Circle_vex);    glEnableClientState(GL_TEXTURE_COORD_ARRAY);    glTexCoordPointer(2, GL_FLOAT, 0, Circle_vex);}void DrawGLScene(){    glClear(GL_COLOR_BUFFER_BIT );  // 每次刷新屏幕颜色缓存    glBindTexture(GL_TEXTURE_2D, textures[flag_tex]);//选择纹理类型    //是否使用纹理    if (b_tex) glEnable(GL_TEXTURE_2D);    else glDisable(GL_TEXTURE_2D);    //矩形    glBegin(GL_QUADS);    glTexCoord2f(0, 0); glVertex2f(0, 0);    glTexCoord2f(1, 0); glVertex2f(1, 0);    glTexCoord2f(1, 1); glVertex2f(1, 1);    glTexCoord2f(0, 1); glVertex2f(0, 1);    glEnd();    //圆形    glDrawArrays(GL_POLYGON, 0, n);}LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)// 消息处理回调函数{    switch (uMsg)                                   // Check For Windows Messages    {        case WM_ACTIVATE:                           // Watch For Window Activate Message        {            return 0;                               // Return To The Message Loop        }        case WM_SYSCOMMAND:                         // Intercept System Commands        {            switch (wParam)                         // Check System Calls            {            case SC_SCREENSAVE:                 // Screensaver Trying To Start?            case SC_MONITORPOWER:               // Monitor Trying To Enter Powersave?                return 0;                           // Prevent From Happening            }            break;                                  // Exit        }        case WM_CLOSE:                              // Did We Receive A Close Message?        {            PostQuitMessage(0);                     // Send A Quit Message            return 0;                               // Jump Back        }        case WM_KEYDOWN:                            // 按键按下 由wParam决定        {            switch (wParam)            {            case 'T':                b_tex = !b_tex;                break;            case VK_UP:                flag_tex++;                if (flag_tex == 2) flag_tex = 0;                break;            }            return 0;                               // Jump Back        }        case WM_KEYUP:                              // 按键松开        {            //z = 0;            return 0;                               // Jump Back        }        case WM_SIZE:                               // Resize The OpenGL Window        {            glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));//改变GL窗口大小            return 0;                               // Jump Back        }    }    // Pass All Unhandled Messages To DefWindowProc    return DefWindowProc(hwnd, uMsg, wParam, lParam);//默认消息回调处理函数}void KillGLWindow(){    if (hRC)                                            // 删除着色描述表    {        if (!wglMakeCurrent(NULL, NULL))                    // Are We Able To Release The DC And RC Contexts?        {            MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);        }        if (!wglDeleteContext(hRC))                     // Are We Able To Delete The RC?        {            MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);        }        hRC = NULL;                                     // Set RC To NULL    }    if (hDC && !ReleaseDC(hWnd, hDC))                   // 释放DC    {        MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);        hDC = NULL;                                     // Set DC To NULL    }    if (hWnd && !DestroyWindow(hWnd))                   // Are We Able To Destroy The Window?    {        MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);        hWnd = NULL;                                        // Set hWnd To NULL    }}int WINAPI WinMain(HINSTANCE h,HINSTANCE,LPSTR lpCmdLine,int nCmdShow){    WNDCLASS wc;    wc.hInstance = h;    wc.hbrBackground = NULL;    wc.hCursor = LoadCursor(NULL, IDC_ARROW);    wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);    wc.lpszMenuName = NULL;    wc.lpszClassName = "OpenGL";    wc.cbClsExtra = 0;                                  // No Extra Window Data    wc.cbWndExtra = 0;    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  // Redraw On Size, And Own DC For Window.    wc.lpfnWndProc = (WNDPROC)WndProc;    RegisterClass(&wc);    hWnd = CreateWindow("OpenGL", "test", WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_BORDER | WS_MAXIMIZEBOX, 0, 0, 300, 300, NULL, NULL, h, NULL);    //opengl设定    hDC = GetDC(hWnd);    static  PIXELFORMATDESCRIPTOR pfd =             // pfd Tells Windows How We Want Things To Be    {        sizeof(PIXELFORMATDESCRIPTOR),              // Size Of This Pixel Format Descriptor        1,                                          // Version Number        PFD_DRAW_TO_WINDOW |                        // Format Must Support Window        PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL        PFD_DOUBLEBUFFER,                           // Must Support Double Buffering        PFD_TYPE_RGBA,                              // Request An RGBA Format        24,                                     // Select Our Color Depth        0, 0, 0, 0, 0, 0,                           // Color Bits Ignored        0,                                          // No Alpha Buffer        0,                                          // Shift Bit Ignored        0,                                          // No Accumulation Buffer        0, 0, 0, 0,                                 // Accumulation Bits Ignored        16,                                         // 16Bit Z-Buffer (Depth Buffer)          0,                                          // No Stencil Buffer        0,                                          // No Auxiliary Buffer        PFD_MAIN_PLANE,                             // Main Drawing Layer        0,                                          // Reserved        0, 0, 0                                     // Layer Masks Ignored    };    int PixelFormat;    if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))              // 按照给定像素格式规范匹配与设备上下文合适的像素格式    {        KillGLWindow();                         // 重置显示区        MessageBox(NULL, "不能设置像素格式", "错误", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                           // 返回 FALSE    }    if (!SetPixelFormat(hDC, PixelFormat, &pfd))                // 设置像素格式    {        KillGLWindow();                         // 重置显示区        MessageBox(NULL, "不能设置像素格式", "错误", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                           // 返回 FALSE    }    if (!(hRC = wglCreateContext(hDC)))                 // 设置合适设备的OpenGL渲染上下文    {        KillGLWindow();                         // 重置显示区        MessageBox(NULL, "不能创建OpenGL渲染描述表", "错误", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                           // 返回 FALSE    }    if (!wglMakeCurrent(hDC, hRC))                      // 尝试激活着色描述表    {        KillGLWindow();                         // 重置显示区        MessageBox(NULL, "不能激活当前的OpenGL渲然描述表", "错误", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                           // 返回 FALSE    }    //opengl着色表设定结束    ShowWindow(hWnd, SW_SHOW);    InitGL();//opengl相关初始化    //消息处理    bool done = false;    MSG msg;    while (!done)                                   // Loop That Runs While done=FALSE    {        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))   // 如果有消息就处理消息        {            if (msg.message == WM_QUIT)             // Have We Received A Quit Message?            {                done = TRUE;                            // If So done=TRUE            }            else                                    // If Not, Deal With Window Messages            {                TranslateMessage(&msg);             // Translate The Message                DispatchMessage(&msg);              // Dispatch The Message            }        }        else                                        // 没消息就处理界面        {            // Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()                          DrawGLScene();                  // Draw The Scene            SwapBuffers(hDC);               // Swap Buffers (Double Buffering)        }    }    return TRUE;}
0 0