Vertexbuffer example

BlitzMax Forums/BlitzMax Programming/Vertexbuffer example

Hi all,

here's an example rendering an tri using DX vertexbuffers. It runs without errors (good) but without a rendered tri (bad). The data copied to the buffer should be ok cause using them in a DrawPrimitive works well.

Any clue what's going wrong here?

Graphics 800,600,0,0

'Type D3DVERTEXBUFFERDESC 
'	Field dwSize
'	Field dwCaps
'	Field dwFVF
'	Field dwNumVertices
'End Type

Global result:Int
Global verts:Float[12]
Global pverts:Byte Ptr

Global d3dVertexBuffer:IDirect3DVertexBuffer7
Global desc:D3DVERTEXBUFFERDESC = New D3DVERTEXBUFFERDESC

pVerts = verts
global vi:Int Ptr=Int Ptr(pverts)

verts[0]=100
verts[1]=100
verts[2]=0
vi[3]=$FFFFFFFF

verts[4]=200
verts[5]=100
verts[6]=0
vi[7]=$FFFFFFFF

verts[8]=150
verts[9]=150
verts[10]=0
vi[11]=$FFFFFFFF



desc.dwSize =SizeOf(desc)
desc.dwNumVertices = 3
desc.dwFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE 
desc.dwCaps = D3DVBCAPS_WRITEONLY
result=9999
result=D3D7GraphicsDriver().Direct3D7().CreateVertexBuffer(desc,varptr(d3dVertexBuffer),0)
Print "Create = "+result
result=9999

global bufsize%
global pbuf:Int ptr=varptr(bufsize)

result=d3dVertexBuffer.lock(DDLOCK_WAIT|DDLOCK_WRITEONLY,pverts,pbuf)
Print "Lock = "+result+" => buffersize: "+bufsize
print "copying "+sizeof(verts)+" bytes to buffer"

verts[0]=100
verts[1]=100
verts[2]=0
vi[3]=$FFFFFFFF

verts[4]=300
verts[5]=100
verts[6]=0
vi[7]=$FFFFFFFF

verts[8]=200
verts[9]=200
verts[10]=0
vi[11]=$FFFFFFFF

MemCopy(pverts,verts,sizeof(verts))
MemCopy(verts,pverts,sizeof(verts))

result=9999
result=d3dVertexBuffer.Unlock()
Print "Unlock = "+result
result=9999
result=D3D7GraphicsDriver().Direct3DDevice7().DrawPrimitiveVB(D3DPT_TRIANGLELIST,d3dVertexBuffer,0,3,0)
print "Draw = "+result

'This is working:
'D3D7GraphicsDriver().Direct3DDevice7().DrawPrimitive (D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE, pverts,3,0)

Flip
waitkey()
end


Happy Eve and a good new year to everyone!
Jake

Vertex Normals?

Glad you read this thread, Indiepath ;)
My code is based on your example you posted here a year ago. Unfortunately it don't work any more - could be the new DX-mod.

I tested the above with added normals, no change in behaviour. No errors but nothing to see.

I tried D3DFVF_XYZRHW | D3DFVF_DIFFUSE as well. DrawPrimitive works, DrawPrimitiveVB not.
I think that the order and kind of information in verts[] is correct, otherwise DrawPrimitive would also fail, right?

Do I use the Memcopy-part in a right way?
My DX7-docs mentioned a function called Direct3DVertexBuffer7.SetVertices. Maybe I have to use it, though it's not declared in pub.directx?

I have the feeling that everything is in the right place and just a tiny little brick is missing to make it work :(

Took me ages to get it working myself, when I have some more time I'll take a look at the code. My hunch is that your normals are pointing in the wrong direction or your not filling the buffer correctly.

"vertex normals" Aha this is something I know from my teen 3D programming days. You must define the points clockwise to be visible (the normal points towards you) or anti-clockwise to be invisible (it points away) (could be the other way round, been a long time...) Be nice if that was the problem, but I guess that's too simple ...

D3D has lighting turned on by default - try turning it off or setting the ambient color white.

Hi Mark,

I'll check this out when I'm back at home this evening. It's strange that DrawPrimitive() works with the same data, so I wouldn't have checked environment things like lighthing and such first. Nevertheless I'll try anything ;)

You know any "behind the scene" differences between DrawPrimitive() and DrawPrimitiveVB() ?

Reading the Dx7 docs I assume that the only difference (beside speed) is that with VB the data could be stored as a whole in VRam. So it *should* work if data is correct and Memcopy works.


You know any "behind the scene" differences between DrawPrimitive() and DrawPrimitiveVB() ?


Crap, didn't read that bit!

If it's drawing OK with DrawPrimitive, it should draw OK with DrawPrimitiveVB too.

You should probably check the VB code though. Have you remembered to unlock the VB after writing to it? etc...

D3D7GraphicsDriver().Direct3D7().CreateVertexBuffer(desc,varptr(d3dVertexBuffer),0) 'returns 0
d3dVertexBuffer.lock(DDLOCK_WAIT|DDLOCK_WRITEONLY,pverts,pbuf) 'returns 0, bufsize returns sizeof(verts), so should be ok
MemCopy(pverts,verts,sizeof(verts))
d3dVertexBuffer.Unlock() 'returns 0
D3D7GraphicsDriver().Direct3DDevice7().DrawPrimitiveVB(D3DPT_TRIANGLELIST,d3dVertexBuffer,0,3,0) 'returns 0


What's about the Memcopy, do I call this in a right way?
All DX-commands return no error, so the only major difference is that using DrawPrimitiveVB I manually copy the data, while DrawPrimitive() takes a pointer to my data.

Thanks for all your effort
Jake

Sorry I didnt see this sooner, change this line
result=d3dVertexBuffer.lock(DDLOCK_WAIT|DDLOCK_WRITEONLY,pverts,pbuf)


to
result=d3dVertexBuffer.lock(DDLOCK_WAIT|DDLOCK_WRITEONLY,Varptr pverts,pbuf)


the lock is setting the pVerts pointer value.

Full example

SuperStrict

Function DXError( n:Int,msg$="DXERROR" )
	If n=0 Return
	WriteStdout msg+" err="+ n+"~n"
	End
End Function


Function CreateVB : IDirect3DVertexBuffer7()
	Local desc:D3DVERTEXBUFFERDESC = New D3DVERTEXBUFFERDESC
	Local d3dVertexBuffer:IDirect3DVertexBuffer7
	desc.dwSize =SizeOf(desc)
	desc.dwNumVertices = 3
	desc.dwFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE 
	desc.dwCaps = 0	
	desc.dwCaps = D3DVBCAPS_WRITEONLY
	DXError(D3D7GraphicsDriver().Direct3D7().CreateVertexBuffer(desc,Varptr(d3dVertexBuffer),0))
	Return d3dVertexBuffer
End Function

Function InitVB(vb : IDirect3DVertexBuffer7)
	Local pVerts : Float Ptr
	DXError(vb.lock(DDLOCK_WAIT|DDLOCK_WRITEONLY,Varptr pVerts,Null))
	pVerts[0]=100.0
	pVerts[1]=100.0
	pVerts[2]=0.0
	Int Ptr(pVerts)[3]=$FFFFFFFF
	
	pVerts[4]=200.0
	pVerts[5]=100.0
	pVerts[6]=0.0
	Int Ptr(pVerts)[7]=$FFFFFFFF

	pVerts[8]=150.0
	pVerts[9]=150.0
	pVerts[10]=0.0
	Int Ptr(pVerts)[11]=$FFFFFFFF
	DXError(d3dVertexBuffer.Unlock())
End Function



Graphics 800,600,0,0
Global d3dVertexBuffer :IDirect3DVertexBuffer7=CreateVB()
InitVB(d3dVertexBuffer) 
DXError(D3D7GraphicsDriver().Direct3DDevice7().DrawPrimitiveVB(D3DPT_TRIANGLELIST,d3dVertexBuffer,0,3,0))
Flip
WaitKey()


End



Budman is the man! Jake does this mean that the example code you sent me can be fixed for DX now?

@Budman

You're wonderful, this little Varptr() was the missing brick! THANK YOU VERY MUCH, YOU MADE MY DAY !!!!!!!!!!!!

@Grey
Yeah ;)

Now back to coding...with a smile on my face....

Jake

Your welcome.

Doug Stastny