Search in sources :

Example 1 with ChunkMesh

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;
}
Also used : ChunkMesh(org.terasology.rendering.primitives.ChunkMesh) RenderableChunk(org.terasology.world.chunks.RenderableChunk) Vector3i(org.terasology.math.geom.Vector3i) ChunkView(org.terasology.world.ChunkView)

Example 2 with ChunkMesh

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;
}
Also used : ChunkMesh(org.terasology.rendering.primitives.ChunkMesh) RenderableChunk(org.terasology.world.chunks.RenderableChunk)

Example 3 with ChunkMesh

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();
}
Also used : ChunkMesh(org.terasology.rendering.primitives.ChunkMesh) Vector3f(org.terasology.math.geom.Vector3f) RenderableChunk(org.terasology.world.chunks.RenderableChunk)

Example 4 with ChunkMesh

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();
    }
}
Also used : ChunkMesh(org.terasology.rendering.primitives.ChunkMesh) Vector3f(org.terasology.math.geom.Vector3f) RenderableChunk(org.terasology.world.chunks.RenderableChunk)

Example 5 with ChunkMesh

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();
}
Also used : ChunkMesh(org.terasology.rendering.primitives.ChunkMesh) Vector3f(org.terasology.math.geom.Vector3f) RenderableChunk(org.terasology.world.chunks.RenderableChunk)

Aggregations

ChunkMesh (org.terasology.rendering.primitives.ChunkMesh)9 RenderableChunk (org.terasology.world.chunks.RenderableChunk)8 Vector3f (org.terasology.math.geom.Vector3f)5 Vector2f (org.terasology.math.geom.Vector2f)1 Vector3i (org.terasology.math.geom.Vector3i)1 ChunkView (org.terasology.world.ChunkView)1