Dynamic Vertex Buffers
BlitzMax Forums/BlitzMax Programming/Dynamic Vertex Buffers
| ||
Hi, Im really flaky with DirectX, but maybe someone can help me figure out major differences between dx7 and 8 in terms of vertex buffer implementation? I'm trying to implement a vertex cache class, and looking at old DX8 code I could create a vertex buffer with DYNAMIC flag to speed up uploading that buffer to video every frame, to be used for all dynamic geometry. This is what dx8 flags look like: pDevice->CreateVertexBuffer(maxVerts*stride, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY|PROCESSING, FVF,D3DPOOL_DEFAULT,&vBuf); I have this working for dx7 now in Blitz, but I cant find the dynamic flag :/ desc.dwCaps = D3DVBCAPS_WRITEONLY D3D7GraphicsDriver().Direct3D7().CreateVertexBuffer(desc , Varptr(VB) , 0) How do i make sure my dx7 vertex buffer is in system memory and gets best options for dynamic access? Would using DrawPrimitiveUP and passing array be any better than updating the vertex buffer and calling DrawPrimitiveVB? Maybe someone has a pointer in a direction of some dx7 optimized rendering sources, I would really appreciate that. TIA |
| ||
DX7 lacks many of this features. DX8+ got the "highly optimized vertex pipeline" features ... Not sure if you can make DX7 vertexbuffers even non-system RAM based as they have no hardware processing at all |
| ||
Could this help? |
| ||
Dug up DX7 docs and found system memory flag, but nothing about dynamic, optimized flag makes app crash :* Here is something I whipped up just now, it's not optimized or anything, but it works :D Even in this state there is some boost, drawing 12,000 sprites went to 300 fps using cache from 90 using DrawImage. An object which accumulates quads until it runs out of vertex space, then flushes the array whole. One thing to note is there is no image being used, for simplicity right now i just insert a DrawImage somewhere before so dx uploads a texture, which gets used for all the cached vertices. Needs work, but there is potential. If sorted by texture, one could achieve greater performance if big chunks of geometry can be sent in few calls. This object can also be extended to function as static VB. Another thing to note is transformations would have to be done manually before adding data to the buffer, as the whole vertex buffer gets rendered with same world transform. Init code vc:TVCache = new TVCache vc.Init() Render code DrawImage someImage, 1000, 1000 ' temporary texture fix vc.Begin() ' loop vc.AddQuad(x, y, width, height) ' next vc.Flush() And heres the vertex cache in its rudimentary form Type TVCache Field VB:IDirect3DVertexBuffer7 Field maxVerts:Int = 24000 Field curVert:Int Field vCache:TVertex[maxVerts] Field pVerts : Float Ptr Field Flushed = True Method Init() Local desc:D3DVERTEXBUFFERDESC = New D3DVERTEXBUFFERDESC desc.dwSize =SizeOf(desc) desc.dwNumVertices = maxVerts desc.dwFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 desc.dwCaps = 0 desc.dwCaps = D3DVBCAPS_WRITEONLY | D3DVBCAPS_SYSTEMMEMORY D3D7GraphicsDriver().Direct3D7().CreateVertexBuffer(desc,Varptr(VB),0) For Local i = 0 To maxVerts - 1 vCache[i] = New TVertex Next End Method Method AddQuad(x:Float , y:Float , w:Float , h:Float) If Flushed = True Then Begin() Local of = 6 pVerts[curVert*of+0] = x pVerts[curVert*of+1] = y pVerts[curVert*of+2] = 0 Int Ptr(pVerts)[curVert*of+3] = $FFFFFFFF pVerts[curVert*of+4] = 0.0 pVerts[curVert*of+5] = 0.0 curVert = curVert + 1 pVerts[curVert*of+0] = x + w pVerts[curVert*of+1] = y pVerts[curVert*of+2] = 0 Int Ptr(pVerts)[curVert*of+3] = $FFFFFFFF pVerts[curVert*of+4] = 1.0 pVerts[curVert*of+5] = 0.0 curVert = curVert + 1 pVerts[curVert*of+0] = x + w pVerts[curVert*of+1] = y + h pVerts[curVert*of+2] = 0 Int Ptr(pVerts)[curVert*of+3] = $FFFFFFFF pVerts[curVert*of+4] = 1.0 pVerts[curVert*of+5] = 1.0 curVert = curVert + 1 pVerts[curVert*of+0] = x pVerts[curVert*of+1] = y pVerts[curVert*of+2] = 0 Int Ptr(pVerts)[curVert*of+3] = $FFFFFFFF pVerts[curVert*of+4] = 0.0 pVerts[curVert*of+5] = 0.0 curVert = curVert + 1 pVerts[curVert*of+0] = x + w pVerts[curVert*of+1] = y + h pVerts[curVert*of+2] = 0 Int Ptr(pVerts)[curVert*of+3] = $FFFFFFFF pVerts[curVert*of+4] = 1.0 pVerts[curVert*of+5] = 1.0 curVert = curVert + 1 pVerts[curVert*of+0] = x pVerts[curVert*of+1] = y + h pVerts[curVert*of+2] = 0 Int Ptr(pVerts)[curVert*of+3] = $FFFFFFFF pVerts[curVert*of+4] = 0.0 pVerts[curVert*of+5] = 1.0 curVert = curVert + 1 If curVert >= maxVerts Then Flush() End If End Method Method Begin() VB.lock(DDLOCK_WAIT | DDLOCK_WRITEONLY , Varptr pVerts , Null) Flushed = False End Method Method Flush() Flushed = True VB.Unlock() D3D7GraphicsDriver().Direct3DDevice7().DrawPrimitiveVB(D3DPT_TRIANGLELIST,VB,0,curVert,0) curVert = 0 End Method End Type Type TVertex Field x:Float Field y:Float Field z:Float Field color:Int Field tu:Float Field tv:Float End Type |