【问题标题】:Using glColor* with OpenGL version 4.4在 OpenGL 4.4 版中使用 glColor*
【发布时间】:2014-02-20 07:53:19
【问题描述】:

我正在更新我们古老的 OpenGL 代码。这是一个 Windows 系统,我正在使用 GLEW。 OpenGL 版本是 4.4(以前,创建上下文的方式将我们限制为 1.1)。代码库很大,所以我想分阶段更新它(即现在让所有工作都在高于 1.1 的版本上运行,只需最少的工作)。到目前为止,我只找到了一个突破口。透明度不再起作用。我怀疑这可能是由于 glColor* 或 glTexEnv* 已被弃用。我试图请求特定版本的 OpenGL,但没有成功。你能告诉我我在上下文创建中做错了什么,或者我可以对绘制代码进行哪些更改以使透明度正常工作? (当然还有其他帮助。)

这是上下文创建代码(为了便于阅读,删除了错误检查):

PIXELFORMATDESCRIPTOR pfd = {
    /*WORD  nSize*/           sizeof(PIXELFORMATDESCRIPTOR),
    /*WORD  nVersion*/        1,
    /*DWORD dwFlags*/         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
    /*BYTE  iPixelType*/      PFD_TYPE_RGBA,
    /*BYTE  cColorBits*/      24,
    /*BYTE  cRedBits*/        0,
    /*BYTE  cRedShift*/       0,
    /*BYTE  cGreenBits*/      0,
    /*BYTE  cGreenShift*/     0,
    /*BYTE  cBlueBits*/       0,
    /*BYTE  cBlueShift*/      0,
    /*BYTE  cAlphaBits*/      8,
    /*BYTE  cAlphaShift*/     0,
    /*BYTE  cAccumBits*/      0,
    /*BYTE  cAccumRedBits*/   0,
    /*BYTE  cAccumGreenBits*/ 0,
    /*BYTE  cAccumBlueBits*/  0,
    /*BYTE  cAccumAlphaBits*/ 0,
    /*BYTE  cDepthBits*/      16,
    /*BYTE  cStencilBits*/    0,
    /*BYTE  cAuxBuffers*/     0,
    /*BYTE  iLayerType*/      PFD_MAIN_PLANE,
    /*BYTE  bReserved*/       0,
    /*DWORD dwLayerMask*/     0,
    /*DWORD dwVisibleMask*/   0,
    /*DWORD dwDamageMask*/    0
};
int nPixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, nPixelFormat, &pfd);

hRC_ = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC_);

MsgUtil::TraceWin("version: %s", glGetString(GL_VERSION)); // Output: version: 4.4.0

glewInit();

GLint attribs[] = {
    WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
    WGL_CONTEXT_MINOR_VERSION_ARB, 0,
    WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
    0
};

HGLRC CompHRC = wglCreateContextAttribsARB(hDC, 0, attribs);
if (CompHRC && wglMakeCurrent(hDC, CompHRC)){
hRC_ = CompHRC;
}

MsgUtil::TraceWin("version: %s", glGetString(GL_VERSION)); // Output: version: 4.4.0

即使在请求版本 3.0 之后,glGetString(GL_VERSION) 也会返回 4.4.0。我绘制到帧缓冲区,然后使用glReadPixels() 写入位图(尽管我认为这在这里并不特别相关)。

这是帧缓冲区代码(在上下文的生命周期内保持绑定):

glGenFramebuffers(1, &defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);

glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, framebufferWidth, framebufferHeight);

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);

glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);

这是抽奖代码:

glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0f, 1.0f, 1.0f, alpha);

glBindTexture(GL_TEXTURE_2D, texture_id);

glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);  
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);

// Turn theImage (a CImage) into a texture
HBITMAP hbitmap = NewCreateDib24(*window_dc_, MAX_DELTA, MAX_DELTA);
CBitmap* bitmap = CBitmap::FromHandle(hbitmap);
CDC* memDC = new CDC();
memDC->CreateCompatibleDC(window_dc_);
CBitmap* pOldBitmap = memDC->SelectObject(bitmap);
theImage.StretchBlt(*memDC, 0, 0, MAX_DELTA, MAX_DELTA, SRCCOPY);
LPBYTE tempbitsMem = new BYTE[bm_info.bmiHeader.biSizeImage];
bitmap->GetBitmapBits(bm_info.bmiHeader.biSizeImage, (LPVOID)tempbitsMem);

glTexImage2D(GL_TEXTURE_2D, 0, 3, MAX_DELTA, MAX_DELTA, 0, GL_BGR, GL_UNSIGNED_BYTE, tempbitsMem);

// Draw texture     
glBegin(GL_QUADS);
glTexCoord2d(tx.x_, 1.0 - tx.y_);
glVertex2d(px.x_, px.y_);
glTexCoord2d(t0.x_, 1.0 - t0.y_);
glVertex2d(p0.x_, p0.y_ );
glTexCoord2d(ty.x_, 1.0 - ty.y_);
glVertex2d(py.x_, py.y_);
glTexCoord2d(txy.x_, 1.0 - txy.y_);
glVertex2d(pxy.x_, pxy.y_); 
glEnd();

无论发送到glColor4f() 的 alpha 值如何,现在都会应用完全不透明的纹理。但是,如果我更改 RGB 值,那么它仍然会反映在输出中。

【问题讨论】:

  • 许多您尝试做的事情在核心配置文件中不可用。 GL_CLAMP 首先作为纹理重复模式以及立即模式和“当前颜色”。然而,透明度不起作用是非常主观的。我看到您在这里使用的唯一透明形式是 alpha 混合,这取决于绘制顺序。还有其他一些“透明度不再起作用”可能意味着,例如,如果您的帧缓冲区应该存储目标 alpha 通道(它目前没有,您已经为 RGB 分配了 32 位,为 alpha 分配了 0 位 - 一个格式更好地称为 RGBx)。
  • 抽奖顺序正确。我对您的声明 (it currently does not, you have allocated 32-bits for RGB and 0-bits for alpha - a format better known as RGBx) 感到困惑,因为我没有提供帧缓冲区创建的详细信息。您指的是纹理创建吗?
  • 您确实提供了创建帧缓冲区的详细信息。在您的 PixelFormat 描述符中。 PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, ... 告诉 WGL 您想要一种具有 32 位颜色和 0 位 alpha 的格式。它通常会为您提供 8 位红色、绿色和蓝色,并添加额外的 8 位用于对齐。现在,考虑到您的混合功能,目标 alpha(存储在帧缓冲区中的 alpha 分量)对于 alpha 混合是微不足道的。但是,如果您尝试使用帧缓冲区进行 alpha 合成,那么您肯定需要存储目标 alpha 以使透明度起作用。
  • 啊,好的。我设置 pfd.cColorBits = 24 和 pfd.cAlphaBits = 8。现在DescribePixelFormat() 显示我为每个 RGBA 获得 8 位(以前我缺少 alpha)。但是,仍然没有透明度。
  • 我编辑了帖子以反映上下文创建代码的变化,并添加了用于创建帧缓冲区的代码。我不确定这两者是如何交互的,但我请求了一个带有 alpha 通道的帧缓冲区,它已经完成了,所以......

标签: windows opengl glew openglcontext


【解决方案1】:

您应该要求提供兼容性配置文件而不是核心配置文件。

【讨论】:

  • 这是有道理的。我将WGL_CONTEXT_CORE_PROFILE_BIT_ARB 更改为WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB。但是,我得到了相同的结果。
  • 虽然这里的建议帮助了我,但我仍在处理同样的问题。如果有兴趣,我在这里发布了修改后的问题:(stackoverflow.com/questions/21921353/…)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2021-09-01
  • 1970-01-01
相关资源
最近更新 更多