最近,我更新了ATI驱动程序(我使用的是HD7970)到最新的一个,我的OpenGL项目的一些对象停止工作。更重要的是,他们的工作在nVidia最新的驱动程序(测试960米)。ATI和nVidia渲染管道之间有什么区别吗?
其他信息:
- 没有来自
glGetError()
的错误, - 着色器已正确编译和链接,
- 其他渲染对象工作正常,但VBO填充和绘制命令是不同的。工作图是从
*.obj
文件中加载并由glDrawArrays()
绘制的。Broken one的VBO由计算着色器(compute shader)填充,它从用于存储的image2D获取顶点,并通过glDrawElements()
绘制, - 用我最简单的GPU调试器,我检查了顶点和片段着色器正在启动。
当我尝试用三角形绘制时,我什么也看不到,但是当我切换到GL_POINTS
时,我看到了绿色点(片段着色器的输出是纯绿色通道),它们正在按照它们应该的方式移动。这可能表明顶点着色器正在启动,因为MVP倍增正在发生。这些都是行星LOD对象与一个大的VBO,所以我使用一个函数来绑定所有缓冲区和其他绘制必要的高度图。VBO大小为128MB
初始化:
glGenBuffers(1, &VBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, VBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, size * sizeof(vec4), NULL, GL_DYNAMIC_COPY);
glGenBuffers(1, &IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * sizeof(unsigned int), NULL, GL_DYNAMIC_DRAW);
glGenBuffers(1, &Normals);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, Normals);
glBufferData(GL_SHADER_STORAGE_BUFFER, size * sizeof(vec4), NULL, GL_DYNAMIC_COPY);
通过计算着色器(Compute Shader)填充VBO:
#version 430 core
layout( std430, binding=1 ) buffer ParamsBuffer
{
float size;
uint index;
int parentIndex;
uint textureSize;
vec4 upVector;
vec4 Position;
vec4 quadrant;
};
layout( std430, binding=2 ) buffer VertBuffer
{
vec4 VBO[ ];
};
layout( std430, binding=3 ) buffer NormalsBuffer
{
vec4 Normals[ ];
};
layout(std430, binding = 4) buffer IndexBuffer
{
uint Index[];
};
layout( std430, binding=10 ) buffer DebugBuffer
{
vec4 debug;
};
layout (rgba32f) uniform image2D HeightMap;
layout (rgba32f) uniform image2D NormalMap;
layout( local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main(void)
{
uint WGidY=(gl_WorkGroupID.y);
uint WGidX=(gl_WorkGroupID.x);
uint mapVBOOffset=index*textureSize*textureSize;
uint indexOffset=6*index*textureSize*textureSize;
VBO[WGidY*textureSize+WGidX+mapVBOOffset]=imageLoad(HeightMap, ivec2(WGidX, WGidY));
Normals[WGidY*textureSize+WGidX+mapVBOOffset]=imageLoad(NormalMap, ivec2(WGidX, WGidY));
// debug=VBO[0];
if(WGidX==textureSize-1 || WGidY==textureSize-1)
return;
uint localIndex = 6*(WGidY*textureSize+WGidX)+indexOffset;
Index[localIndex+0]=(WGidY+1)*textureSize+WGidX +mapVBOOffset;
Index[localIndex+1]=WGidY*textureSize +WGidX+1+mapVBOOffset;
Index[localIndex+2]=WGidY*textureSize +WGidX +mapVBOOffset;
Index[localIndex+3]=WGidY*textureSize +WGidX+1+mapVBOOffset;
Index[localIndex+4]=(WGidY+1)*textureSize+WGidX +mapVBOOffset;
Index[localIndex+5]=(WGidY+1)*textureSize+WGidX+1+mapVBOOffset;
}
约束力:
glUseProgram(RenderProgram);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, PerFrameBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, ConstantBuffer);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, Normals);
glVertexAttribPointer(
2,
4,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(
0,
4,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
图纸:
float discardFactor = 0;
GLint drawMode;
if(renderMode==0)
drawMode = GL_TRIANGLES;
if (renderMode == 1)
{
drawMode = GL_PATCHES;
GLint vert= 3;
glPatchParameteri(GL_PATCH_VERTICES, 3);
}
if (tile->quadrant_x == nullptr)
{
HeightMap hp = tile->quadrantX;
if (CornersInFrustum(hp.Corners))
{
int mapOffset = tile->quadrantX.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
}
}
if (tile->quadrant_y == nullptr)
{
HeightMap hp = tile->quadrantY;
if ( CornersInFrustum(hp.Corners))
{
int mapOffset = tile->quadrantY.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
}
}
if (tile->quadrant_z == nullptr)
{
HeightMap hp = tile->quadrantZ;
if (CornersInFrustum(hp.Corners))
{
int mapOffset = tile->quadrantZ.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
}
}
if (tile->quadrant_w == nullptr)
{
HeightMap hp = tile->quadrantW;
if (CornersInFrustum(hp.Corners))
{
int mapOffset = tile->quadrantW.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
}
}
顶点着色器:
#version 430 //core
layout(location = 0) in vec4 vertexPosition_modelspace;
layout(location = 2) in vec4 vertexNormal_modelspace;
layout(std430, binding = 4) buffer PerFrame
{
mat4 ViewMatrix;
vec4 CameraPosition;
vec4 CameraForward;
mat4 ModelMatrix;
float time;
float perFrametab[3];
};
layout(std430, binding = 5) buffer Constant
{
mat4 ProjectionMatrix;
vec4 SeedBuffer;
vec2 screenSize;
};
layout( std430, binding=10 ) buffer DebugBuffer
{
vec4 debug;
};
out vec3 Position_worldspace;
out vec3 Normal_cameraspace;
out vec3 EyeDirection_cameraspace;
out vec3 LightDirection_cameraspace;
out vec3 LightPosition_worldspace;
out vec3 NormalWorldSpace;
void main()
{
gl_Position =ProjectionMatrix*
ViewMatrix*ModelMatrix*
vec4(vertexPosition_modelspace.xyz,1);
float C = 1,
near = 0.1,
far = 10000000.0f;
gl_Position.z = (2*log2(C*gl_Position.w + 1) / log2(C*far + 1) - 1) * gl_Position.w;
Position_worldspace = (ModelMatrix*vec4(vertexPosition_modelspace.xyz,1)).xyz;
Normal_cameraspace = ( ViewMatrix *(vec4(vertexNormal_modelspace.xyz,0))).xyz;
vec4 normalTemp=ModelMatrix*vertexNormal_modelspace;
NormalWorldSpace=normalize(normalTemp.xyz);
}
1条答案
按热度按时间hkmswyz61#
好吧,我找到了一个解决方案。问题出在计算着色器中的imageStore()和imageLoad()中。即使我使用image2D作为存储目的,我也需要添加
生成纹理后。这就是ATI与NVIDIA的区别。