context.C

00001 /*
00002  * This file is part of the "Archon" framework.
00003  * (http://files3d.sourceforge.net)
00004  *
00005  * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation under the terms of the GNU General Public License is
00009  * hereby granted. No representations are made about the suitability of
00010  * this software for any purpose. It is provided "as is" without express
00011  * or implied warranty. See the GNU General Public License
00012  * (http://www.gnu.org/copyleft/gpl.html) for more details.
00013  *
00014  * The characters in this file are ISO8859-1 encoded.
00015  *
00016  * The documentation in this file is in "Doxygen" style
00017  * (http://www.doxygen.org).
00018  */
00019 
00020 #include <GL/gl.h>
00021 
00022 #include <archon/render/context.H>
00023 
00024 #include <archon/render/conductor.H>
00025 
00026 namespace Archon
00027 {
00028   namespace Render
00029   {
00030     void Channel::render(const Ref<Pipe> &pipe)
00031     {
00032       Display::Bind bind(pipe->context, window);
00033 
00034       if(!pipe->initialized)
00035       {
00036         view->renderer->initOpenGlContext();
00037         pipe->initialized = true;
00038       }
00039 
00040       double l, b, w, h;
00041       Vector3 c, x, y;
00042       double s, t;
00043       Vector3 e;
00044       double n, f;
00045 
00046       // Fetch the view information
00047       {
00048         Mutex::Lock lock(view->viewMutex);
00049         l = viewport->left;
00050         b = viewport->bottom;
00051         w = viewport->width;
00052         h = viewport->height;
00053         c = screen->center;
00054         x = screen->x;
00055         y = screen->y;
00056         s = screen->halfWidth;
00057         t = screen->halfHeight;
00058         e = eye->position;
00059         n = clip->near;
00060         f = clip->far;
00061       }
00062 
00063       // Determine the canonical coordinate system of the eye
00064       Vector3 z = x;
00065       z *= y;
00066 
00067       // Determine the center of the screen in the canonical coordinate
00068       // system of the eye
00069       c -= e;
00070       c.set(dot(c, x), dot(c, y), dot(c, z));
00071 
00072       // Setup the projection matrix
00073       double a = n / -c[2];
00074       glMatrixMode(GL_PROJECTION);
00075       glLoadIdentity();
00076       glFrustum((c[0] - s) * a, (c[0] + s) * a,
00077                 (c[1] - t) * a, (c[1] + t) * a, n, f);
00078 
00079       /*
00080       cerr << "w:\t"
00081            << ((c[0] - s) * a) << ",\t"
00082            << ((c[0] + s) * a) << ",\t"
00083            << ((c[1] - t) * a) << ",\t"
00084            << ((c[1] + t) * a) << ",\t"
00085            << n << ",\t" << f << "\n";
00086       */
00087 
00088       // Setup the modelview matrix
00089       GLdouble m[16] =
00090       {
00091         x[0],       y[0],       z[0],       0,
00092         x[1],       y[1],       z[1],       0,
00093         x[2],       y[2],       z[2],       0,
00094         -dot(x, e), -dot(y, e), -dot(z, e), 1
00095       };
00096       glMatrixMode(GL_MODELVIEW);
00097       glLoadMatrixd(m);
00098 
00099       /*
00100       cerr
00101         << m[0] << "\t" << m[4] << "\t" << m[ 8] << "\t" << m[12] << "\n"
00102         << m[1] << "\t" << m[5] << "\t" << m[ 9] << "\t" << m[13] << "\n"
00103         << m[2] << "\t" << m[6] << "\t" << m[10] << "\t" << m[14] << "\n"
00104         << m[3] << "\t" << m[7] << "\t" << m[11] << "\t" << m[15] << "\n";
00105       */
00106 
00107       // Setup the viewport (with strict round-off controll)
00108       s = window->getWidth();
00109       t = window->getHeight();
00110       unsigned il = static_cast<unsigned>(l * s + 0.5);
00111       unsigned ib = static_cast<unsigned>(b * t + 0.5);
00112       unsigned iw = static_cast<unsigned>((l+w) * s + 0.5) - il;
00113       unsigned ih = static_cast<unsigned>((b+h) * t + 0.5) - ib;
00114       glViewport(il, ib, iw, ih);
00115 
00116       view->renderer->render();
00117     }
00118 
00119 
00120     void Pipe::addChannel(Ref<Conductor> conductor,
00121                           Ref<View> view,
00122                           Ref<Display::Window> window,
00123                           Ref<Viewport> viewport,
00124                           Ref<Screen> screen,
00125                           Ref<Eye> eye,
00126                           Ref<Clip> clip)
00127     {
00128       if(view != viewport->view ||
00129          view !=   screen->view ||
00130          view !=      eye->view ||
00131          view !=     clip->view)
00132         ARCHON_THROW1(ArgumentException,
00133                       "Illegal combination - different View objects found");
00134       conductor->addWindow(window, this);
00135       Mutex::Lock l(channelMutex);
00136       channels.push_back(Channel(view, window, viewport, screen, eye, clip));
00137     }
00138 
00139     void Pipe::render()
00140     {
00141       Ref<Pipe> pipe(this);
00142       Mutex::Lock l(channelMutex);
00143       for(unsigned i=0; i<channels.size(); ++i) channels[i].render(pipe);
00144     }
00145   }
00146 }

Generated on Sun Jul 30 22:55:43 2006 for Archon by  doxygen 1.4.4