[Gambas-devel] Interface of gb.opengl.sge

Benoît Minisini gambas at ...1...
Thu Mar 28 16:39:33 CET 2013


Le 28/03/2013 16:08, Tomek a écrit :
> On 28.03.2013 09:53, Benoît Minisini wrote:
>> Le 28/03/2013 09:24, Tomek a écrit :
>>> On 28.03.2013 02:41, Benoît Minisini wrote:
>>>> Hi Tomek,
>>>>
>>>> I took a glance at your code, and I strongly suggest the following
>>>> changes to the gb.opengl.gse interface before you go further.
>>>>
>>>> Why these changes? Mainly because I try to make Gambas components have
>>>> the most similar interfaces as possible, so that the learning curve is
>>>> lower.
>>>>
>>>> By the way, not that there is a design problem too : the MD2 model
>>>> loading routine only works if the endianness of the CPU is the same as
>>>> the endianness of the file. You should ensure that if the endianness is
>>>> different, you swap the binary data accordingly.
>>>>
>>>> Now the old interface :
>>>>
>>>> GB_DESC Md2ModelDesc[] =
>>>> {
>>>>       GB_DECLARE("Md2Model", sizeof(MD2MODEL)),
>>>>       GB_NOT_CREATABLE(),
>>>>       GB_STATIC_METHOD("Load", "Md2Model" , Md2Model_Load, "(Name)s"),
>>>>       GB_METHOD("SetPosition", NULL, Md2Model_SetPosition,
>>>> "(X)f(Y)f(Z)f" ),
>>>>       GB_METHOD("DrawFrame", NULL, Md2Model_DrawFrame,
>>>> "(Frame_No)i(Texture)i" ),
>>>>       GB_METHOD("DrawInterFrame", NULL, Md2Model_DrawInterFrame,
>>>> "(Frame_No)i(InterFrame)f(Texture)i" ),
>>>>       GB_METHOD("GetFramesNo", "i", Md2Model_GetNoFrames, NULL ),
>>>>       GB_METHOD("GetFrameName", "s", Md2Model_GetFrameName,
>>>> "(FrameNumber)i" ),
>>>>       GB_METHOD("Scale", NULL, Md2Model_Scale,
>>>> "(Scale_x)f(Scale_y)f(Scale_z)f" ),
>>>>       GB_METHOD("_free", NULL, Md2Model_free, NULL ),
>>>>       GB_END_DECLARE
>>>> };
>>>>
>>>> The new one I suggest:
>>>>
>>>> GB_DESC Md2ModelDesc[] =
>>>> {
>>>>       GB_DECLARE("Md2Model", sizeof(MD2MODEL)),
>>>>       GB_NOT_CREATABLE(),
>>>>       GB_STATIC_METHOD("Load", "Md2Model" , Md2Model_Load, "(Name)s"),
>>>>       // 'SetPosition' renamed to 'Move'
>>>>       GB_METHOD("Move", NULL, Md2Model_SetPosition, "(X)f(Y)f(Z)f" ),
>>>>       // Three properties to get/set the one coordinate
>>>>       GB_PROPERTY("X", "f", Md2Model_X),
>>>>       GB_PROPERTY("Y", "f", Md2Model_X),
>>>>       GB_PROPERTY("Z", "f", Md2Model_X),
>>>>       // A virtual object for accessing frame properties and count
>>>>       GB_PROPERTY_SELF("Frames", ".Md2Model.Frames"),
>>>>       GB_METHOD("Scale", NULL, Md2Model_Scale,
>>>> "(ScaleX)f(ScaleY)f(ScaleZ)f" ),
>>>>       // Maybe you should add ScaleX, ScaleY and ScaleZ properties too.
>>>>       GB_METHOD("_free", NULL, Md2Model_free, NULL ),
>>>>       GB_END_DECLARE
>>>> };
>>>>
>>>> GB_DESC Md2ModelFramesDesc[] =
>>>> {
>>>>       GB_DECLARE_VIRTUAL(".Md2Model.Frames"),
>>>>       // Was Md2Model_GetNoFrames
>>>>       GB_PROPERTY_READ("Count", "i", Md2Model_Frames_Count)
>>>>       GB_METHOD("_get", ".Md2Model.Frame", Md2Model_Frames_get,
>>>> "(Frame)i"),
>>>>       GB_END_DECLARE
>>>> }
>>>>
>>>> // The _get method of Md2Model_Frames is implemented that way:
>>>>
>>>> BEGIN_METHOD(Md2Model_Frames_get, GB_INTEGER frame)
>>>>
>>>>       // Store the frame number into the object, it will be used
>>>> immediately
>>>>       // by the method called on the virtual .Md2Model.Frame object.
>>>>       // Maybe check that the frame number is valid now.
>>>>       // And don't forget to add the 'frame' field into the object
>>>>       // structure.
>>>>       THIS->frame = VARG(frame);
>>>>
>>>> END_METHOD
>>>>
>>>> GB_DESC Md2ModelFrameDesc[] =
>>>> {
>>>>       GB_DECLARE_VIRTUAL(".Md2Model.Frame"),
>>>>       // Was 'Md2Model.DrawFrame'
>>>>       GB_METHOD("Draw", NULL, Md2Model_Frame_Draw, "(Texture)i"),
>>>>       // Was 'Md2Model.DrawInterFrame'
>>>>       GB_METHOD("DrawInterFrame", NULL, Md2Model_Frame_DrawInterFrame,
>>>> "(InterFrame)f(Texture)i"),
>>>>       GB_END_DECLARE
>>>> }
>>>>
>>>> Tell me what you think about that and if you have questions!
>>>>
>>>> Regards,
>>>>
>>> Hi Benoit,
>>>
>>> Thanks for your suggestions, I will try to do as much a I can using
>>> devel-api documentation page. It's the best way to learn I think. When
>>> I'm stuck, I'll ask for your help, ok?
>>> Question 1 - How do I check endianess of the CPU from component level?
>> You must read a well known two or four bytes integer value from the file
>> with fread, and see if you get it swapped or not.
>>
>> If you get it swapped, then you know that all binary values must be
>> swapped.
>>
>> You can use the magic identifier at the beginning of the file, but
>> beware that you must check it byte by byte before reading it as a binary
>> data.
>>
>> Otherwise you may take some files starting with the magic number
>> inverted as MD2 model files!
> As I absolutely have no means to test Big-Endianness, I think I'll just
> put GB.Error("Big Endian not supported yet."), if reading header gives
> reversed value.
>
>
>>> One more question - what would be the best way to make the class
>>> creatable - Md2Model_new I suppose, but what should be in that function?
>>> Can it be empty? Without creatable class I can't make an array of it.
>> Yes, you must be able to create void models, and manage them in all
>> functions.
>>
>> If a void model must not be used anywhere, you can use the "check hook".
>>
>> You declare the check hook in the class description structure with:
>>
>> GB_HOOK_CHECK(my_check_function),
>>
>> Then 'my_check_function' must be a function taking a pointer to a
>> Md2Model object and returning an integer different from zero if that
>> object is invalid. (The interpreter will raise the 'Invalid object'
>> error).
>>
>> Moreover, you must think about implementing boolean operators between
>> models if it has some sense (merging two models for example). I have no
>> idea, not being an OpenGL expert, but if you want to implement such a
>> thing, then a void model must be perfectly valid then.
>>
>> Regards,
>>
> Is it similar to cquad class in GLU? But Md2Model has no external
> initiator as quadric do.

No idea. :-)

But if you have two models, maybe it is possible to create one model 
that is the union of both. But I have no idea if it is possible or 
useful. I just told you so in case.

>
> I made some changes if file, but cant figure out how to return frame
> object. File Md2Model.c attached.

Sorry, I forgot a line:

BEGIN_METHOD(Md2Model_Frames_get, GB_INTEGER frame)

   // Store the frame number into the object, it will be used immediately
   // by the method called on the virtual .Md2Model.Frame object.
   // Maybe check that the frame number is valid now.
   // And don't forget to add the 'frame' field into the object
   // structure.
   THIS->frame = VARG(frame);
   GB_RETURN_SELF();

END_METHOD

Then the Md2Model_Frame_Draw method does not take the frame number as 
argument anymore. It will use 'THIS->frame' internally instead.

Regards,

-- 
Benoît Minisini




More information about the Devel mailing list