Added depth-only prepass for non-optimized
This commit is contained in:
parent
a13a77fc1d
commit
51474ad723
26
Resources/Shaders/BasicBlockDepthOnly.fs
Normal file
26
Resources/Shaders/BasicBlockDepthOnly.fs
Normal 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
|
||||||
|
}
|
||||||
|
|
2
Resources/Shaders/BasicBlockDepthOnly.program
Normal file
2
Resources/Shaders/BasicBlockDepthOnly.program
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Shaders/BasicBlockDepthOnly.fs
|
||||||
|
Shaders/BasicBlockDepthOnly.vs
|
35
Resources/Shaders/BasicBlockDepthOnly.vs
Normal file
35
Resources/Shaders/BasicBlockDepthOnly.vs
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user