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

openglserver.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: openglserver.cpp,v 1.15 2004/12/06 08:41:16 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 "openglserver.h"
00024 #include <SDL/SDL.h>
00025 #include <zeitgeist/scriptserver/scriptserver.h>
00026 #include <zeitgeist/fileserver/fileserver.h>
00027 #include <zeitgeist/logserver/logserver.h>
00028 
00029 using namespace std;
00030 
00031 namespace kerosin
00032 {
00033   class MapHolder
00034   {
00035   public:
00037 #if HAVE_HASH_MAP
00038     typedef hash_map<string, unsigned int> TProgramCache;
00039 #else
00040     typedef map<string, unsigned int> TProgramCache;
00041 #endif
00042     TProgramCache mPrograms;
00043   };
00044 }
00045 
00046 using namespace boost;
00047 using namespace kerosin;
00048 using namespace zeitgeist;
00049 
00050 OpenGLServer::OpenGLServer() : Leaf(), mExtensionReg(new GLExtensionReg()),
00051                                mWantsToQuit(false), mHolder( new MapHolder() )
00052 {
00053 }
00054 
00055 OpenGLServer::~OpenGLServer()
00056 {
00057     SDL_Quit();
00058 }
00059 
00060 boost::shared_ptr<GLExtensionReg> OpenGLServer::GetExtensionReg() const
00061 {
00062     return mExtensionReg;
00063 }
00064 
00065 void OpenGLServer::Quit()
00066 {
00067     mWantsToQuit = true;
00068 }
00069 
00070 bool OpenGLServer::WantsToQuit() const
00071 {
00072     return mWantsToQuit;
00073 }
00074 
00075 void OpenGLServer::Update()
00076 {
00077     // Our SDL event placeholder.
00078     SDL_Event event;
00079 
00080     // Grab all the events off the queue.
00081     while( SDL_PollEvent( &event ) )
00082         {
00083         }
00084 }
00085 
00086 void OpenGLServer::SwapBuffers() const
00087 {
00088     SDL_GL_SwapBuffers();
00089 }
00090 
00091 unsigned int OpenGLServer::LoadARBProgram(GLenum /*target*/, const char* /*fileName*/)
00092 {
00093 #if 0
00094     // only try to load stuff if the extension is supported
00095     if (!mExtensionReg->Has_GL_ARB_vertex_program())
00096         {
00097             return 0;
00098         }
00099 
00100     // before actually loading, try the cache
00101     MapHolder::TProgramCache::iterator entry = mHolder->mPrograms.find(fileName);
00102 
00103     if (entry != mHolder->mPrograms.end())
00104         {
00105             // we already have a match
00106             return (*entry).second;
00107         }
00108 
00109     unsigned int id = 0;
00110 
00111     // open file
00112     shared_ptr<FileServer> fileServer = shared_static_cast<FileServer>(GetCore()->Get("/sys/server/file"));
00113     salt::RFile *file = fileServer->Open(fileName);
00114 
00115     if (!file) return 0;
00116 
00117     unsigned char *buffer = new unsigned char[file->Size()+1];
00118     file->Read(buffer, file->Size());
00119 
00120     glGenProgramsARB(1, &id);
00121     glBindProgramARB(target, id);
00122 
00123     // try to load the actual program
00124     glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB, file->Size(), buffer);
00125 
00126     // free memory
00127     delete file;
00128     delete []buffer;
00129 
00130     const unsigned char* error = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
00131 
00132     // if an error occured, display error message
00133     if (error[0] != 0)
00134         {
00135             int i;
00136             glDeleteProgramsARB(1, &id);
00137             glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &i);
00138             GetCore()->GetLogServer()->Error() << "ERROR: Loading ARB program (Pos: " << i << ")..." << endl;
00139             GetCore()->GetLogServer()->Error() << "  => " << error << endl;
00140             return 0;
00141         }
00142 
00143     // enter program into the cache
00144     mHolder->mPrograms[fileName] = id;
00145 
00146     return id;
00147 #else
00148     return 0;
00149 #endif
00150 }
00151 
00152 unsigned int OpenGLServer::LoadARBVertexProgram(const char* fileName)
00153 {
00154     // only try to load stuff if the extension is supported
00155     if (!mExtensionReg->Has_GL_ARB_vertex_program())
00156         {
00157             return 0;
00158         }
00159 
00160     return LoadARBProgram(GL_VERTEX_PROGRAM_ARB, fileName);
00161 }
00162 
00163 unsigned int OpenGLServer::LoadARBFragmentProgram(const char* /*fileName*/)
00164 {
00165     // only try to load stuff if the extension is supported
00166     //      if (!mExtensionReg->Has_GL_ARB_fragment_program())
00167     //      {
00168     //              return 0;
00169     //      }
00170 
00171     //      return LoadARBProgram(GL_FRAGMENT_PROGRAM_ARB, fileName);
00172     return 0;
00173 }
00174 
00178 bool OpenGLServer::ConstructInternal()
00179 {
00180     int result = SDL_Init(SDL_INIT_VIDEO);
00181 
00182     if( result < 0 )
00183         {
00184             GetLog()->Error() << "ERROR: (OpenGLServer) Could not init SDL."
00185                               << "SDL_Init returned error "
00186                               << result << "\n";
00187             return false;
00188         }
00189 
00190     const SDL_VideoInfo* info = SDL_GetVideoInfo();
00191 
00192     int redBits;
00193     int greenBits;
00194     int blueBits;
00195     int alphaBits;
00196     int depthBits;
00197     int stencilBits;
00198     bool doubleBuffer;
00199     bool fullScreen;
00200     int xRes, yRes;
00201     string title;
00202 
00203     bool getConfig =
00204         (
00205          GetScript()->GetVariable("Viewport.RedBits", redBits) &&
00206          GetScript()->GetVariable("Viewport.GreenBits", greenBits) &&
00207          GetScript()->GetVariable("Viewport.BlueBits", blueBits) &&
00208          GetScript()->GetVariable("Viewport.AlphaBits", alphaBits) &&
00209          GetScript()->GetVariable("Viewport.DepthBits", depthBits) &&
00210          GetScript()->GetVariable("Viewport.StencilBits", stencilBits) &&
00211          GetScript()->GetVariable("Viewport.DoubleBuffer", doubleBuffer) &&
00212          GetScript()->GetVariable("Viewport.FullScreen", fullScreen) &&
00213          GetScript()->GetVariable("Viewport.XRes", xRes) &&
00214          GetScript()->GetVariable("Viewport.YRes", yRes) &&
00215          GetScript()->GetVariable("Application.Title", title)
00216          );
00217 
00218     if (! getConfig)
00219         {
00220             GetLog()->Error()
00221                 << "(OpenGLServer) error reading config from ScriptServer\n";
00222             return false;
00223         }
00224 
00225     GetLog()->Normal() << "(OpenGLServer) bits per channel (RGB): "
00226                        << redBits << " "
00227                        << greenBits << " "
00228                        << blueBits << "\n";
00229 
00230     GetLog()->Normal() << "(OpenGLServer)"
00231                        << " depth bits= " << depthBits
00232                        << " alpha depth= " << alphaBits
00233                        << " stencil depth= " << stencilBits
00234                        << "\n";
00235 
00236     GetLog()->Normal() << "(OpenGLServer)"
00237                        << " doubleBuffer= " << doubleBuffer
00238                        << " fullScreen= " << fullScreen
00239                        << "\n";
00240 
00241     GetLog()->Normal() << "(OpenGLServer)"
00242                        << " xRes = " << xRes
00243                        << " yRes = " << yRes
00244                        << "\n";
00245 
00246     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, redBits);
00247     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, greenBits);
00248     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, blueBits);
00249     SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits);
00250     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits);
00251     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits);
00252     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, doubleBuffer ? 1:0);
00253 
00254     int flags = SDL_OPENGL;
00255     if (fullScreen)
00256         {
00257             flags |= SDL_FULLSCREEN;
00258         }
00259 
00260     SDL_Surface *screen = SDL_SetVideoMode
00261         (xRes, yRes, info->vfmt->BitsPerPixel, flags);
00262 
00263     if (screen == 0)
00264         {
00265             GetLog()->Error()
00266                 << "ERROR: (OpenGLServer) SDL_SetVideoMode() failed\n";
00267             return false;
00268         }
00269 
00270     SDL_WarpMouse(xRes/2,yRes/2);
00271     SDL_WM_SetCaption(title.c_str(), NULL);
00272 
00273     mExtensionReg->Init();
00274 
00275     // check if fancy lighting is supported
00276     mSupportsFancyLighting = true;
00277 
00278     //      if (!mExtensionReg->Has_GL_ARB_vertex_program() || !mExtensionReg->Has_GL_ARB_fragment_program())
00279     //      {
00280     // GetLog()->Normal() << "WARNING: GL_ARB_vertex_program not supported. "
00281     //                   << "disabling fancy lighting\n" << endl;
00282     mSupportsFancyLighting = false;
00283     //      }
00284 
00285     glClear(GL_COLOR_BUFFER_BIT);
00286 
00287     GetLog()->Normal() << "(OpenGLServer) Initialized OpenGL Window\n";
00288 
00289     const unsigned char* glRenderer = glGetString(GL_RENDERER);
00290     const unsigned char* glVersion = glGetString(GL_VERSION);
00291     const unsigned char* glExtensions = glGetString(GL_EXTENSIONS);
00292 
00293     GetLog()->Normal() << "(OpenGLServer) GL_RENDERER:   " << glRenderer   << "\n";
00294     GetLog()->Normal() << "(OpenGLServer) GL_VERSION:    " << glVersion    << "\n";
00295     GetLog()->Normal() << "(OpenGLServer) GL_EXTENSIONS: " << glExtensions << "\n";
00296     GetLog()->Normal() << "(OpenGLServer) GL_MAX_LIGHTS: " << GL_MAX_LIGHTS << "\n";
00297 
00298     // prepare the set of available lights
00299     for (int i=0;i<GL_MAX_LIGHTS;++i)
00300         {
00301             mAvailableLights.insert(GL_LIGHT0+i);
00302         }
00303 
00304     return true;
00305 }
00306 
00307 void OpenGLServer::ToggleFancyLighting()
00308 {
00309     if (mSupportsFancyLighting)
00310         mSupportsFancyLighting = false;
00311     else
00312         mSupportsFancyLighting = true;
00313 }
00314 
00315 int
00316 OpenGLServer::AllocLight()
00317 {
00318     if (mAvailableLights.size() == 0)
00319         {
00320             return -1;
00321         }
00322 
00323     TLightSet::iterator iter = mAvailableLights.begin();
00324     int l = (*iter);
00325     mAvailableLights.erase(iter);
00326 
00327     return l;
00328 }
00329 
00330 void
00331 OpenGLServer::PutLight(int l)
00332 {
00333     glDisable(l);
00334     mAvailableLights.insert(l);
00335 }
00336 
00337 

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