Author: DavidCzech Date: 2008-07-09 21:37:18 -0400 (Wed, 09 Jul 2008) New Revision: 1306
Modified: trunk/pysoy/examples/LandScape.py trunk/pysoy/include/soy.scenes.pxd trunk/pysoy/src/scenes/Landscape.pym Log: Ticket #929 : Landscape VBOs almost working. Modified: trunk/pysoy/examples/LandScape.py =================================================================== --- trunk/pysoy/examples/LandScape.py 2008-06-19 17:01:51 UTC (rev 1305) +++ trunk/pysoy/examples/LandScape.py 2008-07-10 01:37:18 UTC (rev 1306) @@ -3,11 +3,47 @@ import soy from time import sleep -heightTex = soy.transports.File('media/heightmap.soy')['gimp'] -heightMap = soy.scenes.landscape(heightTex) +### Start Heightmap Code +heightTex = soy.transports.File('media/white.soy')['gimp'] +sleep(2) # HACK: this will wait while transportloop does his stuff +heightScene = soy.scenes.Landscape(heightTex,soy.materials.Material()) +#sce = soy.scenes.Scene() +#heightScene = soy.scenes.Scene();# with normal scene, everything is peachy +### Start PySoy Code (Excerpt from pysoy-primer.py) +# Initialize a window +scr = soy.Screen() +win = soy.Window(scr, "A Spinning Cube") + +# Create a cube with a shape, material and a body. +cube = soy.shapes.Box(1, 1, 1) # Step 1: Shape +mat = soy.materials.Material() # Step 2: Material +mat.shininess = 5 # (Optional) Looks nicer (modifies the applied specular lighting; play with this setting to see how it affects appearance) +body = soy.bodies.Body(scene=heightScene, model=soy.models.Shape(mat), shape=cube, position=(0,-2,0)) # Step 3: Body + +# Put a light and camera into the initialized screen +light = soy.bodies.Light(heightScene) +camera = soy.bodies.Camera(heightScene) +#stx = soy.widgets.StackX(win) +#pro = soy.widgets.Projector(stx, camera=camera) +#cam2 = soy.bodies.Camera(sce) +#cam2.position = (-0.3, 0.0, 15.0) +#pro2 = soy.widgets.Projector(stx, camera=cam2) + +pro = soy.widgets.Projector(win, camera=camera) + +#lig = soy.bodies.Light(sce) +#lig.position = (-10.0,10.0,2.0) + +camera.position = (0, -2, 5.0) #50? +light.position = (0.5, 1.0, 5.0) +#heightScene.gravity = (0,-1,0) +#mat=soy.materials.Material() +#a=soy.bodies.Body(scene=sce,model=soy.models.Shape(mat),shape=soy.shapes.Box(2,1,2),position=(0,-1.2,-1)) + if __name__ == "__main__": - #mainloop goes here - while 1: - sleep(0.1) \ No newline at end of file + #mainloop goes here + while 1: + sleep(1) + #print body.position #annoying Modified: trunk/pysoy/include/soy.scenes.pxd =================================================================== --- trunk/pysoy/include/soy.scenes.pxd 2008-06-19 17:01:51 UTC (rev 1305) +++ trunk/pysoy/include/soy.scenes.pxd 2008-07-10 01:37:18 UTC (rev 1306) @@ -80,9 +80,15 @@ cdef ode.dHeightfieldDataID _heightmapID cdef ode.dGeomID _heightmap cdef int _width + cdef int _depth cdef int _height cdef gl.GLuint _buffer + cdef gl.GLuint _elementbuffer cdef void _createBuffer ( self ) + cdef int _verts + cdef Vert* _vertArray + cdef Face* _elementArray + cdef gl.GLfloat* vertices[72] cdef class Planar (Scene) : cdef ode.dGeomID _planeID Modified: trunk/pysoy/src/scenes/Landscape.pym =================================================================== --- trunk/pysoy/src/scenes/Landscape.pym 2008-06-19 17:01:51 UTC (rev 1305) +++ trunk/pysoy/src/scenes/Landscape.pym 2008-07-10 01:37:18 UTC (rev 1306) @@ -22,7 +22,7 @@ ''' Landscape Scene This is a scene based on a heightmap. - Accepts a heightmap and the width, depth, and heigth of it. + Accepts a heightmap with the detail of it, the width, depth, and height of it. ''' ############################################################################ @@ -30,12 +30,22 @@ # Python functions # - def __cinit__(self, heightmap, scale, width=1024, depth=1024, *args, **kw) : - if not isinstance(soy.textures.Texture, heightmap) or heightmap._chans != 1 : - raise TypeError('heightmap must be of type soy.textures.Texture and 1 channel.') - self._width = width - self._depth = depth + def __cinit__(self, soy.textures.Texture heightmap,soy.materials.Material mat, detail = 1, width=1024, depth=1024, height=1024, *args, **kw) : + cdef int _i, _j + cdef double _value + if not isinstance(heightmap, soy.textures.Texture) or heightmap._chans != 1 : + raise TypeError('Heightmap must be of type soy.textures.Texture and 1 channel, not '+str(heightmap._chans)) + #We need to make an array on the heap, and put the verts there + stdio.printf("Cinit Start!\n"); + # Now we need to define the vars somehow (like px py pz, tx ty ...) + self._verts = 0 + self._width = width + self._depth = depth + self._height = height self._heightmapID = ode.dGeomHeightfieldDataCreate() + self._vertArray = <Vert *> py.PyMem_Malloc((heightmap._width*heightmap._height/detail)*16*4) + self._elementArray = <Face *> py.PyMem_Malloc(sizeof(Face)*((heightmap._width*heightmap._height/detail))/3) #21k*Face + #for _i from 0 < _i < 72: ode.dGeomHeightfieldDataBuildByte(self._heightmapID, <unsigned char*> heightmap._texels, 0, heightmap._width, heightmap._depth, @@ -43,8 +53,36 @@ self._depth/heightmap._depth, 1, 0, 1, 0) self._heightmap = ode.dCreateHeightfield(self._spaceID, self._heightmapID, 1) - - + ##Setup Arrays Here + for _i from 1 <= _i < heightmap._width : + for _j from 1 <= _j < heightmap._height : + self._verts +=1 + # Get the y value here + _value = heightmap._texels[heightmap._width*(_i-1)+_j] + #stdio.printf("%d\n",value) + #yea, so now value*scale got + _value = _value/255.0 #255 is max, so if the value == 255(white) then its a 1 for high, thats mul'ed by height + self._vertArray[heightmap._width*(_i-1)+_j].px = _i + self._vertArray[heightmap._width*(_i-1)+_j].pz = _j + self._vertArray[heightmap._width*(_i-1)+_j].py = _value + self._vertArray[heightmap._width*(_i-1)+_j].tx = 0 + self._vertArray[heightmap._width*(_i-1)+_j].ty = 1 + self._vertArray[heightmap._width*(_i-1)+_j].tz = 0 + self._vertArray[heightmap._width*(_i-1)+_j].nx = 0 + self._vertArray[heightmap._width*(_i-1)+_j].ny = 1 + self._vertArray[heightmap._width*(_i-1)+_j].nz = 0 + #stdio.printf("%f\n", _value); + #Make a Step for the above loops, or make a loop for making the faces + #I think we need to make the element array generation code here + _i = 0 + for _i from 1 <= _i < ((heightmap._width*heightmap._height/detail))/3: + + self._elementArray[_i].a = (_i*3)-2 + self._elementArray[_i].b = (_i*3)-1 + self._elementArray[_i].c = (_i*3) + #stdio.printf("index :%d, A: %d, B: %d, C: %d\n",_i,self._elementArray[_i].a,self._elementArray[_i].b,self._elementArray[_i].c); + stdio.printf("Cinit Done!\n"); + def __dealloc__(self) : ode.dGeomHeightfieldDataDestroy(self._heightmapID) #gl.glDeleteBuffersARB(1, &self._buffer); @@ -56,13 +94,55 @@ # cdef void _createBuffer(self) : - pass - #gl.glGenBuffersARB(1, &self._buffer) - #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, self._buffer) - #gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, (sizeof(Vert)+4+12)*self._bufferAlloc, - # self._heightmap, gl.GL_STATIC_DRAW_ARB) + stdio.printf("createBuffer Start!\n"); - cdef void _render(self) : - pass + stdio.printf("%s","_render\n") + gl.glGenBuffersARB(1, <gl.GLuint*> &self._buffer) # Create the vertex buffers? + gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._buffer) + gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, (sizeof(Vert)*self._verts), + 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.glBufferDataARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._verts/3, + self._elementArray, gl.GL_STATIC_DRAW_ARB) + #gl.glGenBuffersARB(1, &self._buffer); + #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, self._buffer); + #gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, sizeof(vertices), <gl.GLvoid*>0, gl.GL_STATIC_DRAW_ARB); + #gl.glBufferSubDataARB(gl.GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), vertices); + #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, _buffer) + gl.glVertexPointer (3, gl.GL_FLOAT, sizeof(Vert), <float*> 0) + gl.glNormalPointer ( gl.GL_FLOAT, sizeof(Vert), <float*> 12) + #gl.glNormalPointer(gl.GL_FLOAT, 0, <gl.GLvoid *>0); + gl.glTexCoordPointer(3, gl.GL_FLOAT, sizeof(Vert), <float*> 24) + #gl.glDrawArrays(gl.GL_QUADS, 0, 24); + stdio.printf("%s","glDrawElements\n") + gl.glDrawElements (gl.GL_TRIANGLES, 20, + gl.GL_UNSIGNED_SHORT, <Face*> 0)#self._elementArray) + gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, 0); + Scene._render(self) + stdio.printf("Render Done!\n"); +""" +TODO : +- First Get it to render +- Divide data in to sectors +- get Sectors middle point +- Relative to the sector distance to camera, calculate LOD value +- Apply LOD algo using value +yea + the size of the number of triangles times three +its one big block to you since a landscape will have *one* material + Z texcoord can be used to change the terrain type +this means that you can use the face array for LOD more easily + see basically you can "shift up" the array, adding one to both the offset and length, such that the "base" face array is the lowest resolution and each time you shift up one it removes one triangle and replaces it with two + is, if your array has four triangles in the low resolution, ABCD + and the second step is A split = EF, B=GH, C=IJ, D=KL, then it's arranged as: + ABCDEFGHIJKL +if you're rendering the whole thing as step 1, then its offset 0 length 4 (ABCD) + if you want 50% of step2 then its offset 2, length 6, = CDEFGH + and then it's a matter of grouping these into geographic boundaries such that depending on where your camera is within the terrain it can render them in groups like this + if you try to do this on a one polygon basis you'll end up rendering too many. its easier to group them + in each group give the most radical angles the highest priority - so a steep angled triangle would be D in the above example + er, sorry, the steepest would be A +""" \ No newline at end of file _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn