所以我写了一个非常简单的 OpenGL 程序来绘制 100x100x100 点,使用几何着色器绘制为立方体。我想将它与我目前使用 DirectX11 可以做的事情进行基准测试。
使用 DirectX11,我可以轻松地以 60fps (vsync) 渲染这些立方体。但是,使用 OpenGL 我被困在 40fps。
在这两个应用程序中,我都是:
- 使用点拓扑仅表示立方体的位置(步幅 = 12 字节)。
- 仅在初始化函数中映射到顶点缓冲区,仅一次。
- 总共只使用了两个绘制调用:一个渲染立方体,一个渲染帧时间。
- 使用背面剔除和深度测试。
- 将状态更改限制在绘制立方体所需的最小值(VBO/着色器程序)。
这是我的抽奖电话:
GLboolean CCubeApplication::Draw()
{
auto program = m_ppBatches[0]->GetShaders()->GetProgram(0);
program->Bind();
{
glUniformMatrix4fv(program->GetUniform("g_uWVP"), 1, false, glm::value_ptr(m_matMatrices[MATRIX_WVP]));
glDrawArrays(GL_POINTS, 0, m_uiTotal);
}
return true;
}
该函数调用 glBindVertexArray 和 glUseProgram
program->Bind();
其余的都是直截了当的。我的 Update 函数只更新相机的位置和视图矩阵,并且在 DirectX/OpenGL 版本中是相同的。
我的顶点着色器是直通的,我的片段着色器返回一个恒定的颜色。这是我的几何着色器:
#version 440 core
// GS_LAYOUT
layout(points) in;
layout(triangle_strip, max_vertices = 36) out;
// GS_IN
in vec4 vOut_pos[];
// GS_OUT
// UNIFORMS
uniform mat4 g_uWVP;
const float f = 0.1f;
const int elements[] = int[]
(
0,2,1,
2,3,1,
1,3,5,
3,7,5,
5,7,4,
7,6,4,
4,6,0,
6,2,0,
3,2,7,
2,6,7,
5,4,1,
4,0,1
);
// GS
void main()
{
vec4 vertices[] = vec4[]
(
g_uWVP * (vOut_pos[0] + vec4(-f,-f,-f, 0)),
g_uWVP * (vOut_pos[0] + vec4(-f,-f,+f, 0)),
g_uWVP * (vOut_pos[0] + vec4(-f,+f,-f, 0)),
g_uWVP * (vOut_pos[0] + vec4(-f,+f,+f, 0)),
g_uWVP * (vOut_pos[0] + vec4(+f,-f,-f, 0)),
g_uWVP * (vOut_pos[0] + vec4(+f,-f,+f, 0)),
g_uWVP * (vOut_pos[0] + vec4(+f,+f,-f, 0)),
g_uWVP * (vOut_pos[0] + vec4(+f,+f,+f, 0))
);
uint uiIndex = 0;
for(uint uiTri = 0; uiTri < 12; ++uiTri)
{
for(uint uiVert = 0; uiVert < 3; ++uiVert)
{
gl_Position = vertices[elements[uiIndex++]];
EmitVertex();
}
EndPrimitive();
}
}
我见过人们谈论实例化或其他此类渲染方法,但我主要想了解为什么我不能从 OpenGL 获得至少与使用 DirectX 相同的性能 - 就像我在这两种方法中所做的那样似乎和我几乎一模一样。相同的数据,相同的着色器。帮助?
更新 所以我下载了 gDEBugger,这是我的一帧调用堆栈:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
// Drawing cubes
glBindVertexArray(1)
glUseProgram(1)
glUniformMatrix4fv(0, 1, FALSE, {matrixData})
glDrawArrays(GL_POINTS, 0, 1000000)
// Drawing text
glBindVertexArray(2);
glUseProgram(5);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 2);
glBindBuffer(GL_ARRAY_BUFFER, 2);
glBufferData(GL_ARRAY_BUFFER, 212992, {textData}, GL_DYNAMIC_DRAW);
glDrawArrays(GL_POINTS, 0, 34);
// Swap buffers
wglSwapBuffers();