我正在为旧游戏引擎开发更新的渲染器,但在Intel和AMD卡上出现了非常令人沮丧的视觉问题。好的,我发现了无数关于英特尔和OpenGL问题的页面,但我希望它至少也可以在AMD的NVidia卡上使用,无论什么一代,它似乎都可以正常工作。我正在从项目中剥离一些代码,因此请告诉我是否缺少某些内容。起初,我认为它是由旧的GL固定管道残余物引起的,但是在清理掉此问题后仍然存在。这是它的外观快照:
我一直在研究https://www.opengl.org/wiki/Debugging_Tools上列出的调试器和调试方法,我逐行使用了经典的glGetError,我使用了AMD的CodeXL和GPUProfiler。尽管其中一些工具相当复杂,并且我对所有工具都不熟悉,但是这些工具都没有显示警告或错误。
好的,将一些信息放入:上下文创建当前看起来像这样:
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
DesiredColorBits,
0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0,
DesiredDepthBits,
DesiredStencilBits,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
INT nPixelFormat = ChoosePixelFormat( hDC, &pfd );
check(nPixelFormat);
verify(SetPixelFormat( hDC, nPixelFormat, &pfd ));
// oldstyle context to init glew.
HGLRC tempContext = wglCreateContext(hDC);
wglMakeCurrent(hDC, tempContext);
//init glew
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
appErrorf(TEXT("Error: Init glew failed: %s"), appFromAnsi((char*)glewGetErrorString(err)));
else debugf(NAME_Init, TEXT("Glew successfully initialized."));
//Now init pure OpenGL >= 3.3 context.
if (WGLEW_ARB_create_context && WGLEW_ARB_pixel_format)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = DesiredColorBits;
pfd.cDepthBits = DesiredDepthBits;
pfd.iLayerType = PFD_MAIN_PLANE;
const INT iPixelFormatAttribList[] =
{
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, DesiredColorBits,
WGL_DEPTH_BITS_ARB, DesiredDepthBits,
WGL_STENCIL_BITS_ARB, DesiredStencilBits,
0 // End of attributes list
};
INT ContextFlags=0;
if (UseOpenGLDebug)
ContextFlags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | WGL_CONTEXT_DEBUG_BIT_ARB;
else ContextFlags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
INT iContextAttribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion,
WGL_CONTEXT_MINOR_VERSION_ARB, MinorVersion,
WGL_CONTEXT_FLAGS_ARB, ContextFlags,
0 // End of attributes list
};
INT iPixelFormat, iNumFormats;
wglChoosePixelFormatARB(hDC, iPixelFormatAttribList, NULL, 1, &iPixelFormat, (UINT*)&iNumFormats);
// pfd oldstyle crap...
debugf(NAME_Init, TEXT("DesiredColorBits: %i"), DesiredColorBits);
debugf(NAME_Init, TEXT("DesiredDepthBits: %i"), DesiredDepthBits);
debugf(NAME_Init, TEXT("DesiredStencilBits: %i"), DesiredStencilBits);
debugf(NAME_Init, TEXT("PixelFormat: %i"), iPixelFormat);
if (!SetPixelFormat(hDC, iPixelFormat, &pfd))
{
appErrorf(TEXT("Error: SetPixelFormat failed."));
return;
}
hRC = wglCreateContextAttribsARB(hDC, 0, iContextAttribs);
}
else appErrorf(TEXT("Error: Init glew failed: %s"), appFromAnsi((char*)glewGetErrorString(err)));
if(hRC)
{
MakeCurrent();
debugf(NAME_Init, TEXT("GL_VENDOR : %s"), appFromAnsi((const ANSICHAR *)glGetString(GL_VENDOR)));
debugf(NAME_Init, TEXT("GL_RENDERER : %s"), appFromAnsi((const ANSICHAR *)glGetString(GL_RENDERER)));
debugf(NAME_Init, TEXT("GL_VERSION : %s"), appFromAnsi((const ANSICHAR *)glGetString(GL_VERSION)));
debugf(NAME_Init, TEXT("GLEW Version : %s"), appFromAnsi((const ANSICHAR *)glewGetString(GLEW_VERSION)));
int NumberOfExtensions=0;
glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
for (INT i = 0; i<NumberOfExtensions; i++)
{
FString ExtensionString = appFromAnsi((const ANSICHAR *)glGetStringi(GL_EXTENSIONS, i));
debugf(NAME_DevLoad, TEXT("GL_EXTENSIONS(%i) : %s"), i, ExtensionString);
}
debugf(NAME_Init, TEXT("OpenGL %i.%i context initialized!"), MajorVersion,MinorVersion);
}
else
appErrorf(TEXT("Error: No OpenGL %i.%i context support."), MajorVersion, MinorVersion);
if( ShareLists && AllContexts.Num() )
verify(wglShareLists(AllContexts(0),hRC)==1);
AllContexts.AddItem(hRC);
if (UseOpenGLDebug)
{
glDebugMessageCallbackARB(&UXOpenGLRenderDevice::DebugCallback, NULL);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
GWarn->Logf(TEXT("OpenGL debugging enabled, this can cause severe performance drain!"));
}
我尝试了几种方法,但最终还是出现了问题。但是,我也尝试了一些更简单的版本,其中包括初始化问题,还尝试了其他一些令人高兴的事情以及用于创建上下文的SDL2。结果总是一样的。
矩阵的设置如下:
viewMat = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f, -1.0f, -1.0f));
modelMat = glm::mat4(1.0f);
projMat = glm::frustum(-RProjZ*zNear, +RProjZ*zNear, -Aspect*RProjZ*zNear, +Aspect*RProjZ*zNear, 1.0f*zNear, zFar);
这是绘制例程之一,还有更复杂的功能,但是这种非常简单的函数已经发生了:
顶点着色器
#version 330
layout (location = 0) in vec3 v_coord; // == gl_Vertex
layout (location = 2) in vec2 TexCoords;
layout(std140) uniform GlobalMatrices
{
mat4 modelviewprojMat;
};
uniform vec4 DrawColor;
out vec4 vDrawColor;
out vec2 vTexCoords;
void main(void)
{
vTexCoords=TexCoords;
vDrawColor=DrawColor;
gl_Position = modelviewprojMat * vec4(v_coord, 1.0);
}
片段着色器
#version 330
uniform sampler2D Texture0;
uniform float AlphaThreshold;
in vec4 vDrawColor;
in vec2 vTexCoords;
out vec4 FragColor;
void main(void)
{
vec4 Color = texture(Texture0, vTexCoords);
if(Color.a <= AlphaThreshold)
discard;
FragColor = Color*vDrawColor;
}
在这里,我还尝试了从150到430的各种版本,内核,兼容性,甚至可以快速跳转到OpenGL ES。
这是对应的C ++函数
DrawTileVerts(FLOAT* verts, UINT size, FLOAT* tex, UINT texsize, FPlane Color)
{
CHECK_GL_ERROR();
glBindVertexArray(DrawTileVertsVao);
// Verts
glBindBuffer(GL_ARRAY_BUFFER, DrawTileVertBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size, verts, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(VERTEX_COORD_ATTRIB);
glVertexAttribPointer(VERTEX_COORD_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof(float) * FloatsPerVertex, 0);
// Textures
glBindBuffer(GL_ARRAY_BUFFER, DrawTileTexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * texsize, tex, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(TEXTURE_COORD_ATTRIB);
glVertexAttribPointer(TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, GL_FALSE, sizeof(float) * TexCoords2D, 0);
glUniform4f(DrawTile_DrawColor, Color.X, Color.Y, Color.Z, Color.W);
glDrawArrays(GL_TRIANGLE_FAN, 0, size);
// Clean up
glDisableVertexAttribArray(VERTEX_COORD_ATTRIB);
glDisableVertexAttribArray(TEXTURE_COORD_ATTRIB);
CHECK_GL_ERROR();
glBindVertexArray(0);
}
我非常感谢我可以尝试的任何提示,如何获取更多信息或可以尝试的其他提示。另外,如果您需要更多代码,请告诉我,因为这还缺少某些部分。我暂时不做纹理,但是我确信这没有关系。同样,在着色器中没有AlphaThreshold时也会发生这种情况,这是我稍后添加的。
在DrawTileVerts中,您传入了一个名为“ size”的参数。
从将其传递到对glDrawArrays的调用的方式来看,看起来应该是顶点数。
但是从使用它来计算要传递给glBufferData的大小的方式来看,您将其视为浮点数。
我认为您对glBufferData的调用应该是
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size * FloatsPerVertex, verts, GL_DYNAMIC_DRAW);
也许您对glDrawArrays的调用应该是:
glDrawArrays(GL_TRIANGLE_FAN, 0, size / FloatsPerVertex);
有足够的信息可以看到存在不一致的地方,但是没有足够的信息来解决这是正确的解决方法。
我还要仔细检查您使用texsize的方式,因为这可能也是错误的,但是我看不到更多代码。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句