Changeset 1306

Show
Ignore:
Timestamp:
07/09/08 21:37:18 (5 months ago)
Author:
DavidCzech
Message:

Ticket #929 : Landscape VBOs almost working.

Location:
trunk/pysoy
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/pysoy/examples/LandScape.py

    r1301 r1306  
    44from time import sleep 
    55 
    6 heightTex = soy.transports.File('media/heightmap.soy')['gimp'] 
    76 
    8 heightMap = soy.scenes.landscape(heightTex) 
     7### Start Heightmap Code 
     8heightTex = soy.transports.File('media/white.soy')['gimp'] 
     9sleep(2) # HACK: this will wait while transportloop does his stuff 
     10heightScene = soy.scenes.Landscape(heightTex,soy.materials.Material()) 
     11#sce = soy.scenes.Scene() 
     12#heightScene = soy.scenes.Scene();# with normal scene, everything is peachy 
     13### Start PySoy Code (Excerpt from pysoy-primer.py) 
     14# Initialize a window  
     15 
     16scr = soy.Screen() 
     17win = soy.Window(scr, "A Spinning Cube") 
     18 
     19# Create a cube with a shape, material and a body. 
     20cube = soy.shapes.Box(1, 1, 1) # Step 1: Shape 
     21mat = soy.materials.Material() # Step 2: Material 
     22mat.shininess = 5 # (Optional) Looks nicer (modifies the applied specular lighting; play with this setting to see how it affects appearance) 
     23body = soy.bodies.Body(scene=heightScene, model=soy.models.Shape(mat), shape=cube, position=(0,-2,0)) # Step 3: Body 
     24 
     25# Put a light and camera into the initialized screen 
     26light = soy.bodies.Light(heightScene) 
     27camera = soy.bodies.Camera(heightScene) 
     28#stx = soy.widgets.StackX(win) 
     29#pro = soy.widgets.Projector(stx, camera=camera) 
     30#cam2 = soy.bodies.Camera(sce) 
     31#cam2.position = (-0.3, 0.0, 15.0) 
     32#pro2 = soy.widgets.Projector(stx, camera=cam2) 
     33 
     34pro = soy.widgets.Projector(win, camera=camera) 
     35 
     36#lig = soy.bodies.Light(sce) 
     37#lig.position = (-10.0,10.0,2.0) 
     38 
     39camera.position = (0, -2, 5.0) #50? 
     40light.position = (0.5, 1.0, 5.0) 
     41#heightScene.gravity = (0,-1,0) 
     42#mat=soy.materials.Material() 
     43#a=soy.bodies.Body(scene=sce,model=soy.models.Shape(mat),shape=soy.shapes.Box(2,1,2),position=(0,-1.2,-1)) 
    944 
    1045if __name__ == "__main__": 
    11         #mainloop goes here 
    12         while 1: 
    13                 sleep(0.1) 
     46  #mainloop goes here 
     47  while 1: 
     48    sleep(1) 
     49    #print body.position #annoying 
  • trunk/pysoy/include/soy.scenes.pxd

    r1274 r1306  
    8181  cdef ode.dGeomID                _heightmap 
    8282  cdef int                        _width 
     83  cdef int                        _depth 
    8384  cdef int                        _height 
    8485  cdef gl.GLuint                  _buffer 
     86  cdef gl.GLuint                  _elementbuffer 
    8587  cdef void                       _createBuffer   ( self ) 
     88  cdef int                        _verts 
     89  cdef Vert*                      _vertArray 
     90  cdef Face*                      _elementArray 
     91  cdef gl.GLfloat*                vertices[72] 
    8692   
    8793cdef class Planar (Scene) : 
  • trunk/pysoy/src/scenes/Landscape.pym

    r1224 r1306  
    2323 
    2424    This is a scene based on a heightmap. 
    25     Accepts a heightmap and the width, depth, and heigth of it. 
     25    Accepts a heightmap with the detail of it, the width, depth, and height of it. 
    2626  ''' 
    2727 
     
    3131  # 
    3232 
    33   def __cinit__(self, heightmap, scale, width=1024, depth=1024, *args, **kw) : 
    34     if not isinstance(soy.textures.Texture, heightmap) or heightmap._chans != 1 : 
    35       raise TypeError('heightmap must be of type soy.textures.Texture and 1 channel.') 
    36     self._width = width 
    37     self._depth = depth 
     33  def __cinit__(self, soy.textures.Texture heightmap,soy.materials.Material mat, detail = 1, width=1024, depth=1024, height=1024, *args, **kw) : 
     34    cdef int _i, _j 
     35    cdef double _value 
     36    if not isinstance(heightmap, soy.textures.Texture) or heightmap._chans != 1 : 
     37      raise TypeError('Heightmap must be of type soy.textures.Texture and 1 channel, not '+str(heightmap._chans)) 
     38    #We need to make an array on the heap, and put the verts there 
     39    stdio.printf("Cinit Start!\n"); 
     40    # Now we need to define the vars somehow (like px py pz, tx ty ...) 
     41    self._verts  = 0 
     42    self._width  = width 
     43    self._depth  = depth 
     44    self._height = height 
    3845    self._heightmapID = ode.dGeomHeightfieldDataCreate() 
     46    self._vertArray = <Vert *> py.PyMem_Malloc((heightmap._width*heightmap._height/detail)*16*4)  
     47    self._elementArray =  <Face *> py.PyMem_Malloc(sizeof(Face)*((heightmap._width*heightmap._height/detail))/3) #21k*Face 
     48    #for _i from 0 < _i < 72: 
    3949    ode.dGeomHeightfieldDataBuildByte(self._heightmapID, 
    4050                                      <unsigned char*> heightmap._texels, 0, 
     
    4454                                      1, 0, 1, 0) 
    4555    self._heightmap = ode.dCreateHeightfield(self._spaceID, self._heightmapID, 1) 
    46  
    47  
     56    ##Setup Arrays Here 
     57    for _i from 1 <= _i < heightmap._width : 
     58      for _j from 1 <= _j < heightmap._height :  
     59        self._verts +=1 
     60        # Get the y value here 
     61        _value = heightmap._texels[heightmap._width*(_i-1)+_j] 
     62        #stdio.printf("%d\n",value) 
     63        #yea, so now value*scale got  
     64        _value = _value/255.0 #255 is max, so if the value == 255(white) then its a 1 for high, thats mul'ed by height 
     65        self._vertArray[heightmap._width*(_i-1)+_j].px = _i 
     66        self._vertArray[heightmap._width*(_i-1)+_j].pz = _j 
     67        self._vertArray[heightmap._width*(_i-1)+_j].py = _value 
     68        self._vertArray[heightmap._width*(_i-1)+_j].tx = 0 
     69        self._vertArray[heightmap._width*(_i-1)+_j].ty = 1 
     70        self._vertArray[heightmap._width*(_i-1)+_j].tz = 0 
     71        self._vertArray[heightmap._width*(_i-1)+_j].nx = 0 
     72        self._vertArray[heightmap._width*(_i-1)+_j].ny = 1 
     73        self._vertArray[heightmap._width*(_i-1)+_j].nz = 0 
     74        #stdio.printf("%f\n", _value); 
     75        #Make a Step for the above loops, or make a loop for making the faces 
     76        #I think we need to make the element array generation code here 
     77    _i = 0 
     78    for _i from 1 <= _i < ((heightmap._width*heightmap._height/detail))/3: 
     79         
     80        self._elementArray[_i].a = (_i*3)-2 
     81        self._elementArray[_i].b = (_i*3)-1 
     82        self._elementArray[_i].c = (_i*3) 
     83        #stdio.printf("index :%d, A: %d, B: %d, C: %d\n",_i,self._elementArray[_i].a,self._elementArray[_i].b,self._elementArray[_i].c); 
     84    stdio.printf("Cinit Done!\n"); 
     85     
    4886  def __dealloc__(self) : 
    4987    ode.dGeomHeightfieldDataDestroy(self._heightmapID) 
     
    5795 
    5896  cdef void _createBuffer(self) : 
    59     pass 
    60     #gl.glGenBuffersARB(1, &self._buffer) 
    61     #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, self._buffer) 
    62     #gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, (sizeof(Vert)+4+12)*self._bufferAlloc, 
    63     #                   self._heightmap, gl.GL_STATIC_DRAW_ARB) 
    64  
     97    stdio.printf("createBuffer Start!\n");     
    6598 
    6699  cdef void _render(self) : 
    67     pass 
     100    stdio.printf("%s","_render\n") 
     101    gl.glGenBuffersARB(1, <gl.GLuint*> &self._buffer) # Create the vertex buffers? 
     102    gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._buffer) 
     103    gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, (sizeof(Vert)*self._verts), 
     104                       self._vertArray, gl.GL_STATIC_DRAW_ARB) 
     105    gl.glGenBuffersARB(1, &self._elementbuffer) 
     106    gl.glBindBufferARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._elementbuffer)  # Create the elements buffers 
     107    gl.glBufferDataARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._verts/3, 
     108                       self._elementArray, gl.GL_STATIC_DRAW_ARB) 
     109    #gl.glGenBuffersARB(1, &self._buffer); 
     110    #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, self._buffer); 
     111    #gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, sizeof(vertices), <gl.GLvoid*>0, gl.GL_STATIC_DRAW_ARB); 
     112    #gl.glBufferSubDataARB(gl.GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), vertices); 
     113    #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, _buffer) 
     114    gl.glVertexPointer  (3,  gl.GL_FLOAT, sizeof(Vert), <float*>  0) 
     115    gl.glNormalPointer  (    gl.GL_FLOAT, sizeof(Vert), <float*> 12) 
     116    #gl.glNormalPointer(gl.GL_FLOAT, 0, <gl.GLvoid *>0); 
     117    gl.glTexCoordPointer(3, gl.GL_FLOAT, sizeof(Vert), <float*> 24) 
     118    #gl.glDrawArrays(gl.GL_QUADS, 0, 24); 
     119    stdio.printf("%s","glDrawElements\n") 
     120    gl.glDrawElements (gl.GL_TRIANGLES, 20, 
     121                    gl.GL_UNSIGNED_SHORT, <Face*> 0)#self._elementArray) 
     122    gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, 0); 
     123    Scene._render(self) 
     124    stdio.printf("Render Done!\n"); 
     125""" 
    68126 
     127TODO : 
     128- First Get it to render 
     129- Divide data in to sectors 
     130- get Sectors middle point 
     131- Relative to the sector distance to camera, calculate LOD value 
     132- Apply LOD algo using value 
     133yea 
     134 the size of the number of triangles times three 
     135its one big block to you since a landscape will have *one* material 
     136 Z texcoord can be used to change the terrain type  
     137this means that you can use the face array for LOD more easily 
     138 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 
     139 is, if your array has four triangles in the low resolution, ABCD 
     140 and the second step is A split = EF, B=GH, C=IJ, D=KL, then it's arranged as: 
     141 ABCDEFGHIJKL 
     142if you're rendering the whole thing as step 1, then its offset 0 length 4 (ABCD) 
     143 if you want 50% of step2 then its offset 2, length 6, = CDEFGH 
     144 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 
     145 if you try to do this on a one polygon basis you'll end up rendering too many. its easier to group them 
     146 in each group give the most radical angles the highest priority - so a steep angled triangle would be D in the above example 
     147 er, sorry, the steepest would be A 
     148"""