Castle Game EngineIntroduction Units Class Hierarchy Classes, Interfaces, Objects and Records Types Variables Constants Functions and Procedures Identifiers |
Unit CastleRenderer
Description
VRML/X3D low-level rendering (TGLRenderer). You usually don't want to use this renderer directly, you should rather use TCastleScene that wraps this renderer and gives you simple method to render whole scene.
The overview of this class can also be found in engine documentation [http://castle-engine.sourceforge.net/engine_doc.php] in chapter "OpenGL rendering", section "Basic OpenGL rendering".
Usage:
Call TGLRenderer.Prepare for all the states that you want to later render. The order of calling TGLRenderer.Prepare methods doesn't matter, also you are free to prepare states that you will not actually use later. Of course a state, once prepared, may be used in rendering as many times as you want.
It's important that you have to prepare every state that you plan to later render. During rendring the state must have exactly the same (fields, properties) values as when it was prepared. In particular, it must have the same pointers to nodes Last*/Active* and their contents also must be the same. TGLRenderer.Prepare may save some associations between objects and OpenGL resources, so it's important that the same pointer must always point to the same object (until it's unprepared).
TGLRenderer.Prepare requires active OpenGL context. It doesn't modify OpenGL state (only allocates some resources like texture names). It cannot be called inside a display list.
When you want to release resources, you should call TGLRenderer.Unprepare on nodes that you want to change or free. This should be used with nodes that were passed as Last*/Active* in some State for TGLRenderer.Prepare.
Note: before engine 2.0.0 release, it was allowed to free some VRML nodes before unpreparing them. This was depending on the fact that during unprepare we will not actually dereference pointers (not look at nodes contents etc.). This is forbidden since 2010-03-25, as it causes some difficult problems (like TGLRendererShaderProgram.Destroy really needs to access some VRML nodes), and was inherently unclean and unsafe (it's not a nice programming practice to have a pointers that may be invalid).
To start actual rendering, call TGLRenderer.RenderBegin. To end rendering, call TGLRenderer.RenderEnd. Between these calls, you should not touch OpenGL state yourself — the renderer may depend that every state change goes through it. At the end of TGLRenderer.RenderEnd, the OpenGL state is restored just as it was before TGLRenderer.RenderBegin.
Between TGLRenderer.RenderBegin and TGLRenderer.RenderEnd you should render the shapes by calling RenderShape.
Remember that you can render only shapes that have Shape.State prepared by TGLRenderer.Prepare.
Since the first prepare / render calls, this renderer assumes it's always called in the same OpenGL context. To break association with OpenGL context call TGLRenderer.UnprepareAll (this is like calling TGLRenderer.Unprepare on every prepared thing + clearing some remaining resources).
OpenGL state affecting VRML rendering:
Some OpenGL state is unconditionally reset by TGLRenderer.RenderBegin.
There's also some OpenGL state that we let affect our rendering. This allows you to customize rendering by using normal OpenGL commands.
First of all, current matrix values (MODELVIEW, PROJECTION and TEXTURE) affect our rendering as usual.
So you can move the rendered VRML model by normal OpenGL matrix transformations, you can even affect rendered texture coords by your own texture matrix etc.
Current glPolygonMode.
Of course for normal rendering you want to render polygons (both sides, GL_FRONT_AND_BACK) with GL_FILL. But you can change it to get wireframe model view.
Blending settings (GL_BLEND enabled state, glBlendFunc), and glDepthMask.
These are typically controlled by higher-level renderer (Scene) to allow rendering scenes with both tranparent and opaque objects. Only such higher-level renderer may control them, as only it controls the order of rendering shapes, which is important for rendering tranparent shapes.
Current GL_FOG_HINT.
Just like for any other OpenGL program, you may want to set this to GL_NICEST (if you have to render models that may look bad when fog is interpolated without perspective correction).
glFrontFace is assumed to be CCW (OpenGL default) but not manipulated by this unit anywhere.
So our normals passed to OpenGL always point from CCW side. Even if you supplied in VRML file normals pointing from CW (indicated e.g. by IndexedFaceSet.ccw = FALSE field in VRML 97), we will internally invert them and pass inverted ones to OpenGL. And when culling faces, we switch using glCullFace( GL_BACK / GL_FRONT) , not by switching front face.
Why so much work was done to always work with front face = CCW assumption? Because this is very handy when you render mirrors by using Scale(1, 1, -1) trick. See [http://www.opengl.org/resources/code/samples/mjktips/Reflect.html] and example program castle_game_engine/examples/vrml/plane_mirror_and_shadow.lpr . With such strange scale, CCW and CW invert places. Sides that were CCW normally are now CW. This means that you want to call glFrontFace(GL_CW) temporarily when rendering scene in the mirror. This way scene in the mirror will have correct normals and backface culling.
Since we don't touch glFrontFace anywhere, this is possible to you. And you can reuse resources for the scene in the mirror.
Rendered TrianglesCount and VerticesCount:
This renderer uses the same triangles and vertices counts as calculated by TAbstractGeometryNode.Triangulate, TAbstractGeometryNode.LocalTriangulate, TAbstractGeometryNode.TrianglesCount, TAbstractGeometryNode.VerticesCount, with OverTriangulate = True .
Note that it doesn't mean that we actually call TAbstractGeometryNode.Triangulate for VRML rendering. In fact, currently we don't, and it allows us to be much faster (for starters, rendering by indexes, or quad strips, that would not be possible by generic implementation calling TAbstractGeometryNode.Triangulate). But our rendering methods generate the same triangles as TAbstractGeometryNode.Triangulate.
Although for debug purposes, we have a renderer using TShape.LocalTriangulate, see notes about USE_VRML_TRIANGULATION in the source code.
Uses
Overview
Classes, Interfaces, Objects and Records
Types
Constants
Variables
Description
Types
TShadersRendering = (...); |
Values
-
srDisable:
-
srWhenRequired:
-
srAlways:
|
TCullFace = (...); |
Faces to cull (make invisible) during VRML/X3D rendering.
Values
|
TBumpMapping = CastleRendererInternalShader.TBumpMapping; |
|
TLightRenderEvent = CastleRendererInternalLights.TLightRenderEvent; |
|
TRenderingMode = (...); |
TRenderingAttributes.Mode possible values.
Values
-
rmFull: Normal rendering features. Everything is enabled (as long as other TRenderingAttributes settings allow them).
-
rmPureGeometry: Pure geometry is rendered, without any colors, materials, lights, textures. Only the geometry primitives are rendered. We still set correct modelview matrix transformations, control face culling and depth test and such. The idea is that we "hit" the same pixels as normal rendering (with the exception of alpha test textures, that are not used for pure geometry rendering — for now). But we do absolutely nothing to set a particular pixel color. Which means that the caller controls the color (by default, if lighting and everything else is disabled, you just get solid look with color from last glColor).
For example, Renderer will not set any color (no glColor calls), will not set any material (no glMaterial calls), will not set any texture coordinates and will not bind any texture, fog and such.
This is useful for special tricks, in particular to draw the geometry into stencil buffer. Another example of use is to render plane-projected shadows, see castle_game_engine/examples/vrml/plane_projected_shadow_demo.lpr, where you have to draw the model with pure black color.
-
rmDepth: Only the rendering fetures that affect depth buffer work reliably, everything else is undefined (and works as fast as possible). This is suitable if you render only to depth buffer, like for shadow maps.
It's quite similar to rmPureGeometry, except alpha testing must work, so (at least some) textures must be applied over the model. Also, contrary to rmPureGeometry, various features (like fixed-function lighting state) are simply forcibly disabled (instead of letting caller to set OpenGL state for them).
|
TVboType = (...); |
Values
-
vtCoordinate:
-
vtAttribute:
-
vtIndex:
|
TShapeCacheList = specialize TFPGObjectList<TShapeCache>; |
|
TLineType = (...); |
Line types (patterns). For ease of implementation, ordered exactly like VRML/X3D LineProperties.linetype field.
Values
-
ltSolid:
-
ltDashed:
-
ltDotted:
-
ltDashedDotted:
-
ltDashDotDot:
|
Constants
BumpMappingNames: array [TBumpMapping] of string =
( 'None',
'Basic',
'Parallax',
'Steep Parallax',
'Steep Parallax With Self-Shadowing' ); |
|
Variables
LogRendererCache: boolean = false; |
Log renderer cache events. Allows to see how the cache performs. A lot of log messages.
Meaningful only if you initialized log (see CastleLog unit) by InitializeLog first.
|
LogRenderer: boolean = false; |
Log various renderer information.
Meaningful only if you initialized log (see CastleLog unit) by InitializeLog first.
|
Generated by PasDoc 0.13.0 on 2014-08-30 12:10:38
|