纹理 2D

只使用了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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值