use of org.terasology.world.chunks.RenderableChunk in project Terasology by MovingBlocks.
the class ShadowMapNode method process.
/**
* Re-positions the shadow map camera to loosely match the position of the main light (sun, moon), then
* writes depth information from that camera into a depth buffer, to be used later to create shadows.
*
* The loose match is to avoid flickering: the shadowmap only moves in steps while the main light actually
* moves continuously.
*
* This method is executed within a NodeTask in the Render Tasklist, but its calculations are executed
* only once per frame. I.e. in VR mode they are executed only when the left eye is processed. This is
* done in the assumption that we do not need to generate and use a shadow map for each eye as it wouldn't
* be noticeable.
*/
@Override
public void process() {
// TODO: remove this IF statement when VR is handled via parallel nodes, one per eye.
if (worldRenderer.isFirstRenderingStageForCurrentFrame()) {
PerformanceMonitor.startActivity("rendering/" + getUri());
// Actual Node Processing
// TODO: extract these calculation into a separate node.
positionShadowMapCamera();
int numberOfRenderedTriangles = 0;
int numberOfChunksThatAreNotReadyYet = 0;
final Vector3f cameraPosition = shadowMapCamera.getPosition();
shadowMapCamera.lookThrough();
// FIXME: storing chunksOpaqueShadow or a mechanism for requesting a chunk queue for nodes which calls renderChunks method?
while (renderQueues.chunksOpaqueShadow.size() > 0) {
RenderableChunk chunk = renderQueues.chunksOpaqueShadow.poll();
if (chunk.hasMesh()) {
final ChunkMesh chunkMesh = chunk.getMesh();
final Vector3f chunkPosition = chunk.getPosition().toVector3f();
numberOfRenderedTriangles += chunkMesh.render(OPAQUE, chunkPosition, cameraPosition);
} else {
numberOfChunksThatAreNotReadyYet++;
}
}
worldRenderer.increaseTrianglesCount(numberOfRenderedTriangles);
worldRenderer.increaseNotReadyChunkCount(numberOfChunksThatAreNotReadyYet);
PerformanceMonitor.endActivity();
}
}
use of org.terasology.world.chunks.RenderableChunk in project Terasology by MovingBlocks.
the class WorldReflectionNode method process.
/**
* Renders the landscape, reflected, into the buffers attached to the "engine:sceneReflected" FBO. It is used later,
* to render horizontal reflective surfaces, i.e. water.
*
* Notice that this method -does not- clear the FBO. The rendering takes advantage of the depth buffer to decide
* which pixel is in front of the one already stored in the buffer.
*
* See: https://en.wikipedia.org/wiki/Deep_image_compositing
*/
@Override
public void process() {
PerformanceMonitor.startActivity("rendering/" + getUri());
chunkMaterial.activateFeature(ShaderProgramFeature.FEATURE_USE_FORWARD_LIGHTING);
// Common Shader Parameters
chunkMaterial.setFloat("daylight", backdropProvider.getDaylight(), true);
chunkMaterial.setFloat("time", worldProvider.getTime().getDays(), true);
// Specific Shader Parameters
// TODO: This is necessary right now because activateFeature removes all material parameters.
// TODO: Remove this explicit binding once we get rid of activateFeature, or find a way to retain parameters through it.
chunkMaterial.setInt("textureAtlas", 0, true);
chunkMaterial.setInt("textureEffects", 1, true);
chunkMaterial.setInt("textureLava", 2, true);
if (isNormalMapping) {
chunkMaterial.setInt("textureAtlasNormal", 3, true);
if (isParallaxMapping) {
chunkMaterial.setInt("textureAtlasHeight", 4, true);
chunkMaterial.setFloat4("parallaxProperties", parallaxBias, parallaxScale, 0.0f, 0.0f, true);
}
}
chunkMaterial.setFloat("clip", 0.0f, true);
// Actual Node Processing
int numberOfRenderedTriangles = 0;
int numberOfChunksThatAreNotReadyYet = 0;
final Vector3f cameraPosition = activeCamera.getPosition();
while (renderQueues.chunksOpaqueReflection.size() > 0) {
RenderableChunk chunk = renderQueues.chunksOpaqueReflection.poll();
if (chunk.hasMesh()) {
final ChunkMesh chunkMesh = chunk.getMesh();
final Vector3f chunkPosition = chunk.getPosition().toVector3f();
chunkMesh.updateMaterial(chunkMaterial, chunkPosition, chunk.isAnimated());
numberOfRenderedTriangles += chunkMesh.render(OPAQUE, chunkPosition, cameraPosition);
} else {
numberOfChunksThatAreNotReadyYet++;
}
}
chunkMaterial.deactivateFeature(ShaderProgramFeature.FEATURE_USE_FORWARD_LIGHTING);
worldRenderer.increaseTrianglesCount(numberOfRenderedTriangles);
worldRenderer.increaseNotReadyChunkCount(numberOfChunksThatAreNotReadyYet);
PerformanceMonitor.endActivity();
}
use of org.terasology.world.chunks.RenderableChunk in project Terasology by MovingBlocks.
the class WorldProviderCoreImpl method setBlock.
@Override
public Block setBlock(Vector3i worldPos, Block type) {
/*
* Hint: This method has a benchmark available in the BenchmarkScreen, The screen can be opened ingame via the
* command "showSCreen BenchmarkScreen".
*/
Vector3i chunkPos = ChunkMath.calcChunkPos(worldPos);
CoreChunk chunk = chunkProvider.getChunk(chunkPos);
if (chunk != null) {
Vector3i blockPos = ChunkMath.calcBlockPos(worldPos);
Block oldBlockType = chunk.setBlock(blockPos, type);
if (oldBlockType != type) {
BlockChange oldChange = blockChanges.get(worldPos);
if (oldChange == null) {
blockChanges.put(worldPos, new BlockChange(worldPos, oldBlockType, type));
} else {
oldChange.setTo(type);
}
for (Vector3i pos : ChunkMath.getChunkRegionAroundWorldPos(worldPos, 1)) {
RenderableChunk dirtiedChunk = chunkProvider.getChunk(pos);
if (dirtiedChunk != null) {
dirtiedChunk.setDirty(true);
}
}
notifyBlockChanged(worldPos, type, oldBlockType);
}
return oldBlockType;
}
return null;
}
use of org.terasology.world.chunks.RenderableChunk in project Terasology by MovingBlocks.
the class HeadlessWorldRenderer method updateChunksInProximity.
/**
* Updates the list of chunks around the player.
*
* @param force Forces the update
* @return True if the list was changed
*/
public boolean updateChunksInProximity(boolean force) {
Vector3i newChunkPos = calcCamChunkOffset();
// TODO: This should actually be done based on events from the ChunkProvider on new chunk availability/old chunk removal
boolean chunksCurrentlyPending = false;
if (!newChunkPos.equals(chunkPos) || force || pendingChunks) {
Vector3i viewingDistance = config.getRendering().getViewDistance().getChunkDistance();
Region3i viewRegion = Region3i.createFromCenterExtents(newChunkPos, new Vector3i(viewingDistance.x / 2, viewingDistance.y / 2, viewingDistance.z / 2));
if (chunksInProximity.size() == 0 || force || pendingChunks) {
// just add all visible chunks
chunksInProximity.clear();
for (Vector3i chunkPosition : viewRegion) {
RenderableChunk c = chunkProvider.getChunk(chunkPosition);
if (c != null && worldProvider.getLocalView(c.getPosition()) != null) {
chunksInProximity.add(c);
} else {
chunksCurrentlyPending = true;
}
}
} else {
Region3i oldRegion = Region3i.createFromCenterExtents(chunkPos, new Vector3i(viewingDistance.x / 2, viewingDistance.y / 2, viewingDistance.z / 2));
Iterator<Vector3i> chunksForRemove = oldRegion.subtract(viewRegion);
// remove
while (chunksForRemove.hasNext()) {
Vector3i r = chunksForRemove.next();
RenderableChunk c = chunkProvider.getChunk(r);
if (c != null) {
chunksInProximity.remove(c);
c.disposeMesh();
}
}
// add
for (Vector3i chunkPosition : viewRegion) {
RenderableChunk c = chunkProvider.getChunk(chunkPosition);
if (c != null && worldProvider.getLocalView(c.getPosition()) != null) {
chunksInProximity.add(c);
} else {
chunksCurrentlyPending = true;
}
}
}
chunkPos.set(newChunkPos);
pendingChunks = chunksCurrentlyPending;
Collections.sort(chunksInProximity, new ChunkFrontToBackComparator());
return true;
}
return false;
}
use of org.terasology.world.chunks.RenderableChunk in project Terasology by MovingBlocks.
the class RenderableWorldImpl method generateVBOs.
@Override
public void generateVBOs() {
PerformanceMonitor.startActivity("Building Mesh VBOs");
ChunkMesh pendingMesh;
chunkMeshUpdateManager.setCameraPosition(playerCamera.getPosition());
for (RenderableChunk chunk : chunkMeshUpdateManager.availableChunksForUpdate()) {
if (chunk.hasPendingMesh() && chunksInProximityOfCamera.contains(chunk)) {
pendingMesh = chunk.getPendingMesh();
pendingMesh.generateVBOs();
if (chunk.hasMesh()) {
chunk.getMesh().dispose();
}
chunk.setMesh(pendingMesh);
chunk.setPendingMesh(null);
} else {
if (chunk.hasPendingMesh()) {
chunk.getPendingMesh().dispose();
chunk.setPendingMesh(null);
}
}
}
PerformanceMonitor.endActivity();
}
Aggregations