我正在更新我们古老的OpenGL代码。这是一个Windows系统,我正在使用GLEW。 OpenGL的版本是4.4(以前,创建上下文的方式将我们限制为1.1)。代码基数很大,所以我想分阶段更新它(即,只需很少的工作即可让所有的工作都能在高于1.1的版本上运行)。到目前为止,我发现只有一个突破。透明度不再有效。我怀疑这可能是由于glColor *或glTexEnv *被弃用。我试图请求一个特定版本的OpenGL,但没有成功。你能告诉我在上下文创建中我做了什么错误吗?或者我可以对绘制代码做些什么改变以获得透明度? (当然赞赏其他帮助)使用glColor *和OpenGL版本4.4
这里是上下文的创建代码(可读性检查删除错误):
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();
纹理现在应用与完全不透明,而不管alpha值发送到glColor4f()
。但是,如果我改变RGB值,那么它仍然反映在输出中。
您正在尝试做的很多事情在核心配置文件中不可用。首先将GL_CLAMP作为纹理重复模式以及即时模式和“当前颜色”。然而,透明度不起作用是非常主观的。我看到你在这里使用的透明度的唯一形式是alpha混合,这取决于绘制顺序。还有其他一些“透明不再有效”的事情可能意味着,例如,如果你的帧缓冲区应该存储一个目标alpha通道(它目前不支持,你已经分配了32位的RGB和0位的alpha-a格式更好地称为RGBx)。 –
绘制顺序是正确的。由于我没有提供帧缓冲创建的细节,所以我对你的陈述感到困惑(它现在不是,你已经为RGB分配了32位,为alpha分配了0位 - 一种更为人熟知的RGBx格式)。你是指纹理创作? – AbleArcher
您确实提供了帧缓冲区创建的详细信息。在你的PixelFormat描述符中。 'PFD_TYPE_RGBA,32,0,0,0,0,0,0,...'告诉WGL你想要一个32位颜色和0位阿尔法的格式。它通常会给你8位的红色,绿色和蓝色,并添加一个额外的8位对齐。现在,在给定混合函数的情况下,目标alpha(存储在framebuffer中的alpha分量)对alpha混合来说是无关紧要的。但是,如果您尝试使用framebuffer进行alpha合成,那么您肯定需要存储目标alpha以使透明度起作用。 –