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