我的shader / vbo / vao使用OpenGL时遇到了一些麻烦。
我创建了一个几何着色器,它允许我从一个位置绘制一个立方体(使用制服设置的位置)。
我尝试使用块系统来减少我的绘制调用。问题是我无法找到开始的方法。如何减少绘制调用但仍然渲染多个立方体?
我正在考虑使用3次16次迭代的循环重新处理我的几何着色器,以生成4096个立方体的顶点位置。我想到的另一种可能性是为每个位置调用4096次我的着色器。 (我是OpenGL的初学者,但我不确定是否可行)。
uint8_t
的数组?数组的每个元素都包含一个字节来告诉块类型,0表示空气,1表示灰尘。请注意,数组索引将用于确定块位置。 (例如:chunk_data[0][5][2]
位置为vec3(0.f, 5.f, 2.f) + chunk_position
且他的类型为污垢。layout (location = 0) in vec3 position;
更改为字节数组(int我猜是因为GLSL没有提供字节/ uint8_t)我发现,感谢@Acorn,实例绘图可以帮助我提高我的表现。我现在试图了解实例绘图是如何工作的,以及如何将其应用于我的问题。现在我认为我需要定义包含我的实例数组的内容(我猜它会阻塞位置和类型)
RenderingManager.cpp(处理体素绘制的方法)
void ElkRendering::Managers::RenderingManager::DrawVoxel(const glm::vec3 & p_position)
{
if (m_currentTexture && m_currentShader)
{
m_currentShader->SetUniformVec3("u_position", p_position);
m_voxel.Draw(*m_currentShader);
}
}
Voxel.cpp(设置和绘制方法)
void Voxel::Setup()
{
GLfloat verts[] =
{
0.0f, 0.0f, 0.0f
};
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
}
void Voxel::Draw(Shader& p_shader)
{
PROFILER_SPY("Voxel::Draw");
glBindVertexArray(m_vao);
glDrawArrays(GL_POINTS, 0, 1);
glBindVertexArray(0);
}
Chunk.cpp(只是一个想法,这段代码根本不起作用而且还没有完成)
void Chunk::Setup()
{
for (uint8_t x = 0; x < 16; ++x)
{
for (uint8_t y = 0; y < 16; ++y)
{
for (uint8_t z = 0; z < 16; ++z)
{
blocks[x][y][z] = 1;
}
}
}
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(uint8_t) * 16 * 16 * 16, blocks, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
}
void Chunk::Draw(Shader& p_shader)
{
glBindVertexArray(m_vao);
glDrawArrays(GL_POINTS, 0, 1);
glBindVertexArray(0);
}
voxel.glsl
#shader vertex
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;
out vec3 v_pos;
void main()
{
v_pos = position;
}
#shader geometry
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 24) out;
uniform vec3 u_position;
uniform mat4 u_vp;
const float textCount = 3.0f;
const vec3 cubeVertex[8] = vec3[8]
(
/* Z+ (Front) */
vec3(-0.5f, -0.5f, +0.5f), // 0
vec3(-0.5f, +0.5f, +0.5f), // 1
vec3(+0.5f, -0.5f, +0.5f), // 2
vec3(+0.5f, +0.5f, +0.5f), // 3
/* Z- (Back) */
vec3(-0.5f, -0.5f, -0.5f), // 4
vec3(-0.5f, +0.5f, -0.5f), // 5
vec3(+0.5f, -0.5f, -0.5f), // 6
vec3(+0.5f, +0.5f, -0.5f) // 7
);
const int cubeIndices[24] = int[24]
(
1,0,3,2, // Z+ (Front)
3,2,7,6, // X+ (Right)
7,6,5,4, // Z- (Back)
5,4,1,0, // X- (Left)
0,4,2,6, // Y- (Bottom)
5,1,7,3 // Y+ (Top)
);
const vec2 textCoords[24] = vec2[24]
(
vec2(1/textCount, 1), vec2(1/textCount, 0), vec2(2/textCount, 1), vec2(2/textCount, 0), // Front
vec2(1/textCount, 1), vec2(1/textCount, 0), vec2(2/textCount, 1), vec2(2/textCount, 0), // Right
vec2(1/textCount, 1), vec2(1/textCount, 0), vec2(2/textCount, 1), vec2(2/textCount, 0), // Back
vec2(1/textCount, 1), vec2(1/textCount, 0), vec2(2/textCount, 1), vec2(2/textCount, 0), // Left
vec2(2/textCount, 1), vec2(2/textCount, 0), vec2(1, 1), vec2(1, 0), // Bottom
vec2(0, 1), vec2(0, 0), vec2(1/textCount, 1), vec2(1/textCount, 0) // Top
);
out vec2 textureCoord;
out float lighting;
void main()
{
mat4 model = mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, u_position.x, u_position.y, u_position.z, 1.0);
mat4 mvp = u_vp * model;
for (int i = 0; i < 24; ++i)
{
gl_Position = mvp * (gl_in[0].gl_Position + vec4(cubeVertex[cubeIndices[i]], 0));
textureCoord = textCoords[i];
if (i >= 16 && i < 20)
lighting = 0.2f;
else if (i >= 20)
lighting = 1.0f;
else
lighting = 0.6f;
EmitVertex();
if ((i + 1) % 4 == 0) EndPrimitive();
}
}
#shader fragment
#version 330 core
uniform sampler2D tex;
out vec4 FragColor;
in vec2 textureCoord;
in float lighting;
void main()
{
// Final color
FragColor = texture2D(tex, textureCoord) * lighting;
}