/* * Copyright 2017 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.rendering.world; import org.terasology.math.geom.Vector3f; import org.terasology.math.geom.Vector3i; import org.terasology.rendering.assets.material.Material; import org.terasology.rendering.cameras.Camera; import org.terasology.rendering.cameras.SubmersibleCamera; import org.terasology.rendering.world.viewDistance.ViewDistance; /** * Implementations of this class are responsible for rendering the whole 3D world, * inclusive of background. * * While 2D GUIs are dealt with elsewhere, it is in the remit of implementations of this class * to provide Augmented-Reality-Style user interfaces, i.e. boxes around selected objects * 3d-positioned labels above player's heads or held-in-hand tools. * * If this is the first time you look into this interface, you might want to start with * the update and render methods as they are central to a rendering implementation. */ public interface WorldRenderer { float BLOCK_LIGHT_POW = 0.96f; float BLOCK_LIGHT_SUN_POW = 0.96f; float BLOCK_INTENSITY_FACTOR = 0.7f; float getSecondsSinceLastFrame(); Material getMaterial(String assetId); boolean isFirstRenderingStageForCurrentFrame(); /** * This method is triggered when a chunk has been loaded. * * @param chunkPos a Vector3i providing the coordinates of the chunk that has just been loaded. */ void onChunkLoaded(Vector3i chunkPos); /** * This method is triggered when a chunk has been unloaded. * * @param chunkPos a Vector3i providing the coordinates of the chunk that has just been unloaded. */ void onChunkUnloaded(Vector3i chunkPos); /** * Lists the stages the rendering engine may go through on a given frame. * * At the time of the writing the rendering engine works in two conceptual modes: mono or stereo. * * In mono mode, used to render to a standard monitor, the rendering engine goes through * a single rendering stage every frame, called MONO. * * Stereo mode is for stereoscopic displays: every frame the rendering engine first goes through * the LEFT_EYE rendering stage and then the RIGHT_EYE rendering stage. Each stage produces * an image and the two images are then combined at the end of the RIGHT_EYE stage. * * Notice that the renderer has no explicit notion of mono/stereo. It only knows which stage is the current one. */ enum RenderingStage { MONO, LEFT_EYE, RIGHT_EYE } /** * Retrieves the camera the world is being rendered from. * * @return a SubmersibleCamera object */ SubmersibleCamera getActiveCamera(); /** * Retrieves the camera positioned and oriented to look down on the world from the point of view * of the main light source. This camera is used to produce the shadow map. * * @return a Camera object */ Camera getLightCamera(); /** * Called potentially multiple times per frame, this method allows the renderer to trigger the update * of any data it requires with a higher frequency than just once per frame. * * This is usually not necessary. Normally a renderer is interested in data updated with the same frequency * as it renders to the display, once per frame. As such, implementations might want to leave this method * fairly lightweight, with most updates occurring somewhere at the beginning of the render() method execution * instead. * * However, there are effects for which it would be beneficial to have more frequent updates, for example * multi-segment motion blur. * * @param delta The elapsed time, in seconds, since the previous update. */ void update(float delta); /** * Increase the triangles count, eventually retrieved through the getMetrics() method. * * @param increase An integer representing the triangle count increase. */ void increaseTrianglesCount(int increase); /** * Increases the count of chunks that are not ready yet. The count is eventually retrieved through the getMetrics() method. * * @param increase An integer representing the not-ready chunk count increase. */ void increaseNotReadyChunkCount(int increase); /** * This method triggers the execution of the rendering pipeline and, eventually, sends the output to the display * or to a file, when grabbing a screenshot. * * @param renderingStage "MONO" for standard rendering and "LEFT_EYE" or "RIGHT_EYE" for stereoscopic displays. */ void render(RenderingStage renderingStage); /** * Request a refresh of the render task list. The refresh takes place before the next frame. */ void requestTaskListRefresh(); /** * Gives the chance to an implementation to deal with anything that might need a more careful disposal * than standard garbage collection would afford. */ void dispose(); /** * Used only during the early part of the WorldRenderer lifecycle, this method triggers the loading of * chunks around the camera and the generation of their meshes. * * @return Returns True if all necessary chunks have been loaded and their meshes have been generated, False otherwise. */ // TODO: it might be desirable to separate the loading of chunks and mesh generation. The former may concern // TODO: systems dealing with beyond-the-horizon simulations. The latter usually only concerns the renderer. boolean pregenerateChunks(); /** * Sets how far from the camera chunks are kept in memory and displayed. * * @param viewDistance a viewDistance value. */ void setViewDistance(ViewDistance viewDistance); /** * Returns the intensity of the light at a given location due to the combination of main light (sun or moon) * and in-scene light sources, i.e. torches. * * @param coordinates a Vector3f providing the coordinates of the block to calculate the light intensity from. * @return a float value representing the intensity of the main light and in-scene lights combined */ float getRenderingLightIntensityAt(Vector3f coordinates); /** * Returns the intensity of the main light (sun or moon) at the given location * * @param coordinates a vector3f providing the coordinates of the block to sample the intensity of the main light from * @return a float value representing the intensity of the main light at the given coordinates */ float getMainLightIntensityAt(Vector3f coordinates); /** * Returns the intensity of the light at the given location due to in-scene sources, * * @param coordinates a vector3f providing the coordinates of the block to sample the intensity of in-scene sources from * @return a float value representing the total light intensity of the in-scene sources, at the given coordinates */ float getBlockLightIntensityAt(Vector3f coordinates); /** * Returns the time-smoothed intensity of the main light (sun or moon) at the camera's location * * @return a float value representing the time-smoothed light intensity of the main light at the camera's coordinates */ float getTimeSmoothedMainLightIntensity(); /** * Returns the current tick, an always progressing time value animations are based on. * * @return the number of milliseconds since rendering started */ float getMillisecondsSinceRenderingStart(); /** * Returns the current rendering stage, i.e. mono, left eye or right eye. * * @return the current WorldRenderingStage */ RenderingStage getCurrentRenderStage(); /** * Returns a string containing a number of metrics in the format: * * metric label 1: value1\n * metric label 2: value2\n * . * . * metric label N: value3\n * * @return a string containing metrics labels and associated values, separated by new lines. */ // TODO: transform this to return an object or a map. Consumers would then take care of formatting. String getMetrics(); }