Revision: 6664
          http://playerstage.svn.sourceforge.net/playerstage/?rev=6664&view=rev
Author:   alexcb
Date:     2008-06-21 22:48:02 -0700 (Sat, 21 Jun 2008)

Log Message:
-----------
modified visualization of camera model to produce quads based off vertices 
created with depth buffer

Modified Paths:
--------------
    code/stage/trunk/libstage/model_camera.cc
    code/stage/trunk/libstage/stage.hh

Modified: code/stage/trunk/libstage/model_camera.cc
===================================================================
--- code/stage/trunk/libstage/model_camera.cc   2008-06-22 05:38:17 UTC (rev 
6663)
+++ code/stage/trunk/libstage/model_camera.cc   2008-06-22 05:48:02 UTC (rev 
6664)
@@ -14,10 +14,10 @@
 #include <sstream>
 
 
-StgModelCamera::StgModelCamera( StgWorld* world, 
-                                                                               
  StgModel* parent ) 
+StgModelCamera::StgModelCamera( StgWorld* world, StgModel* parent ) 
   : StgModel( world, parent, MODEL_TYPE_CAMERA ),
-_frame_data( NULL ), _frame_color_data( NULL ), _vertexbuf( NULL ),  _width( 0 
), _height( 0 ), _yaw_offset( 0 )
+_frame_data( NULL ), _frame_color_data( NULL ), 
+_vertexbuf_scaled( NULL ),  _width( 0 ), _height( 0 ), _valid_vertexbuf_cache( 
false ), _yaw_offset( 0 )
 {
        PRINT_DEBUG2( "Constructing StgModelCamera %d (%s)\n", 
                        id, typestr );
@@ -48,7 +48,9 @@
        if( _frame_data != NULL ) {
                delete[] _frame_data;
                delete[] _frame_color_data;
-               delete[] _vertexbuf;
+               delete[] _vertexbuf_cache;
+               delete[] _vertexbuf_scaled;
+               delete[] _vertexbuf_scaled_index;
        }
 }
 
@@ -74,36 +76,6 @@
 float* StgModelCamera::laser()
 {
        return NULL;
-//     //TODO allow the h and w to be passed by user
-//     int w = _width;
-//     int h = 1;
-//     
-//     static GLfloat* data_gl = NULL;
-//     static GLfloat* data = NULL;
-//     if( data == NULL ) {
-//             data = new GLfloat[ h * w ];
-//             data_gl = new GLfloat[ h * w ];
-//             
-//     }
-//     
-//     glViewport( 0, 0, w, h );
-//     _camera.update();
-//     _camera.SetProjection( w, h, 0.1, 40.0 );
-//     
-//     _camera.setPose( parent->GetGlobalPose().x, parent->GetGlobalPose().y, 
0.3 );
-//     _camera.setYaw( rtod( parent->GetGlobalPose().a ) - 90.0 );
-//     _camera.Draw();
-//
-//     _canvas->renderFrame( true );
-//     
-//     glReadPixels(0, 0, w, h, GL_DEPTH_COMPONENT, GL_FLOAT, data_gl );
-//
-//     for( int i = 0; i < w; i++ ) {
-//             data[ w-1-i ] = _camera.realDistance( data_gl[ i ]);
-//     }
-//
-//     _canvas->invalidate();
-//     return data;
 }
 
 const char* StgModelCamera::GetFrame( bool depth_buffer )
@@ -115,14 +87,18 @@
                if( _frame_data != NULL ) {
                        delete[] _frame_data;
                        delete[] _frame_color_data;
-                       delete[] _vertexbuf;    
+                       delete[] _vertexbuf_cache;
+                       delete[] _vertexbuf_scaled;
+                       delete[] _vertexbuf_scaled_index;
                }
-               _frame_data = new char[ 4 * _width * _height ]; //assumes a max 
of depth 4
-               _frame_color_data = new char[ 3 * _width * _height ]; //for RGB
-               _vertexbuf = new float[ 3 * _width * _height ]; //for RGB
+               _frame_data = new GLfloat[ _width * _height ]; //assumes a max 
of depth 4
+               _frame_color_data = new GLubyte[ 4 * _width * _height ]; //for 
RGBA
+
+               _vertexbuf_cache = new ColoredVertex[ _width * _height ]; //for 
unit vectors
+               _vertexbuf_scaled = new ColoredVertex[ _width * _height ]; 
//scaled with z-buffer
+               _vertexbuf_scaled_index = new GLushort[ 4 * (_width-1) * 
(_height-1) ]; //for indicies to draw a quad
        }
 
-       
        glViewport( 0, 0, _width, _height );
        _camera.update();
        _camera.SetProjection();
@@ -145,13 +121,13 @@
 
        //read color buffer
        glReadPixels(0, 0, _width, _height,
-                                GL_RGB,
+                                GL_RGBA,
                                 GL_UNSIGNED_BYTE,
                                 _frame_color_data );           
 
 
        _canvas->invalidate();
-       return _frame_data;
+       return NULL; //_frame_data;
 }
 
 //TODO create lines outlineing camera frustrum, then iterate over each depth 
measurement and create a square
@@ -171,14 +147,7 @@
                
        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); //TODO this doesn't seem 
to work.
 
-//     float z = cos( dtor( h_fov / 2.0 ) ) * length;
        
-       glColor4f(1.0, 0.0, 0.0, 1.0 ); 
-       
-       static float foo = 0.0;
-       foo += 1.0;
-       
-       const float* data = ( float* )( _frame_data ); //TODO use static_cast 
here
        int w = _width;
        int h = _height;
        float a;
@@ -187,74 +156,100 @@
        float vert_a_space = h_fov / h; //degrees between each vertical sample
        float x, y, z;
        float tmp_x, tmp_y, tmp_z;
-       float *buf;
 
-       glBegin( GL_POINTS );
-       for( int i = 0; i < w; i++ ) {
+
+       //TODO - there are still some vertices which aren't accurate - possibly 
due to a buffer overflow / memory corruption.
+       //In some cases the vertices appear to be below the floor which 
shouldn't be possible once the unit vectors are scaled (and should simply hit 
the floor, but not pass beneath them)
+       if( _valid_vertexbuf_cache == false ) {
                for( int j = 0; j < h; j++ ) {
-                       float length = data[ i + j * h ];
-                       
-                       a = start_fov - static_cast< float >( i ) * a_space;
-                       vert_a = start_vert_fov - static_cast< float >( j ) * 
vert_a_space;
-                       
-                       x = length;
-                       y = 0;
-                       z = 0;
-                       
-                       tmp_x = x * cos( dtor( a ) ); // - y *sin( but y=0)
-                       tmp_y = x * sin( dtor( a ) ); // + y * cos( but y=0 )
-                       tmp_z = z;
-                       
-                       x = tmp_x; y = tmp_y; z = tmp_z;
-                       
-                       tmp_z = - x * sin( dtor( vert_a ) );
-                       tmp_x = x * cos( dtor( vert_a ) );
+                       for( int i = 0; i < w; i++ ) {
+                               
+                               a = start_fov - static_cast< float >( i ) * 
a_space;
+                               vert_a = start_vert_fov - static_cast< float >( 
j ) * vert_a_space;
+                               
+                               //calculate based on a unit vector, which is 
scaled later on (this reduces all the sin/cos/dtor calls)
+                               x = 1;
+                               y = 0;
+                               z = 0;
 
-                       x = tmp_x; y = tmp_y; z = tmp_z;
+                               //rotate about z by a
+                               tmp_x = x * cos( dtor( a ) ); // - y *sin( but 
y=0)
+                               tmp_y = x * sin( dtor( a ) ); // + y * cos( but 
y=0 )
+                               tmp_z = z;
+                               
+                               x = tmp_x; y = tmp_y; z = tmp_z;
+                               
+                               //rotate about x
+                               tmp_z = - x * sin( dtor( vert_a ) );
+                               tmp_x = x * cos( dtor( vert_a ) );
+
+                               x = tmp_x;
+                               y = tmp_y;
+                               z = tmp_z;
+                               
+                               int index = i + j * w;
+                               ColoredVertex* vertex = _vertexbuf_cache + 
index;
+                               
+                               vertex->x = x;
+                               vertex->y = y;
+                               vertex->z = z;
+                               
+                               //TODO move the quad generate to the same 
section as scalling code, and only insert a quad when the distance between 
vertices isn't too large (i.e. spanning from a wall to sky)
+                               //It might also be possible to write a shader 
which would scale vertices and create quads instead of doing it here on the CPU.
+                               
+                               //skip top and left boarders
+                               if( i == 0 || j == 0 )
+                                       continue;
+                               
+                               //decrement i and j, since the first boarders 
were skipped
+                               //note: the width of this array is (w-1) since 
it contains QUADS between the vertices
+                               GLushort* p = _vertexbuf_scaled_index + ( (i-1) 
+ (j-1) * (w-1) ) * 4;
+                               
+                               //create quad growing adjacent point on top 
left (use width of `w' since these are VERTICES)
+                               p[ 0 ] = i     + j * w;
+                               p[ 1 ] = i - 1 + j * w;
+                               p[ 2 ] = i - 1 + ( j - 1 ) * w;
+                               p[ 3 ] = i     + ( j - 1 ) * w;
+                               
+                       }
+               }
+               _valid_vertexbuf_cache = true;
+       }
+       
+       //Scale cached unit vectors with depth-buffer
+       float* depth_data = ( float* )( _frame_data );
+       for( int j = 0; j < h; j++ ) {
+               for( int i = 0; i < w; i++ ) {
+                       int index = i + j * w;
+                       const ColoredVertex* unit_vertex = _vertexbuf_cache + 
index;
+                       ColoredVertex* scaled_vertex = _vertexbuf_scaled + 
index;
+                       const GLubyte* color = _frame_color_data + index * 4; 
//TODO might be buggy indexing
+                       const float length = depth_data[ index ];
                        
-                       buf = _vertexbuf + ( i + j * h  ) * 3;
+                       //scale unitvectors with depth-buffer
+                       scaled_vertex->x = unit_vertex->x * length;
+                       scaled_vertex->y = unit_vertex->y * length;
+                       scaled_vertex->z = unit_vertex->z * length;
                        
-                       buf[ 0 ] = x;
-                       buf[ 1 ] = y;
-                       buf[ 2 ] = z;
+                       //colour the points
+                       //TODO color is buggy
+                       scaled_vertex->r = 0x00; //color[ 0 ];
+                       scaled_vertex->g = 0x00; //color[ 1 ];
+                       scaled_vertex->b = 0x00; //color[ 2 ];
+                       scaled_vertex->a = 0xFF;
                        
-                       //TODO push into a buffer
-                       //glVertex3f( x, y, z );
-
                }
        }
-       glEnd();
-       
-       //TODO use vertex array buffer
-       glEnableClientState( GL_VERTEX_ARRAY );
 
-       glVertexPointer( 3, GL_FLOAT, 0, _vertexbuf );
-       glDrawArrays( GL_POINTS, 0, _width * _height );
-       
-       glDisableClientState( GL_VERTEX_ARRAY );
-       
-//     for( int i = 0; i < w; i++ ) {
-//             float z_a = h_fov / _width * static_cast< float >( i );
-//             for( int j = 0; j < h; j++ ) {
-//                     float length = data[ i + j * w ];
-//                     float a;
-//                     //float z = cos( z_a ) * length;
-//                     //TODO rename j to not conflict with loop
-//                     int j = i + 1;
-//                     if( j < _width/2 ) 
-//                             a = center_horiz - w_fov / _width * 
static_cast< float >( _width/2 - 1 - j );
-//                     else
-//                             a = center_horiz + w_fov / _width * 
static_cast< float >( j - _width/2 );
-//                     x = sin( dtor( a ) ) * length;
-//                     y = cos( dtor( a ) ) * length;
-//                     glBegin( GL_LINE_LOOP );
-//                     glVertex3f( 0.0, 0.0, 0.0 );
-//                     glVertex3f( x, y, 0.0 );
-//                     glEnd();
-//                     
-//             }
-//     }
-       
+
+       //draw then camera data
+       glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
+       glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); //Can also be GL_FILL - 
but harder to debug
+       glInterleavedArrays( GL_C4UB_V3F, 0, _vertexbuf_scaled );
+       glDrawElements( GL_QUADS, 4 * (w-1) * (h-1), GL_UNSIGNED_SHORT, 
_vertexbuf_scaled_index );
+       glPopClientAttrib();
+
+
 }
 
 void StgModelCamera::Draw( uint32_t flags, StgCanvas* canvas )

Modified: code/stage/trunk/libstage/stage.hh
===================================================================
--- code/stage/trunk/libstage/stage.hh  2008-06-22 05:38:17 UTC (rev 6663)
+++ code/stage/trunk/libstage/stage.hh  2008-06-22 05:48:02 UTC (rev 6664)
@@ -2457,14 +2457,25 @@
 };
 
 // CAMERA MODEL ----------------------------------------------------
+typedef struct {
+       // GL_C4UB_V3F
+       GLubyte r, g, b, a;
+       GLfloat x, y, z;
+} ColoredVertex;
+       
 class StgModelCamera : public StgModel
 {
        private:
                StgCanvas* _canvas;
 
-               char* _frame_data;  //opengl read buffer
-               char* _frame_color_data;  //opengl read buffer
-               float* _vertexbuf;   //vertex buffer for visualiation
+               GLfloat* _frame_data;  //opengl read buffer
+               GLubyte* _frame_color_data;  //opengl read buffer
+
+               bool _valid_vertexbuf_cache;
+               ColoredVertex* _vertexbuf_cache; //cached unit vectors with 
appropriate rotations (these must be scalled by z-buffer length)
+               ColoredVertex* _vertexbuf_scaled;   //vertex buffer for 
visualiation
+               GLushort* _vertexbuf_scaled_index; //indecies for scaled buffer
+       
                int _width;         //width of buffer
                int _height;        //height of buffer
                static const int _depth = 4;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to