Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

renderserver.cpp

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
00002 
00003 this file is part of rcssserver3D
00004 Fri May 9 2003
00005 Copyright (C) 2002,2003 Koblenz University
00006 Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group
00007 $Id: renderserver.cpp,v 1.20 2004/12/30 15:53:47 rollmark Exp $
00008 
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of the GNU General Public License as published by
00011 the Free Software Foundation; version 2 of the License.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with this program; if not, write to the Free Software
00020 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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     // setup SceneServer reference
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     // setup OpenGLServer reference
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& /*frustum*/,
00112                                   boost::shared_ptr<oxygen::Camera>& /*camera*/,
00113                                   TLeafList& /*myLights*/, TLeafList& /*allMeshes*/,
00114                                   TLeafList& /*visibleMeshes*/)
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     // render lights
00125     glBlendFunc(GL_ONE, GL_ONE);
00126     glEnable(GL_BLEND);
00127     //glEnable(GL_ALPHA_TEST);
00128     //glAlphaFunc(GL_GREATER, 0.0f);
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             // only render the light if it is visible
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                             // we only have to render meshes, whose bounding volume intersects the light volume
00144                             if (light->GetWorldBoundingBox().Intersects(mesh->GetWorldBoundingBox()))
00145                                 {
00146                                     Matrix   toObjectSpace;
00147                                     toObjectSpace.Identity();
00148                                     toObjectSpace = mesh->GetWorldTransform();
00149                                     toObjectSpace.InvertRotationMatrix();
00150                                     //light->GetWorldTransform().Pos().Dump();
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     // standard rendering
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     // get a camera to render with
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     // set the view transformation
00206     BindCamera(camera);
00207 
00208 #if 0
00209     // get the view frustum from the camera
00210     Frustum frustum;
00211     camera->DescribeFrustum(frustum);
00212 
00213     // cull lights and geometries against the frustum
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             // try to cull meshes, which are outside the viewing frustum
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     // actual rendering
00233 
00234     // ambient pass
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             // no lights in the scene, disable lighting
00246             glDisable(GL_LIGHTING);
00247         } else
00248             {
00249                 glEnable(GL_LIGHTING);
00250                 glShadeModel (GL_SMOOTH);
00251 
00252                 // prepare all lights
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     // standard rendering
00264     RenderScene(mActiveScene);
00265 
00266     // reset GL lights
00267     glDisable(GL_LIGHTING);
00268 
00269 #if 0
00270     // test for fancy lighting support - disabled for now
00271     const bool doFancyLighting = false; /*openglServer->SupportsFancyLighting()*/
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     // test for and render using a RenderNode
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     // traverse the the hierarchy
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     // adjust the viewport
00315     glViewport(
00316                camera->GetViewportX(),
00317                camera->GetViewportY(),
00318                camera->GetViewportWidth(),
00319                camera->GetViewportHeight()
00320                );
00321 
00322     // set depth range
00323     glDepthRange(0, 1);
00324 
00325     // setup the projection matrix
00326     glMatrixMode(GL_PROJECTION);
00327     glLoadIdentity();
00328     glMultMatrixf(camera->GetProjectionTransform().m);
00329 
00330     // initialize the modelview stack
00331     glMatrixMode(GL_MODELVIEW);
00332     glLoadIdentity();
00333     glMultMatrixf(camera->GetViewTransform().m);
00334 }

Generated on Thu Apr 6 15:25:39 2006 for rcssserver3d by  doxygen 1.4.4