PNG 到 Opengl 的使用问题

Posted

技术标签:

【中文标题】PNG 到 Opengl 的使用问题【英文标题】:PNG to Opengl usage issues 【发布时间】:2015-05-28 06:32:06 【问题描述】:

我正在尝试将几个原生 PNG 图像整理到 Opengl 中,但遇到了一些障碍。我已经在使用 Cximage 库,所以如果我能提供帮助,我更愿意坚持使用它。

3个相关问题;

    PNG 在 OpenGL 中显示为黑白。图像不是问题,因为其他图像类型可以工作,但我宁愿不转换,除非它很容易且不需要磁盘保存或其他库。 PNG 有黑色背景,假设是透明的。 OpenGL 视图/方向问题。图像在 OpenGL 中倾斜,即方向不正确。 PNG 包含我正在尝试显示的等距视图。

我当前使用的代码示例

*是的,我意识到我正在使用折旧的 Opengl。由于我正在使用遗留代码,我需要这样做。

int MyScene::LoadTexture

    m_pImgCol = new CxImage((BYTE *)pdatabuffer, (DWORD)filesize, CXIMAGE_FORMAT_PNG);

    DWORD iDest(0), iSrc(0);
    DWORD dwSize = m_pImgCol->GetWidth()*m_pImgCol->GetHeight();
    BYTE  *pSrc = m_pImgCol->GetBits();
    BYTE  *pDest = new BYTE[dwSize * 4];
    BYTE  *pSrcA = m_pImgAlpha ? m_pImgAlpha->GetBits() : NULL;
    BYTE  alpha;

    for (DWORD iX = 0; iX<dwSize; iX++)
    
        alpha = 255;
        if (pSrcA)
            alpha = pSrcA[iX];
        else
        
            if (pSrc[iSrc] == 0 && pSrc[iSrc + 1] == 0 && pSrc[iSrc + 2] == 0)
                alpha = 0;
        
        pDest[iDest++] = pSrc[iSrc++];
        pDest[iDest++] = pSrc[iSrc++];
        pDest[iDest++] = pSrc[iSrc++];
        pDest[iDest++] = alpha;
    

    GLuint iTexture=0;
    glGenTextures(1, &iTexture);
    glBindTexture(GL_TEXTURE_2D, 0);
    glTexImage2D(GL_TEXTURE_2D, 0, 4, m_pImgCol->GetWidth(), m_pImgCol->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pDest);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glEnable(GL_TEXTURE_2D);



int MyScene::DrawGLScene()

    CRect rWnd;
    GetClientRect(&rWnd);

    glViewport(0,0,rWnd.Width(),rWnd.Height()); 
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();                       
    glOrtho(-20 * m_Zoom, 20 * m_Zoom, -15 * m_Zoom, 25 * m_Zoom, 20000, -20000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glEnable(GL_TEXTURE_2D);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glTranslatef(0, -0.5f, 0.0f);
    glRotatef(m_rx, 1.0f, 0.0f, 0.0f);   
    glRotatef(m_rz, 0.0f, 0.0f, 1.0f);  
    glRotatef(m_ry, 0.0f, 1.0f, 0.0f);

    DrawScene();

    SwapBuffers(m_pView->m_hDC);
    return TRUE;



int MyScene::DrawScene

    float dL = -8;
    float dR = 8;
    float dT = -8;
    float dB = 8;

    glBindTexture(GL_TEXTURE_2D, 0);
    glColor3f(1.0f, 1.0f, 1.0f);

    glBegin(GL_QUADS);
    glVertex3f(dL, dT, 0);
    glTexCoord2f(0, 0);
    glVertex3f(dL, dB, 0);
    glTexCoord2f(0, 1);
    glVertex3f(dR, dB, 0);
    glTexCoord2f(1, 1);
    glVertex3f(dR, dT, 0);
    glTexCoord2f(1, 0);
    glEnd();

如有必要,我可以提供更多代码,但这是我可以分解为基本的代码。

【问题讨论】:

【参考方案1】:

    找到 http://ysflight.in.coocan.jp/programming/pngdecoder/pngdecodere.html 并修改它以读取现有缓冲区。大惊小怪,没有磁盘保存或库。

    通过添加获得 PNG 透明度;

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    

    成像撕裂;似乎我的顺序错误;

    glTexCoord2f(0, 0);
    glVertex3f(dL, dT, 0);
    

【讨论】:

2. PNG透明度;对于某些人来说,图像本身似乎是问题的根源,因此不得不手动调整 rgba 数据并为 PNG 图像本身添加/更改透明度,如下所示; if (rgba[index] != 0 && rgba[index + 1] != 0 && rgba[index+ 2] != 0) rgba[index + 3] = 0xff;

以上是关于PNG 到 Opengl 的使用问题的主要内容,如果未能解决你的问题,请参考以下文章

在 Haskell 中使用 OpenGL 渲染 PNG 图像

在Haskell中使用OpenGL渲染PNG图像

使用 opengl 硬件渲染器导出带有颜色条的 MATLAB 冲浪图会导致损坏的 png 文件

在 OpenGL 中使用 PNG 纹理的最快最简单方法

OpenGL在2个纹理之间切换

在 Android OpenGL ES 中将 2D 纹理保存为 png