From: Oliver O. <fr...@us...> - 2007-06-17 08:49:00
|
Update of /cvsroot/simspark/simspark/spark/kerosin/renderserver In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv12375 Modified Files: Tag: projectx renderserver.cpp Log Message: - merged from HEAD - added methods to deliver Width() and Height() of current view - added method to copy current view into a buffer Index: renderserver.cpp =================================================================== RCS file: /cvsroot/simspark/simspark/spark/kerosin/renderserver/renderserver.cpp,v retrieving revision 1.2.2.3.2.1 retrieving revision 1.2.2.3.2.2 diff -C2 -d -r1.2.2.3.2.1 -r1.2.2.3.2.2 *** renderserver.cpp 30 Mar 2007 01:56:19 -0000 1.2.2.3.2.1 --- renderserver.cpp 17 Jun 2007 08:48:56 -0000 1.2.2.3.2.2 *************** *** 1,24 **** /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- ! this file is part of rcssserver3D ! Fri May 9 2003 ! Copyright (C) 2002,2003 Koblenz University ! Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group ! $Id$ ! This program is free software; you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation; version 2 of the License. ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include "renderserver.h" #include <oxygen/sceneserver/sceneserver.h> --- 1,23 ---- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- ! this file is part of rcssserver3D ! Fri May 9 2003 ! Copyright (C) 2002,2003 Koblenz University ! Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group ! $Id$ ! This program is free software; you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation; version 2 of the License. ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "renderserver.h" #include <oxygen/sceneserver/sceneserver.h> *************** *** 37,43 **** --- 36,58 ---- using namespace zeitgeist; + /** OpenGL picking result buffer */ + static GLuint gSelectBuffer[4096]; + RenderServer::RenderServer() : BaseRenderServer() { mAmbientColor = RGBA(0.0,0.0,0.0,0.0); + mEnablePicking = false; + mPickAt = Vector2f(0.0,0.0); + mPickRange = 10.0; + mNextName = 1; + } + + void + RenderServer::PreparePicking() + { + mNameMap.clear(); + mNextName = 1; + glSelectBuffer(sizeof(gSelectBuffer), gSelectBuffer); + mPickedNode.reset(); } *************** *** 45,48 **** --- 60,65 ---- RenderServer::Render() { + PreparePicking(); + if (! GetActiveScene()) { *************** *** 111,114 **** --- 128,254 ---- // reset GL lights glDisable(GL_LIGHTING); + + if (mEnablePicking) + { + ProcessPicks(); + } + } + + + int + RenderServer::Width() const + { + if (mActiveScene.get() == 0) return 0; + + // get camera + shared_ptr<Camera> camera = + shared_static_cast<Camera>(mActiveScene->GetChildOfClass("Camera", true)); + + if (camera.get() == 0) + { + GetLog()->Error() + << "(RenderServer) ERROR: found no camera node in the active scene\n"; + return 0; + } + return camera->GetViewportWidth(); + } + + int + RenderServer::Height() const + { + if (mActiveScene.get() == 0) return 0; + + // get camera + shared_ptr<Camera> camera = + shared_static_cast<Camera>(mActiveScene->GetChildOfClass("Camera", true)); + + if (camera.get() == 0) + { + GetLog()->Error() + << "(RenderServer) ERROR: found no camera node in the active scene\n"; + return 0; + } + return camera->GetViewportHeight(); + } + + bool + RenderServer::CopyFrame(char* buffer) const + { + if (mActiveScene.get() == 0) return false; + glReadPixels(0,0,Width()-1,Height()-1,GL_RGB,GL_UNSIGNED_BYTE,buffer); + + size_t len = Width() * 3; + uint8_t* line = new uint8_t[len]; /* one line of packed RGB pixels */ + + unsigned char* a; + unsigned char* b; + + for (int y = 0; y < Height() >> 1; ++y) + { + a = ( unsigned char * ) & buffer[y * len]; + b = ( unsigned char * ) & buffer[(Height() - ( y + 1 )) * len]; + + memcpy(line, a, len); + memcpy(a, b, len); + memcpy(b, line, len); + } + delete[] line; + return true; + } + + void + RenderServer::ProcessPicks() + { + // restoring the original projection matrix + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glFlush(); + + // returning to normal rendering mode + int hits = glRenderMode(GL_RENDER); + + // if there are hits process them + GLuint numberOfNames = 0; + GLuint minZ = 0xffffffff; + GLuint *ptrNames = 0; + + GLuint* ptr = gSelectBuffer; + + for (int i = 0; i < hits; i++) + { + // read number of stored names in the current record + GLuint names = (*ptr); + ptr++; + + if ((*ptr) < minZ) + { + numberOfNames = names; + minZ = *ptr; + ptrNames = ptr+2; + } + + ptr += names+2; + } + + mPickedNode.reset(); + for (;;) + { + if (ptrNames == 0) + { + break; + } + + TGLNameMap::const_iterator iter = mNameMap.find(*ptrNames); + if (iter == mNameMap.end()) + { + break; + } + + mPickedNode = (*iter).second; + break; + } + + mNameMap.clear(); } *************** *** 125,136 **** shared_ptr<RenderNode> renderNode = shared_dynamic_cast<RenderNode>(node); if (renderNode.get() != 0) ! { ! glPushMatrix(); ! glMultMatrixf(node->GetWorldTransform().m); renderNode->RenderInternal(); ! glPopMatrix(); ! } // traverse the the hierarchy --- 265,291 ---- shared_ptr<RenderNode> renderNode = shared_dynamic_cast<RenderNode>(node); if (renderNode.get() != 0) ! { ! glPushMatrix(); ! ! if (mEnablePicking) ! { ! // assign an OpenGL name to the RenderNode ! GLuint name = (mNextName++); ! mNameMap[name] = renderNode; ! glPushName(name); ! } ! ! glMultMatrixf(node->GetWorldTransform().m); renderNode->RenderInternal(); ! if (mEnablePicking) ! { ! // pop name from OpenGL name stack ! glPopName(); ! } ! ! glPopMatrix(); ! } // traverse the the hierarchy *************** *** 163,175 **** glDepthRange(0, 1); ! // setup the projection matrix ! glMatrixMode(GL_PROJECTION); ! glLoadIdentity(); ! glMultMatrixf(camera->GetProjectionTransform().m); ! // initialize the modelview stack ! glMatrixMode(GL_MODELVIEW); ! glLoadIdentity(); ! glMultMatrixf(camera->GetViewTransform().m); } --- 318,350 ---- glDepthRange(0, 1); ! if (mEnablePicking) ! { ! glRenderMode(GL_SELECT); ! GLint viewport[4]; ! glGetIntegerv(GL_VIEWPORT, viewport); ! ! glMatrixMode(GL_PROJECTION); ! glPushMatrix(); ! glLoadIdentity(); ! ! gluPickMatrix(mPickAt[0],viewport[3]-mPickAt[1],mPickRange,mPickRange,viewport); ! ! glMultMatrixf(camera->GetProjectionTransform().m); ! glMatrixMode(GL_MODELVIEW); ! ! glInitNames(); ! } else ! { ! // setup the projection matrix ! glMatrixMode(GL_PROJECTION); ! glLoadIdentity(); ! glMultMatrixf(camera->GetProjectionTransform().m); ! ! // initialize the modelview stack ! glMatrixMode(GL_MODELVIEW); ! glLoadIdentity(); ! glMultMatrixf(camera->GetViewTransform().m); ! } } *************** *** 179,180 **** --- 354,377 ---- mAmbientColor = ambient; } + + void RenderServer::UpdateCached() + { + mActiveScene.reset(); + } + + void RenderServer::DisablePicking() + { + mEnablePicking = false; + } + + void RenderServer::EnablePicking(bool enable, const Vector2f& pickAt, const double pickRange) + { + mEnablePicking = enable; + mPickAt = pickAt; + mPickRange = pickRange; + } + + weak_ptr<RenderNode> RenderServer::GetPickedNode() const + { + return mPickedNode; + } |