use of org.terasology.rendering.primitives.ChunkMesh in project Terasology by MovingBlocks.
the class RenderableWorldImpl method pregenerateChunks.
/**
* @return true if pregeneration is complete
*/
@Override
public boolean pregenerateChunks() {
boolean pregenerationIsComplete = true;
chunkProvider.completeUpdate();
chunkProvider.beginUpdate();
RenderableChunk chunk;
ChunkMesh newMesh;
ChunkView localView;
for (Vector3i chunkCoordinates : calculateRenderableRegion(renderingConfig.getViewDistance())) {
chunk = chunkProvider.getChunk(chunkCoordinates);
if (chunk == null) {
pregenerationIsComplete = false;
} else if (chunk.isDirty()) {
localView = worldProvider.getLocalView(chunkCoordinates);
if (localView == null) {
continue;
}
chunk.setDirty(false);
newMesh = chunkTessellator.generateMesh(localView, ChunkConstants.SIZE_Y, 0);
newMesh.generateVBOs();
if (chunk.hasMesh()) {
chunk.getMesh().dispose();
}
chunk.setMesh(newMesh);
pregenerationIsComplete = false;
break;
}
}
return pregenerationIsComplete;
}
use of org.terasology.rendering.primitives.ChunkMesh in project Terasology by MovingBlocks.
the class RenderableWorldImpl method queueVisibleChunks.
/**
* Updates the currently visible chunks (in sight of the player).
*/
@Override
public int queueVisibleChunks(boolean isFirstRenderingStageForCurrentFrame) {
PerformanceMonitor.startActivity("Queueing Visible Chunks");
statDirtyChunks = 0;
statVisibleChunks = 0;
statIgnoredPhases = 0;
int processedChunks = 0;
int chunkCounter = 0;
ChunkMesh mesh;
boolean isDynamicShadows = renderingConfig.isDynamicShadows();
for (RenderableChunk chunk : chunksInProximityOfCamera) {
if (isChunkValidForRender(chunk)) {
mesh = chunk.getMesh();
if (isDynamicShadows && isFirstRenderingStageForCurrentFrame && chunkCounter < maxChunksForShadows && isChunkVisibleFromMainLight(chunk)) {
if (triangleCount(mesh, ChunkMesh.RenderPhase.OPAQUE) > 0) {
renderQueues.chunksOpaqueShadow.add(chunk);
} else {
statIgnoredPhases++;
}
}
if (isChunkVisible(chunk)) {
if (triangleCount(mesh, ChunkMesh.RenderPhase.OPAQUE) > 0) {
renderQueues.chunksOpaque.add(chunk);
} else {
statIgnoredPhases++;
}
if (triangleCount(mesh, ChunkMesh.RenderPhase.REFRACTIVE) > 0) {
renderQueues.chunksAlphaBlend.add(chunk);
} else {
statIgnoredPhases++;
}
if (triangleCount(mesh, ChunkMesh.RenderPhase.ALPHA_REJECT) > 0 && chunkCounter < MAX_BILLBOARD_CHUNKS) {
renderQueues.chunksAlphaReject.add(chunk);
} else {
statIgnoredPhases++;
}
statVisibleChunks++;
if (statVisibleChunks < MAX_ANIMATED_CHUNKS) {
chunk.setAnimated(true);
} else {
chunk.setAnimated(false);
}
}
if (isChunkVisibleReflection(chunk)) {
renderQueues.chunksOpaqueReflection.add(chunk);
}
// Process all chunks in the area, not only the visible ones
if (isFirstRenderingStageForCurrentFrame && (chunk.isDirty() || !chunk.hasMesh())) {
statDirtyChunks++;
chunkMeshUpdateManager.queueChunkUpdate(chunk);
processedChunks++;
}
}
chunkCounter++;
}
PerformanceMonitor.endActivity();
return processedChunks;
}
use of org.terasology.rendering.primitives.ChunkMesh in project Terasology by MovingBlocks.
the class AlphaRejectBlocksNode method process.
/**
* Renders the world's semi-transparent blocks, i.e. tree foliage and terrain plants.
* Does not render fully opaque blocks, i.e. the typical landscape blocks.
*
* Takes advantage of the two methods
*
* - WorldRenderer.increaseTrianglesCount(int)
* - WorldRenderer.increaseNotReadyChunkCount(int)
*
* to publish some statistics over its own activity.
*/
@Override
public void process() {
PerformanceMonitor.startActivity("rendering/" + getUri());
chunkMaterial.activateFeature(ShaderProgramFeature.FEATURE_ALPHA_REJECT);
// Common Shader Parameters
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 (normalMappingIsEnabled) {
chunkMaterial.setInt("textureAtlasNormal", 3, true);
if (parallaxMappingIsEnabled) {
chunkMaterial.setInt("textureAtlasHeight", 4, true);
chunkMaterial.setFloat4("parallaxProperties", parallaxBias, parallaxScale, 0.0f, 0.0f, true);
}
}
chunkMaterial.setFloat("clip", 0.0f, true);
// Actual Node Processing
final Vector3f cameraPosition = activeCamera.getPosition();
int numberOfRenderedTriangles = 0;
int numberOfChunksThatAreNotReadyYet = 0;
while (renderQueues.chunksAlphaReject.size() > 0) {
RenderableChunk chunk = renderQueues.chunksAlphaReject.poll();
if (chunk.hasMesh()) {
final ChunkMesh chunkMesh = chunk.getMesh();
final Vector3f chunkPosition = chunk.getPosition().toVector3f();
chunkMesh.updateMaterial(chunkMaterial, chunkPosition, chunk.isAnimated());
numberOfRenderedTriangles += chunkMesh.render(ALPHA_REJECT, chunkPosition, cameraPosition);
} else {
// TODO: verify - should we count them only in ChunksOpaqueNode?
numberOfChunksThatAreNotReadyYet++;
}
}
worldRenderer.increaseTrianglesCount(numberOfRenderedTriangles);
worldRenderer.increaseNotReadyChunkCount(numberOfChunksThatAreNotReadyYet);
chunkMaterial.deactivateFeature(ShaderProgramFeature.FEATURE_ALPHA_REJECT);
PerformanceMonitor.endActivity();
}
use of org.terasology.rendering.primitives.ChunkMesh 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.rendering.primitives.ChunkMesh 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();
}
Aggregations