【问题标题】:Textures not working with OpenGL纹理不适用于 OpenGL
【发布时间】:2014-02-25 22:11:27
【问题描述】:

我正在尝试从数组加载纹理。我有一个应该用于纹理的四边形。

#include <Windows.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#include <fstream>
#include <vector>
#include <string>
WNDCLASSEX wclass;
    MSG msg;
    HWND hwnd;
    HDC hdc;
    float angle;
    HGLRC hrc;
    unsigned int tex;
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC);
void resize()
{
    RECT rec; 
    GetClientRect(hwnd, &rec);
    float width = 400;
    float height = 400;
     GLfloat fieldOfView = 60.0f;
     glViewport (0, 0,  rec.right, rec.bottom);

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(fieldOfView, (GLfloat) width/(GLfloat) height, 0.1, 500.0);


  glMatrixMode(GL_MODELVIEW);
  glEnable(GL_TEXTURE_2D);
  glLoadIdentity();
}

void init()
{
    GLubyte pixels[12] = {
        0, 0, 0,   1, 1, 1,
        1, 1, 1,   0, 0, 0
    };
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,2,2, 0, GL_RGB, GL_UNSIGNED_BYTE,pixels);         
}

void draw()
{
    angle -= 0.01f;
    float rtri = 0;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glTranslatef(0, 0, -5);
    glRotatef(angle,0, 1, 0); 
    glBindTexture(GL_TEXTURE_2D, tex);

    glBegin(GL_QUADS);
      glColor3f(0,1,0);
      glTexCoord2f(0.0, 0.0);
      glVertex3f(0.0, 0.0, 0.0);
      glTexCoord2f(1.0, 0.0);
      glVertex3f(1.0, 0.0, 0.0);
      glTexCoord2f(1.0, 1.0);
      glVertex3f(1.0, 1.0, 0.0);
      glTexCoord2f(0.0, 1.0);
      glVertex3f(0.0, 1.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);

    SwapBuffers(hdc);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
{

    wclass.cbSize = sizeof(WNDCLASSEX);
    wclass.style = 0;
    wclass.lpfnWndProc = WinProc;
    wclass.cbClsExtra = 0;
    wclass.cbWndExtra = 0;
    wclass.hInstance = hInstance;
    wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
    wclass.lpszMenuName = NULL;
    wclass.lpszClassName = "CLASS";
    wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wclass))
    {
         MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
         return 0;
    }

    hwnd = CreateWindowEx(
    0, "CLASS", "dddd", WS_OVERLAPPEDWINDOW,
    0, 0, 700, 700,
    HWND_DESKTOP, NULL, hInstance, NULL
    );

    hdc = GetDC(hwnd);
    EnableOpenGL(hwnd, &hdc, &hrc);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    if(hwnd == NULL)
    {
        MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
    }
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
    {
  case WM_CREATE:
      init();
      break;
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        case WM_TIMER:
            switch(wParam)
            {
            //case UPDATER_ID:
                //update();
                //break;
            }
            break;
        case WM_PAINT:
            draw();
            break;
        case WM_SIZE:
            resize();
            break;
        default:
                return DefWindowProc (hwnd, msg, wParam, lParam);
    }

    return 0;
}

void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
    PIXELFORMATDESCRIPTOR pfd;

    int iFormat;

    *hDC = GetDC(hwnd);

    ZeroMemory(&pfd, sizeof(pfd));

    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW |
                  PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;

    iFormat = ChoosePixelFormat(*hDC, &pfd);

    SetPixelFormat(*hDC, iFormat, &pfd);

    *hRC = wglCreateContext(*hDC);

    wglMakeCurrent(*hDC, *hRC);
}

它没有绘制纹理。一切似乎都很好,只是它没有在数组中绘制纹理。

另外,当调用 glGetError() 时,我得到 1282 作为结果。

我想避免使用 SOIL 或 SDL 等外部库。使用着色器也不是一种选择。

【问题讨论】:

  • @wendelbsilva 但是仍然无法正常工作。我编辑了问题中的代码。
  • 在这段代码中没有一次调用glGetError (...),因此无法知道是什么原因造成的。我建议您在各个地方对glGetError (...) 进行插件调用,以尝试本地化源代码。此外,由于所有 GL 错误代码都以十六进制定义,因此 1282 并不是特别有用。如果将其转换为 0x0502,您可以很快发现它是 GL_INVALID_OPERATION
  • 我认为您错过了对glActiveTexture的呼叫
  • glActiveTexture 不是必需的,除非您想更改默认的 GL_TEXTURE0
  • 各位,我尝试在绘图前启用它,但它不起作用。结果还是一样。

标签: c++ opengl


【解决方案1】:

在你的draw call中你有:

glDisable(GL_TEXTURE_2D);

但是你在draw call中没有对应的glEnable。如果您的窗口渲染不止一次,后续帧将禁用纹理。

【讨论】:

    【解决方案2】:

    您在 init() 中没有当前 GL 上下文,而您在 WinProc() 中调用它。将init() 调用移到WinMain() 中的EnableOpenGL() 之后。


    还有:

    GLubyte pixels[12] = 
    {
        0, 0, 0,   1, 1, 1,
        1, 1, 1,   0, 0, 0
    };
    

    GLubyte 频道范围从0(最小强度)到255(最大强度)。

    你有一个纯黑色的棋盘图案,非常接近纯黑色。

    试试这个:

    GLubyte pixels[12] = 
    {
          0,   0,   0,   255, 255, 255,
        255, 255, 255,     0,   0,   0,
    };
    

    您还应该在调用glTexImage2D() 之前发出glPixelStorei(GL_UNPACK_ALIGNMENT, 1)(默认4),因为您使用的是RGB。


    还有:

    您需要在渲染四边形之前使用glEnable( GL_TEXTURE_2D ) 实际启用纹理。


    所有修复:

    #include <Windows.h>
    #include <gl\GL.h>
    #include <gl\GLU.h>
    #include <fstream>
    #include <vector>
    #include <string>
    
    WNDCLASSEX wclass;
    MSG msg;
    HWND hwnd;
    HDC hdc;
    float angle;
    HGLRC hrc;
    unsigned int tex;
    
    void init()
    {
        GLubyte pixels[] = 
        {
            0,   0,   0,   255, 255, 255,
            255, 255, 255,   0,   0,   0,
        };
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,2,2, 0, GL_RGB, GL_UNSIGNED_BYTE,pixels);         
    }
    
    void draw()
    {
        angle -= 0.01f;
        float rtri = 0;
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glClearColor(0.5, 0.5, 0.5, 1.0);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glTranslatef(0, 0, -5);
        glRotatef(angle,0, 1, 0); 
    
        glEnable( GL_TEXTURE_2D );
        glBindTexture(GL_TEXTURE_2D, tex);
    
        glBegin(GL_QUADS);
        glTexCoord2f(0.0, 0.0);
        glVertex3f(0.0, 0.0, 0.0);
        glTexCoord2f(1.0, 0.0);
        glVertex3f(1.0, 0.0, 0.0);
        glTexCoord2f(1.0, 1.0);
        glVertex3f(1.0, 1.0, 0.0);
        glTexCoord2f(0.0, 1.0);
        glVertex3f(0.0, 1.0, 0.0);
        glEnd();
    
        glDisable(GL_TEXTURE_2D);
    
        SwapBuffers(hdc);
    }
    
    void resize()
    {
        RECT rec; 
        GetClientRect(hwnd, &rec);
        float width = 400;
        float height = 400;
        GLfloat fieldOfView = 60.0f;
        glViewport (0, 0,  rec.right, rec.bottom);
    
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(fieldOfView, (GLfloat) width/(GLfloat) height, 0.1, 500.0);
    
        glMatrixMode(GL_MODELVIEW);
        glEnable(GL_TEXTURE_2D);
        glLoadIdentity();
    }
    
    LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_CREATE:
            break;
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        case WM_TIMER:
            break;
        case WM_PAINT:
            draw();
            break;
        case WM_SIZE:
            resize();
            break;
        default:
            return DefWindowProc (hwnd, msg, wParam, lParam);
        }
    
        return 0;
    }
    
    void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
    {
        PIXELFORMATDESCRIPTOR pfd;
    
        int iFormat;
    
        *hDC = GetDC(hwnd);
    
        ZeroMemory(&pfd, sizeof(pfd));
    
        pfd.nSize = sizeof(pfd);
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW |
            PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 24;
        pfd.cDepthBits = 16;
        pfd.iLayerType = PFD_MAIN_PLANE;
    
        iFormat = ChoosePixelFormat(*hDC, &pfd);
    
        SetPixelFormat(*hDC, iFormat, &pfd);
    
        *hRC = wglCreateContext(*hDC);
    
        wglMakeCurrent(*hDC, *hRC);
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
    {
        wclass.cbSize = sizeof(WNDCLASSEX);
        wclass.style = 0;
        wclass.lpfnWndProc = WinProc;
        wclass.cbClsExtra = 0;
        wclass.cbWndExtra = 0;
        wclass.hInstance = hInstance;
        wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
        wclass.lpszMenuName = NULL;
        wclass.lpszClassName = "CLASS";
        wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    
        if(!RegisterClassEx(&wclass))
        {
            MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
            return 0;
        }
    
        hwnd = CreateWindowEx
            (
            0, "CLASS", "dddd", WS_OVERLAPPEDWINDOW,
            0, 0, 700, 700,
            HWND_DESKTOP, NULL, hInstance, NULL
            );
    
        hdc = GetDC(hwnd);
        EnableOpenGL(hwnd, &hdc, &hrc);
        init();
    
        ShowWindow(hwnd, nCmdShow);
        UpdateWindow(hwnd);
        if(hwnd == NULL)
        {
            MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
        }
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    

    【讨论】:

    • 谢谢。谢谢你。谢谢你。如果我有足够的分数来喜欢你的回答,我会尽快这样做。我很高兴。它有效!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 2011-10-28
    相关资源
    最近更新 更多