Search in sources :

Example 6 with RenderableChunk

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

Example 7 with RenderableChunk

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

Example 8 with RenderableChunk

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;
}
Also used : CoreChunk(org.terasology.world.chunks.CoreChunk) BlockChange(org.terasology.world.propagation.BlockChange) Vector3i(org.terasology.math.geom.Vector3i) RenderableChunk(org.terasology.world.chunks.RenderableChunk) Block(org.terasology.world.block.Block)

Example 9 with RenderableChunk

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

Example 10 with RenderableChunk

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

Aggregations

RenderableChunk (org.terasology.world.chunks.RenderableChunk)14 ChunkMesh (org.terasology.rendering.primitives.ChunkMesh)8 Vector3i (org.terasology.math.geom.Vector3i)6 Vector3f (org.terasology.math.geom.Vector3f)5 CoreChunk (org.terasology.world.chunks.CoreChunk)3 Block (org.terasology.world.block.Block)2 BlockChange (org.terasology.world.propagation.BlockChange)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 Region3i (org.terasology.math.Region3i)1 ChunkView (org.terasology.world.ChunkView)1 Biome (org.terasology.world.biomes.Biome)1 BiomeChange (org.terasology.world.propagation.BiomeChange)1