Author: ArcRiley
Date: 2008-07-19 01:29:37 -0400 (Sat, 19 Jul 2008)
New Revision: 1340

Modified:
   trunk/pysoy/include/soy.scenes.pxd
   trunk/pysoy/src/scenes/Landscape.pym
Log:
Ticket #929 :
  * changed it to use quads instead of triangles
  * now supports heightmaps > 256x256 (int, not short)
  * signifigant cleanup


Modified: trunk/pysoy/include/soy.scenes.pxd
===================================================================
--- trunk/pysoy/include/soy.scenes.pxd  2008-07-19 04:01:59 UTC (rev 1339)
+++ trunk/pysoy/include/soy.scenes.pxd  2008-07-19 05:29:37 UTC (rev 1340)
@@ -33,6 +33,12 @@
     unsigned short b
     unsigned short c
 
+  struct Quad :
+    unsigned int a
+    unsigned int b
+    unsigned int c
+    unsigned int d
+
   struct Vert :
     float px
     float py
@@ -89,10 +95,10 @@
   cdef soy.textures.Texture       _pyMap
   cdef soy.textures.Texture       _tzMap
   cdef soy.materials.Material     _material
-  cdef gl.GLuint                  _buffer
-  cdef gl.GLuint                  _elementbuffer
   cdef Vert*                      _vertArray
-  cdef Face*                      _elementArray
+  cdef gl.GLuint                  _vertBuffer
+  cdef Quad*                      _faceArray
+  cdef gl.GLuint                  _faceBuffer
   cdef void                       _createBuffer   ( self )
   cdef void                       _createArrays   ( self )
   

Modified: trunk/pysoy/src/scenes/Landscape.pym
===================================================================
--- trunk/pysoy/src/scenes/Landscape.pym        2008-07-19 04:01:59 UTC (rev 
1339)
+++ trunk/pysoy/src/scenes/Landscape.pym        2008-07-19 05:29:37 UTC (rev 
1340)
@@ -41,40 +41,28 @@
     assert type(position[0]) == int or type(position[1]) == int or \
       type(position[2]) == int, "The heightmap position must be an int"
     #We need to make an array on the heap, and put the verts there
-    self._buffer = 0
-    self._elementbuffer = 0
     self._width  = width
     self._height = height
     self._depth  = depth
     self.position = position
     self._pyMap = heightmap
     self._material = mat
-    self._heightfieldDataID = ode.dGeomHeightfieldDataCreate()
-    self._vertArray = <Vert *> py.PyMem_Malloc(self._pyMap._width * \
-                                               self._pyMap._height * 16 * 4)
-    self._elementArray = <Face *> py.PyMem_Malloc(sizeof(Face) *
-                                                  (self._pyMap._width -1) * \
-                                                  (self._pyMap._height-1) * 2)
-    ode.dGeomHeightfieldDataBuildByte(self._heightfieldDataID,
-                                      <unsigned char*> heightmap._texels,
-                                      0,                             # copy?
-                                      self._width,                   # width
-                                      self._depth,                   # depth
-                                      self._pyMap._width,            # dataX
-                                      self._pyMap._height,           # dataY
-                                      1.0 / 255.0 * self._height,    # scale
-                                      0,                             # offset
-                                      4.0,                           # thick
-                                      0)                             # wrapped
-    self._geomID = ode.dCreateHeightfield(self._spaceID, 
-                                          self._heightfieldDataID, 1)
-    ode.dGeomSetPosition(self._geomID, self._position[0],
-                         self._position[1], self._position[2])
+    self._vertArray = NULL
+    self._faceArray = NULL
+    self._vertBuffer = 0
+    self._faceBuffer = 0
     self._createArrays()
     
   def __dealloc__(self) :
     ode.dGeomHeightfieldDataDestroy(self._heightfieldDataID)
-    gl.glDeleteBuffersARB(1, &self._buffer);
+    if self._vertArray != NULL :
+      py.PyMem_Free(self._vertArray)
+    if self._faceArray != NULL :
+      py.PyMem_Free(self._faceArray)
+    if self._vertBuffer != 0 :
+      gl.glDeleteBuffersARB(1, &self._vertBuffer)
+    if self._faceBuffer != 0 :
+      gl.glDeleteBuffersARB(1, &self._faceBuffer)
 
 
   ############################################################################
@@ -101,11 +89,38 @@
   #
 
   cdef void _createArrays(self) :
-    cdef int _i, _j, _currentLoop, _offset
-    cdef unsigned short _a, _b, _c, _d
+    cdef int _i, _j, _l, _offset
+    cdef int _a, _b, _c, _d
     cdef float *_deltaCols, *_deltaRows
     cdef double _v1[3], _v2[3], _normal[3], _normal2[3], _length, _u[3]
+    self._heightfieldDataID = ode.dGeomHeightfieldDataCreate()
     #
+    # Free old arrays when needed
+    py.PyMem_Free(self._vertArray)
+    py.PyMem_Free(self._faceArray)
+    #
+    # Alloc new arrays
+    self._vertArray = <Vert *> py.PyMem_Malloc(self._pyMap._width * \
+                                               self._pyMap._height * 16 * 4)
+    self._faceArray = <Quad *> py.PyMem_Malloc(sizeof(Quad) *
+                                               (self._pyMap._width -1) * \
+                                               (self._pyMap._height-1))
+    ode.dGeomHeightfieldDataBuildByte(self._heightfieldDataID,
+                                      <unsigned char*> self._pyMap._texels,
+                                      0,                             # copy?
+                                      self._width,                   # width
+                                      self._depth,                   # depth
+                                      self._pyMap._width,            # dataX
+                                      self._pyMap._height,           # dataY
+                                      1.0 / 255.0 * self._height,    # scale
+                                      0,                             # offset
+                                      4.0,                           # thick
+                                      0)                             # wrapped
+    self._geomID = ode.dCreateHeightfield(self._spaceID, 
+                                          self._heightfieldDataID, 1)
+    ode.dGeomSetPosition(self._geomID, self._position[0],
+                         self._position[1], self._position[2])
+    #
     # Alloc _delta arrays
     #
     #   These are arrays for column and row edge deltas:
@@ -243,33 +258,21 @@
         self._vertArray[_offset].uz = _u[2]
     
     #and finally, set up the face array to make all of the triangles
-    _currentLoop = 0
+    _l = 0
     #loop through all of the quads in the grid
     for _i from 0 <= _i < self._pyMap._height-1 :
       for _j from 0 <= _j < self._pyMap._width-1 :
         # 
-        # for code cleanlyness, get the four verticies first as:
+        # CCW winding order:
+        #   a--d
+        #   |  |
+        #   b--c
         # 
-        # a-d  Note CCW winding order.
-        # |\|   Tri 1 = abc
-        # b-c   Tri 2 = acd
-        # 
-        _a = _j + ( _i    * self._pyMap._width)
-        _b = _j + ((_i+1) * self._pyMap._width)
-        _c = _j + ((_i+1) * self._pyMap._width) + 1
-        _d = _j + ( _i    * self._pyMap._width) + 1
-        # 
-        #create the upper left tri in the quad
-        #verts are in counter clockwise direction
-        self._elementArray[_currentLoop].a = _a
-        self._elementArray[_currentLoop].b = _b
-        self._elementArray[_currentLoop].c = _c
-        _currentLoop += 1
-        #now the bottom right!
-        self._elementArray[_currentLoop].a = _a
-        self._elementArray[_currentLoop].b = _c
-        self._elementArray[_currentLoop].c = _d
-        _currentLoop += 1
+        self._faceArray[_l].a = _j + ( _i    * self._pyMap._width)
+        self._faceArray[_l].b = _j + ((_i+1) * self._pyMap._width)
+        self._faceArray[_l].c = _j + ((_i+1) * self._pyMap._width) + 1
+        self._faceArray[_l].d = _j + ( _i    * self._pyMap._width) + 1
+        _l += 1
     #
     # Free previously alloc'ed delta arrays
     py.PyMem_Free(_deltaCols)
@@ -277,16 +280,16 @@
 
 
   cdef void _createBuffer(self) :
-    gl.glGenBuffersARB(1, <gl.GLuint*> &self._buffer) # Create the vertex 
buffers
-    gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._buffer)
+    gl.glGenBuffersARB(1, <gl.GLuint*> &self._vertBuffer) # Create the vertex 
buffers
+    gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._vertBuffer)
     gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, (sizeof(Vert)*
           self._pyMap._width*self._pyMap._height), self._vertArray,
           gl.GL_STATIC_DRAW_ARB)
-    gl.glGenBuffersARB(1, &self._elementbuffer)
-    gl.glBindBufferARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._elementbuffer)  # 
Create the elements buffers
+    gl.glGenBuffersARB(1, &self._faceBuffer)
+    gl.glBindBufferARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._faceBuffer)  # 
Create the elements buffers
     gl.glBufferDataARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, 
-         sizeof(Face)*(self._pyMap._width-1)*(self._pyMap._height-1)*2, 
-         self._elementArray, gl.GL_STATIC_DRAW_ARB)
+                 sizeof(Quad)*(self._pyMap._width-1)*(self._pyMap._height-1), 
+                 self._faceArray, gl.GL_STATIC_DRAW_ARB)
 
 
   cdef void _render(self, gl.GLdouble _fovy,  gl.GLdouble _aspect,
@@ -311,13 +314,13 @@
       (<soy.bodies.Light> self._lights._list[_i])._on(gl.GL_LIGHT0 + _i)
     gl.glPushMatrix()
     gl.glTranslatef(self._position[0], self._position[1], self._position[2])
-    if self._buffer:
-      py.PyMem_Free(self._elementArray) # The arrays are in Vram so lets free 
it in system mem
+    if self._vertBuffer :
+      py.PyMem_Free(self._faceArray)
       py.PyMem_Free(self._vertArray)
-      self._elementArray = NULL; # Make the pointer NULL so UB doesn't occur 
in free()
-      self._vertArray = NULL;
-      gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._buffer) # 
Bind to buffer for rendering below
-      gl.glBindBufferARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._elementbuffer) 
+      self._faceArray = NULL # Make the pointer NULL so UB doesn't occur in 
free()
+      self._vertArray = NULL
+      gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._vertBuffer) 
# Bind to buffer for rendering below
+      gl.glBindBufferARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._faceBuffer) 
     else:
       self._createBuffer()
     gl.glVertexPointer  (3,  gl.GL_FLOAT, sizeof(Vert),(<char *>NULL + (0))) 
#px py pz
@@ -325,12 +328,12 @@
     gl.glTexCoordPointer(3, gl.GL_FLOAT, sizeof(Vert),  (<char *> NULL + 
(24))) # tx ty tz
     #gl.glDrawArrays(gl.GL_TRIANGLES, 0, self._verts)
     #stdio.printf("%s","glDrawElements\n")
-    while self._material._render(_pass,<float *>24,<float *>0):
-        gl.glDrawElements (gl.GL_TRIANGLES, 
-                       (self._pyMap._width-1) * \
-                       (self._pyMap._height-1) * 2 * 3,
-                       gl.GL_UNSIGNED_SHORT, <Face*> 0)
-        _pass+=1
+    while self._material._render(_pass, <float*> 24, <float*> 0) :
+      gl.glDrawElements(gl.GL_QUADS, 
+                        (self._pyMap._width-1) * (self._pyMap._height-1) * 4,
+                        gl.GL_UNSIGNED_INT,
+                        <Quad*> 0)
+      _pass+=1
     gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, 0)
     #
     # Render the rest of the scene normally    

_______________________________________________
PySoy-SVN mailing list
PySoy-SVN@pysoy.org
http://www.pysoy.org/mailman/listinfo/pysoy-svn

Reply via email to