C++ OpenGL 3+;英特尔/AMD C++;

C++ OpenGL 3+;英特尔/AMD C++;,c++,opengl,opengl-es,C++,Opengl,Opengl Es,我正在为一个旧游戏引擎开发一个更新的渲染器,我在Intel和AMD卡上遇到了一个非常令人沮丧的视觉问题。好吧,我发现了很多关于英特尔和OpenGL问题的页面,但我希望它至少在AMD上也能工作——在NVidia卡上,无论是哪一代,它似乎都能完美工作。 我正在从项目中剥离一些代码,所以请告诉我是否缺少一些东西。 起初,我假设它是由旧GL固定管道残余物引起的,但在清理后,问题仍然存在。下面是它的一张照片: 我一直在研究上面列出的调试器和调试方法,我使用了经典的GLGETRROR逐行调试,我使用了AM

我正在为一个旧游戏引擎开发一个更新的渲染器,我在Intel和AMD卡上遇到了一个非常令人沮丧的视觉问题。好吧,我发现了很多关于英特尔和OpenGL问题的页面,但我希望它至少在AMD上也能工作——在NVidia卡上,无论是哪一代,它似乎都能完美工作。 我正在从项目中剥离一些代码,所以请告诉我是否缺少一些东西。 起初,我假设它是由旧GL固定管道残余物引起的,但在清理后,问题仍然存在。下面是它的一张照片:

我一直在研究上面列出的调试器和调试方法,我使用了经典的GLGETRROR逐行调试,我使用了AMD的CodeXL和GPU文件管理器。尽管这些工具中的一些相当复杂,而且我对每件事都不熟悉,但这些东西都没有显示警告或错误

好的,将一些信息放入:上下文创建当前如下所示:

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!"));
}
这是一个绘图例程,有更复杂的函数,但它已经发生在这个非常简单的例程中:

顶点着色器

#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; 
}

我非常感谢任何提示我可以尝试什么,如何获得更多信息,或者我可以尝试什么。另外,如果您需要更多的代码,请告诉我,因为这还缺少一些部分。我暂时忽略了纹理,但我很确定这没有关系。此外,在着色器中没有AlphaThreshold时也会发生这种情况,这是我后来添加的。

在DrawTileVerts中,您将传入一个名为“size”的参数

从您将其传递到调用gldrawArray的方式来看,它看起来应该是顶点数

但是从您使用它来计算传递到glBufferData的大小的方式来看,您将它视为浮点数

我想你打给glBufferData的电话应该是

glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size * FloatsPerVertex, verts, GL_DYNAMIC_DRAW);
或者您对GLDrawArray的呼叫应该是:

glDrawArrays(GL_TRIANGLE_FAN, 0, size / FloatsPerVertex);
有足够的信息可以看出存在不一致性,但没有足够的信息来确定哪一个是正确的修复


我还想再次检查您使用texsize的方式,因为这可能也是错误的,但如果没有看到更多的代码,我无法判断。

尝试使用renderdoc或AMD的GPUPerf之类的帧调试器-它们允许您在整个渲染过程中导航drawcall到drawcall,并随时查看帧缓冲区、纹理等内容。它们还向您显示当前绑定的网格,这样您就可以看到问题是在上传的顶点缓冲区内还是其他地方。我已经尝试过了,但没有成功,但我仍然需要了解很多,而且这个函数现在是一个非常简单的绘制平铺,甚至不是一个复杂的网格,所以我假设它是一些更“全局”的问题哦,我的上帝!我检查了这部分100万次都没看到。我可以吻你的脚。事实上,我错过了“/FloatsPerVertex”——有趣的是,英伟达似乎对这样的错误更加宽容。我希望这篇文章能帮助其他人发现这样的问题。
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size * FloatsPerVertex, verts, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLE_FAN, 0, size / FloatsPerVertex);