Have Type, need Float Ptr

BlitzMax Forums/BlitzMax Beginners Area/Have Type, need Float Ptr

Difference(Posted 2004) [#1]
I have a type that I want to send to glMaterialfv

glMaterialfv declare is: Function glMaterialfv(face_,pname_,params_:Float Ptr)

Type color4f
Field r#,g#,b#,a#
End Type

Local ambient:color4f = New color4f
ambient.r=0.2
ambient.g=0.2
ambient.b=0.2
ambient.a=1

All these gives an errors:
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient)

glLightfv(GL_LIGHT0, GL_AMBIENT, Float Ptr(ambient))

glLightfv(GL_LIGHT0, GL_AMBIENT, Float Ptr(ambient.r))


so I end up with glLightfv(GL_LIGHT0, GL_AMBIENT, Varptr(ambient.r)) seems ok, but not too elegant ?

It will mess up if I change the Type definition later.
Is there a better way?


marksibly(Posted 2004) [#2]
Hi,

You could use a float array...

Type color4f
Field rgba#[4]
End Type

...and pass that directly...

glLightfv GL_LIGHT0, GL_AMBIENT, ambient.rgba

However, OpenGL is intrinsicly low level anyway and I'd be inclined to stick with what you've got. You'll find out pretty quickly if you move something and break it!


dmoc(Posted 2004) [#3]
From the glblur example:

...
Local glfMaterialColor#[]=[0.4#,0.2#,0.8#,1.0#]
...
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,glfMaterialColor)
...


Difference(Posted 2004) [#4]
Thanks. I had secretly hoped there would be another way, but maybe I'm imagining problems that are not there.

Can I make you consider to allow VarPtr(my.mytype) to work ?


skidracer(Posted 2004) [#5]
Peter, you can do that (Int Ptr(Varptr t:mytype)) but you need to use the varptr of the first field of the type to avoid the blitzmax header:
Type test
	Field	a,b
End Type

Local t:test=New test
Local p:Int Ptr=Varptr t.a
p[0]=10
Print t.a



Difference(Posted 2004) [#6]
or I could:

Type color4f
	Field r#,g#,b#,a#

	Method TypePtr:Float Ptr()
		Return Varptr r
	End Method	
End Type

glLightfv GL_LIGHT0, GL_AMBIENT, ambient.TypePtr()



That way I'll only have to edit the TypePtr definition if the type changes.

I still think VarPtr(t.mytype) should do it for me, or there could be a TypePtr() function in BlitzMax.
In these simple float examples you can use an array, but when you want to match a more complex C struct, it gets more tricky.


marksibly(Posted 2004) [#7]
Hi,

Converting an object to a byte ptr does it.

Unfortunately, you've got to then convert the byte ptr, so it becomes...

Float Ptr( Byte Ptr ambient )

...which ain't pretty.

Max could potentially autocast byte ptrs to anything ptrs (a bit like C and void*), but this seems drastic. Still, once you're in Ptr land...

Or, you the GL module could be modified to only use Byte Ptrs, so you'd be able to send *any* object or ptr to a GL call that required a ptr.


Difference(Posted 2004) [#8]
Thanks a lot!

Float Ptr( Byte Ptr ambient ) is exactly what I was looking for. It works.

I'll leave it to somebody else to decide if the autocast route is the one to follow.

I'm not happy about tweaking the OpenGl module myself because of the version tracking issues that will arise.


AntonyWells(Posted 2005) [#9]
a bit like C and void*


Please do. It's cleaner in the long run imo.


ImaginaryHuman(Posted 2005) [#10]
Hmm, isn't it simply a case of needing to get the pointer to the variables and then turning them into byte pointers?

ie

glLightfv(GL_LIGHT0, GL_AMBIENT, BytePtr(VarPtr(ambient.r)))

?


Difference(Posted 2005) [#11]
@AngelDaniel: What part of:
so I end up with glLightfv(GL_LIGHT0, GL_AMBIENT, Varptr(ambient.r)) seems ok, but not too elegant ?
It will mess up if I change the Type definition later.
Is there a better way?
did you not read? :D


ImaginaryHuman(Posted 2005) [#12]
Oh, well blow me down