Added depth-only prepass for non-optimized

This commit is contained in:
roboman2444 2016-12-31 00:30:37 -05:00
parent a13a77fc1d
commit 51474ad723
8 changed files with 175 additions and 1 deletions

View File

@ -0,0 +1,26 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
void main() {
//nothing
}

View File

@ -0,0 +1,2 @@
Shaders/BasicBlockDepthOnly.fs
Shaders/BasicBlockDepthOnly.vs

View File

@ -0,0 +1,35 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
uniform mat4 projectionViewMatrix;
uniform vec3 chunkPosition;
// --- Vertex attribute ---
// [x, y, z]
attribute vec3 positionAttribute;
void main() {
vec4 vertexPos = vec4(chunkPosition, 1.);
vertexPos.xyz += positionAttribute.xyz;
gl_Position = projectionViewMatrix * vertexPos;
}

View File

@ -295,6 +295,65 @@ namespace spades {
device->BindBuffer(IGLDevice::ArrayBuffer, 0); device->BindBuffer(IGLDevice::ArrayBuffer, 0);
} }
void GLMapChunk::RenderDepthPass() {
SPADES_MARK_FUNCTION();
Vector3 eye = renderer->renderer->GetSceneDef().viewOrigin;
if (!realized)
return;
if (needsUpdate) {
Update();
needsUpdate = false;
}
if (!buffer) {
// empty chunk
return;
}
AABB3 bx = aabb;
Vector3 diff = eye - centerPos;
float sx = 0.f, sy = 0.f;
// FIXME: variable map size?
if (diff.x > 256.f)
sx += 512.f;
if (diff.y > 256.f)
sy += 512.f;
if (diff.x < -256.f)
sx -= 512.f;
if (diff.y < -256.f)
sy -= 512.f;
bx.min.x += sx;
bx.min.y += sy;
bx.max.x += sx;
bx.max.y += sy;
if (!renderer->renderer->BoxFrustrumCull(bx))
return;
GLProgram *depthonlyProgram = renderer->depthonlyProgram;
static GLProgramUniform chunkPosition("chunkPosition");
chunkPosition(depthonlyProgram);
chunkPosition.SetValue((float)(chunkX * Size) + sx, (float)(chunkY * Size) + sy,
(float)(chunkZ * Size));
static GLProgramAttribute positionAttribute("positionAttribute");
positionAttribute(depthonlyProgram);
device->BindBuffer(IGLDevice::ArrayBuffer, buffer);
device->VertexAttribPointer(positionAttribute(), 3, IGLDevice::UnsignedByte, false,
sizeof(Vertex), (void *)asOFFSET(Vertex, x));
device->BindBuffer(IGLDevice::ArrayBuffer, 0);
device->BindBuffer(IGLDevice::ElementArrayBuffer, iBuffer);
device->DrawElements(IGLDevice::Triangles,
static_cast<IGLDevice::Sizei>(indices.size()),
IGLDevice::UnsignedShort, NULL);
device->BindBuffer(IGLDevice::ElementArrayBuffer, 0);
}
void GLMapChunk::RenderSunlightPass() { void GLMapChunk::RenderSunlightPass() {
SPADES_MARK_FUNCTION(); SPADES_MARK_FUNCTION();
Vector3 eye = renderer->renderer->GetSceneDef().viewOrigin; Vector3 eye = renderer->renderer->GetSceneDef().viewOrigin;

View File

@ -89,6 +89,7 @@ namespace spades {
float DistanceFromEye(const Vector3 &eye); float DistanceFromEye(const Vector3 &eye);
void RenderSunlightPass(); void RenderSunlightPass();
void RenderDepthPass();
void RenderDLightPass(std::vector<GLDynamicLight> lights); void RenderDLightPass(std::vector<GLDynamicLight> lights);
}; };
} }

View File

@ -42,6 +42,7 @@ namespace spades {
renderer->RegisterProgram("Shaders/BasicBlockPhys.program"); renderer->RegisterProgram("Shaders/BasicBlockPhys.program");
else else
renderer->RegisterProgram("Shaders/BasicBlock.program"); renderer->RegisterProgram("Shaders/BasicBlock.program");
renderer->RegisterProgram("Shaders/BasicBlockDepthOnly.program");
renderer->RegisterProgram("Shaders/BasicBlockDynamicLit.program"); renderer->RegisterProgram("Shaders/BasicBlockDynamicLit.program");
renderer->RegisterProgram("Shaders/BackFaceBlock.program"); renderer->RegisterProgram("Shaders/BackFaceBlock.program");
renderer->RegisterImage("Gfx/AmbientOcclusion.png"); renderer->RegisterImage("Gfx/AmbientOcclusion.png");
@ -69,6 +70,7 @@ namespace spades {
basicProgram = renderer->RegisterProgram("Shaders/BasicBlockPhys.program"); basicProgram = renderer->RegisterProgram("Shaders/BasicBlockPhys.program");
else else
basicProgram = renderer->RegisterProgram("Shaders/BasicBlock.program"); basicProgram = renderer->RegisterProgram("Shaders/BasicBlock.program");
depthonlyProgram = renderer->RegisterProgram("Shaders/BasicBlockDepthOnly.program");
dlightProgram = renderer->RegisterProgram("Shaders/BasicBlockDynamicLit.program"); dlightProgram = renderer->RegisterProgram("Shaders/BasicBlockDynamicLit.program");
backfaceProgram = renderer->RegisterProgram("Shaders/BackFaceBlock.program"); backfaceProgram = renderer->RegisterProgram("Shaders/BackFaceBlock.program");
aoImage = (GLImage *)renderer->RegisterImage("Gfx/AmbientOcclusion.png"); aoImage = (GLImage *)renderer->RegisterImage("Gfx/AmbientOcclusion.png");
@ -138,12 +140,50 @@ namespace spades {
void GLMapRenderer::Prerender() { void GLMapRenderer::Prerender() {
SPADES_MARK_FUNCTION(); SPADES_MARK_FUNCTION();
// nothing to do now (maybe depth-only pass?) // nothing to do now (maybe depth-only pass?)
GLProfiler profiler(device, "Prerender");
Vector3 eye = renderer->GetSceneDef().viewOrigin;
device->Enable(IGLDevice::CullFace, true);
device->Enable(IGLDevice::DepthTest, true);
device->ColorMask(false, false, false, false);
depthonlyProgram->Use();
static GLProgramAttribute positionAttribute("positionAttribute");
positionAttribute(depthonlyProgram);
device->EnableVertexAttribArray(positionAttribute(), true);
static GLProgramUniform projectionViewMatrix("projectionViewMatrix");
projectionViewMatrix(depthonlyProgram);
projectionViewMatrix.SetValue(renderer->GetProjectionViewMatrix());
RealizeChunks(eye);
// draw from nearest to farthest
int cx = (int)floorf(eye.x) / GLMapChunk::Size;
int cy = (int)floorf(eye.y) / GLMapChunk::Size;
int cz = (int)floorf(eye.z) / GLMapChunk::Size;
DrawColumnDepth(cx, cy, cz, eye);
for (int dist = 1; dist <= 128 / GLMapChunk::Size; dist++) {
for (int x = cx - dist; x <= cx + dist; x++) {
DrawColumnDepth(x, cy + dist, cz, eye);
DrawColumnDepth(x, cy - dist, cz, eye);
}
for (int y = cy - dist + 1; y <= cy + dist - 1; y++) {
DrawColumnDepth(cx + dist, y, cz, eye);
DrawColumnDepth(cx - dist, y, cz, eye);
}
}
device->EnableVertexAttribArray(positionAttribute(), false);
device->ColorMask(true, true, true, true);
} }
void GLMapRenderer::RenderSunlightPass() { void GLMapRenderer::RenderSunlightPass() {
SPADES_MARK_FUNCTION(); SPADES_MARK_FUNCTION();
GLProfiler profiler(device, "Map"); GLProfiler profiler(device, "Map");
Vector3 eye = renderer->GetSceneDef().viewOrigin; Vector3 eye = renderer->GetSceneDef().viewOrigin;
@ -342,6 +382,14 @@ namespace spades {
device->BindTexture(IGLDevice::Texture2D, 0); device->BindTexture(IGLDevice::Texture2D, 0);
} }
void GLMapRenderer::DrawColumnDepth(int cx, int cy, int cz, spades::Vector3 eye) {
cx &= numChunkWidth - 1;
cy &= numChunkHeight - 1;
for (int z = std::max(cz, 0); z < numChunkDepth; z++)
GetChunk(cx, cy, z)->RenderDepthPass();
for (int z = std::min(cz - 1, 63); z >= 0; z--)
GetChunk(cx, cy, z)->RenderDepthPass();
}
void GLMapRenderer::DrawColumnSunlight(int cx, int cy, int cz, spades::Vector3 eye) { void GLMapRenderer::DrawColumnSunlight(int cx, int cy, int cz, spades::Vector3 eye) {
cx &= numChunkWidth - 1; cx &= numChunkWidth - 1;
cy &= numChunkHeight - 1; cy &= numChunkHeight - 1;

View File

@ -40,6 +40,7 @@ namespace spades {
GLRenderer *renderer; GLRenderer *renderer;
IGLDevice *device; IGLDevice *device;
GLProgram *depthonlyProgram;
GLProgram *basicProgram; GLProgram *basicProgram;
GLProgram *dlightProgram; GLProgram *dlightProgram;
GLProgram *backfaceProgram; GLProgram *backfaceProgram;
@ -69,6 +70,7 @@ namespace spades {
void RealizeChunks(Vector3 eye); void RealizeChunks(Vector3 eye);
void DrawColumnDepth(int cx, int cy, int cz, Vector3 eye);
void DrawColumnSunlight(int cx, int cy, int cz, Vector3 eye); void DrawColumnSunlight(int cx, int cy, int cz, Vector3 eye);
void DrawColumnDLight(int cx, int cy, int cz, Vector3 eye, void DrawColumnDLight(int cx, int cy, int cz, Vector3 eye,
const std::vector<GLDynamicLight> &lights); const std::vector<GLDynamicLight> &lights);

View File

@ -609,6 +609,7 @@ namespace spades {
} }
modelRenderer->Prerender(); modelRenderer->Prerender();
device->DepthFunc(IGLDevice::LessOrEqual);
if (!sceneDef.skipWorld && mapRenderer) { if (!sceneDef.skipWorld && mapRenderer) {
mapRenderer->RenderSunlightPass(); mapRenderer->RenderSunlightPass();
} }