00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "renderserver.h"
00024 #include <oxygen/sceneserver/sceneserver.h>
00025 #include <oxygen/sceneserver/scene.h>
00026 #include <oxygen/sceneserver/camera.h>
00027 #include <kerosin/openglserver/openglserver.h>
00028 #include <kerosin/sceneserver/staticmesh.h>
00029 #include <kerosin/sceneserver/light.h>
00030 #include <zeitgeist/logserver/logserver.h>
00031
00032 using namespace boost;
00033 using namespace oxygen;
00034 using namespace kerosin;
00035 using namespace salt;
00036 using namespace zeitgeist;
00037
00038 RenderServer::RenderServer() : Leaf()
00039 {
00040 }
00041
00042 RenderServer::~RenderServer()
00043 {
00044 }
00045
00046 void
00047 RenderServer::OnLink()
00048 {
00049
00050 mSceneServer = shared_dynamic_cast<SceneServer>
00051 (GetCore()->Get("/sys/server/scene"));
00052
00053 if (mSceneServer.get() == 0)
00054 {
00055 GetLog()->Error()
00056 << "(RenderServer) ERROR: SceneServer not found\n";
00057 }
00058
00059
00060 mOpenGLServer = shared_dynamic_cast<OpenGLServer>
00061 (GetCore()->Get("sys/server/opengl"));
00062
00063 if (mOpenGLServer.get() == 0)
00064 {
00065 GetLog()->Error()
00066 << "(RenderServer) ERROR: OpenGLServer not found\n";
00067 } else
00068 {
00069 mAmbientVP = 0;
00070 #if 0
00071 mAmbientVP = mOpenGLServer->LoadARBVertexProgram
00072 ("/sys/program/ambient.vp");
00073 if (mAmbientVP == 0)
00074 {
00075 GetLog()->Error()
00076 << "(RenderServer) ERROR: Could not load vertex program\n";
00077 }
00078 #endif
00079 }
00080 }
00081
00082 void
00083 RenderServer::OnUnlink()
00084 {
00085 mSceneServer.reset();
00086 mOpenGLServer.reset();
00087 mActiveScene.reset();
00088 }
00089
00090 bool
00091 RenderServer::GetActiveScene()
00092 {
00093 if (mSceneServer.get() == 0)
00094 {
00095 mActiveScene.reset();
00096 }
00097
00098 mActiveScene = mSceneServer->GetActiveScene();
00099
00100 if (mActiveScene.get() == 0)
00101 {
00102 GetLog()->Error() <<
00103 "(RenderServer) ERROR: found no active scene\n";
00104 return false;
00105 }
00106
00107 return true;
00108 }
00109
00110 void
00111 RenderServer::RenderFancyLighting(const salt::Frustum& ,
00112 boost::shared_ptr<oxygen::Camera>& ,
00113 TLeafList& , TLeafList& ,
00114 TLeafList& )
00115
00116 {
00117 #if 0
00118 glEnable(GL_VERTEX_PROGRAM_ARB);
00119 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, mAmbientVP);
00120
00121 glColor3f(0.1f,0.1f,0.1f);
00122 mActiveScene->RenderAmbient();
00123
00124
00125 glBlendFunc(GL_ONE, GL_ONE);
00126 glEnable(GL_BLEND);
00127
00128
00129 glDepthMask(0);
00130 glDepthFunc(GL_EQUAL);
00131
00132 for (TLeafList::iterator i=myLights.begin(); i != myLights.end(); ++i)
00133 {
00134 shared_ptr<Light> light = shared_static_cast<Light>(*i);
00135
00136
00137 if (frustum.Intersects(light->GetWorldBoundingBox())!=Frustum::FS_OUTSIDE)
00138 {
00139 for (TLeafList::iterator j=visibleMeshes.begin(); j != visibleMeshes.end(); ++j)
00140 {
00141 shared_ptr<StaticMesh> mesh = shared_static_cast<StaticMesh>(*j);
00142
00143
00144 if (light->GetWorldBoundingBox().Intersects(mesh->GetWorldBoundingBox()))
00145 {
00146 Matrix toObjectSpace;
00147 toObjectSpace.Identity();
00148 toObjectSpace = mesh->GetWorldTransform();
00149 toObjectSpace.InvertRotationMatrix();
00150
00151 light->Prepare();
00152 Vector3f lightPos = toObjectSpace.Transform(light->GetWorldTransform().Pos());
00153 Vector3f viewPos = toObjectSpace.Transform(camera->GetWorldTransform().Pos());
00154 glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, lightPos.x(), lightPos.y(), lightPos.z(), 1.0f);
00155 glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1, viewPos.x(), viewPos.y(), viewPos.z(), 1.0f);
00156 light->RenderLitMesh(shared_static_cast<StaticMesh>(*j));
00157 }
00158 }
00159 }
00160 }
00161
00162 glDisable(GL_BLEND);
00163 glDepthMask(1);
00164
00165 glActiveTextureARB(GL_TEXTURE0_ARB);
00166 glDisable(GL_TEXTURE_2D);
00167 glActiveTextureARB(GL_TEXTURE1_ARB);
00168 glDisable(GL_TEXTURE_2D);
00169 glActiveTextureARB(GL_TEXTURE2_ARB);
00170 glDisable(GL_TEXTURE_2D);
00171
00172 glEnable(GL_VERTEX_PROGRAM_ARB);
00173 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, mAmbientVP);
00174
00175
00176 mActiveScene->Render();
00177
00178 glDisable(GL_VERTEX_PROGRAM_ARB);
00179 #endif
00180 }
00181
00182 void
00183 RenderServer::Render()
00184 {
00185 if (! GetActiveScene())
00186 {
00187 return;
00188 }
00189
00190
00191 shared_ptr<Camera> camera =
00192 shared_static_cast<Camera>(mActiveScene->GetChildOfClass("Camera", true));
00193
00194 if (camera.get() == 0)
00195 {
00196 GetLog()->Error()
00197 << "(RenderServer) ERROR: found no camera node in the active scene\n";
00198 return;
00199 }
00200
00201 glClearColor(0,0,0,0);
00202 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00203 glColor3f(1,1,1);
00204
00205
00206 BindCamera(camera);
00207
00208 #if 0
00209
00210 Frustum frustum;
00211 camera->DescribeFrustum(frustum);
00212
00213
00214 TLeafList myLights;
00215 TLeafList allMeshes;
00216 TLeafList visibleMeshes;
00217
00218 mActiveScene->GetChildrenSupportingClass("Light", myLights, true);
00219 mActiveScene->GetChildrenSupportingClass("StaticMesh", allMeshes, true);
00220
00221 TLeafList::iterator i;
00222 for (i = allMeshes.begin(); i != allMeshes.end(); ++i)
00223 {
00224
00225 if (frustum.Intersects(shared_static_cast<StaticMesh>(*i)->GetWorldBoundingBox())!=Frustum::FS_OUTSIDE)
00226 {
00227 visibleMeshes.push_back(*i);
00228 }
00229 }
00230 #endif
00231
00232
00233
00234
00235 glEnable(GL_DEPTH_TEST);
00236 glDepthFunc(GL_LESS);
00237 glEnable(GL_CULL_FACE);
00238 glCullFace(GL_BACK);
00239
00240 TLeafList lights;
00241 mActiveScene->ListChildrenSupportingClass<Light>(lights,true);
00242
00243 if (lights.size() == 0)
00244 {
00245
00246 glDisable(GL_LIGHTING);
00247 } else
00248 {
00249 glEnable(GL_LIGHTING);
00250 glShadeModel (GL_SMOOTH);
00251
00252
00253 for (
00254 TLeafList::iterator iter = lights.begin();
00255 iter != lights.end();
00256 ++iter
00257 )
00258 {
00259 (shared_static_cast<Light>(*iter))->Prepare();
00260 }
00261 }
00262
00263
00264 RenderScene(mActiveScene);
00265
00266
00267 glDisable(GL_LIGHTING);
00268
00269 #if 0
00270
00271 const bool doFancyLighting = false;
00272
00273 if (doFancyLighting)
00274 {
00275 RenderFancyLighting(frustum, camera, myLights, allMeshes, visibleMeshes);
00276 }
00277 else
00278 #endif
00279 }
00280
00281 void
00282 RenderServer::RenderScene(boost::shared_ptr<BaseNode> node)
00283 {
00284
00285 shared_ptr<RenderNode> renderNode = shared_dynamic_cast<RenderNode>(node);
00286 if (renderNode.get() != 0)
00287 {
00288 glPushMatrix();
00289 glMultMatrixf(node->GetWorldTransform().m);
00290
00291 renderNode->RenderInternal();
00292
00293 glPopMatrix();
00294 }
00295
00296
00297 for (TLeafList::iterator i = node->begin(); i!= node->end(); ++i)
00298 {
00299 shared_ptr<BaseNode> node = shared_dynamic_cast<BaseNode>(*i);
00300 if (node.get() == 0)
00301 {
00302 continue;
00303 }
00304
00305 RenderScene(node);
00306 }
00307 }
00308
00309 void
00310 RenderServer::BindCamera(boost::shared_ptr<Camera>& camera)
00311 {
00312 camera->Bind();
00313
00314
00315 glViewport(
00316 camera->GetViewportX(),
00317 camera->GetViewportY(),
00318 camera->GetViewportWidth(),
00319 camera->GetViewportHeight()
00320 );
00321
00322
00323 glDepthRange(0, 1);
00324
00325
00326 glMatrixMode(GL_PROJECTION);
00327 glLoadIdentity();
00328 glMultMatrixf(camera->GetProjectionTransform().m);
00329
00330
00331 glMatrixMode(GL_MODELVIEW);
00332 glLoadIdentity();
00333 glMultMatrixf(camera->GetViewTransform().m);
00334 }