Thread overview
Passing dynamic arrays into C.
Apr 25, 2010
Bernard Helyer
Apr 25, 2010
Daniel Murphy
Apr 25, 2010
Bernard Helyer
Apr 25, 2010
bearophile
Apr 25, 2010
Bernard Helyer
April 25, 2010
I was having a problem interfacing with OpenGL from D, as demonstrated by this program, written once in D, and again in C:

http://gist.github.com/378273

Now the 'gist' of it is, doing things like this (D):

    glBufferData(GL_ARRAY_BUFFER, vertices.sizeof,
                 vertices.ptr, GL_STATIC_DRAW);

    glVertexPointer(2, GL_FLOAT, GLfloat.sizeof * 2, cast(void*)0);

With this data (D):

    const GLfloat[] vertices = [-1.0f, -1.0f, 1.0f, -
                                 1.0f, -1.0f, 1.0f, 1.0f, 1.0f];

and the same data in C:

    const GLfloat vertices[] = {-1.0f, -1.0f, 1.0f,
                                -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};


I was getting nothing but a blank screen. I'm sure you smart folks know what comes next.

     GLfloat[] vertices = {1.0f, 1.0f};  // vertices is a dynamic array.

     GLfloat[2] vertices = {1.0f, 1.0f};  // vertices is a static array.

The second version enables the program to work as the C one does.


My question is, why doesn't passing the `GLfloat[] vertex ...` declaration work? I've looked through the docs, and can't see anything too obvious.


Thanks.
April 25, 2010
It should work if you treat the dynamic array like a pointer and a length.
eg:
glBufferData(GL_ARRAY_BUFFER, (vertices[0]).sizeof * vertices.length,
                   vertices.ptr, GL_STATIC_DRAW);

It's probably because (type).sizeof gives the number of bytes to hold the
type.
For dynamic arrays, this is the size of the (length, pointer) pair and not
the array itself.

float.sizeof // gives 4
int.sizeof // gives 4
int[].sizeof // gives 8
int[3].sizeof // gives 12

class C { int[100] d; };
C.sizeof // gives the size of the reference, not the instance.

I haven't checked the sizes, but it generally follows something like that.


"Bernard Helyer" <b.helyer@gmail.com> wrote in message news:hr0veq$2269$1@digitalmars.com...
>I was having a problem interfacing with OpenGL from D, as demonstrated by this program, written once in D, and again in C:
>
> http://gist.github.com/378273
>
> Now the 'gist' of it is, doing things like this (D):
>
>     glBufferData(GL_ARRAY_BUFFER, vertices.sizeof,
>                  vertices.ptr, GL_STATIC_DRAW);
>
>     glVertexPointer(2, GL_FLOAT, GLfloat.sizeof * 2, cast(void*)0);
>
> With this data (D):
>
>     const GLfloat[] vertices = [-1.0f, -1.0f, 1.0f, -
>                                  1.0f, -1.0f, 1.0f, 1.0f, 1.0f];
>
> and the same data in C:
>
>     const GLfloat vertices[] = {-1.0f, -1.0f, 1.0f,
>                                 -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};
>
>
> I was getting nothing but a blank screen. I'm sure you smart folks know what comes next.
>
>      GLfloat[] vertices = {1.0f, 1.0f};  // vertices is a dynamic array.
>
>      GLfloat[2] vertices = {1.0f, 1.0f};  // vertices is a static array.
>
> The second version enables the program to work as the C one does.
>
>
> My question is, why doesn't passing the `GLfloat[] vertex ...` declaration work? I've looked through the docs, and can't see anything too obvious.
>
>
> Thanks.


April 25, 2010
Bernard Helyer:
>      glBufferData(GL_ARRAY_BUFFER, vertices.sizeof,
>                   vertices.ptr, GL_STATIC_DRAW);
> 
>      glVertexPointer(2, GL_FLOAT, GLfloat.sizeof * 2, cast(void*)0);

Are you sure that vertices.sizeof is right? It can be wrong. Maybe you want something like: (vertices[0]).sizeof * vertices.length

That: cast(void*)0
is better written:
null

The sizeof of a dynamic array is 2 CPU words.

Bye,
bearophile
April 25, 2010
Ah, thank you!

The problem was I read the way T[].sizeof behaves on static arrays, thinking I was reading the section on dynamic array properties.

On 25/04/10 21:52, Daniel Murphy wrote:
> It should work if you treat the dynamic array like a pointer and a length.
> eg:
> glBufferData(GL_ARRAY_BUFFER, (vertices[0]).sizeof * vertices.length,
>                     vertices.ptr, GL_STATIC_DRAW);
>
> It's probably because (type).sizeof gives the number of bytes to hold the
> type.
> For dynamic arrays, this is the size of the (length, pointer) pair and not
> the array itself.
>
> float.sizeof // gives 4
> int.sizeof // gives 4
> int[].sizeof // gives 8
> int[3].sizeof // gives 12
>
> class C { int[100] d; };
> C.sizeof // gives the size of the reference, not the instance.
>
> I haven't checked the sizes, but it generally follows something like that.
>
>
> "Bernard Helyer"<b.helyer@gmail.com>  wrote in message
> news:hr0veq$2269$1@digitalmars.com...
>> I was having a problem interfacing with OpenGL from D, as demonstrated by
>> this program, written once in D, and again in C:
>>
>> http://gist.github.com/378273
>>
>> Now the 'gist' of it is, doing things like this (D):
>>
>>      glBufferData(GL_ARRAY_BUFFER, vertices.sizeof,
>>                   vertices.ptr, GL_STATIC_DRAW);
>>
>>      glVertexPointer(2, GL_FLOAT, GLfloat.sizeof * 2, cast(void*)0);
>>
>> With this data (D):
>>
>>      const GLfloat[] vertices = [-1.0f, -1.0f, 1.0f, -
>>                                   1.0f, -1.0f, 1.0f, 1.0f, 1.0f];
>>
>> and the same data in C:
>>
>>      const GLfloat vertices[] = {-1.0f, -1.0f, 1.0f,
>>                                  -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};
>>
>>
>> I was getting nothing but a blank screen. I'm sure you smart folks know
>> what comes next.
>>
>>       GLfloat[] vertices = {1.0f, 1.0f};  // vertices is a dynamic array.
>>
>>       GLfloat[2] vertices = {1.0f, 1.0f};  // vertices is a static array.
>>
>> The second version enables the program to work as the C one does.
>>
>>
>> My question is, why doesn't passing the `GLfloat[] vertex ...` declaration
>> work? I've looked through the docs, and can't see anything too obvious.
>>
>>
>> Thanks.
>
>

April 25, 2010
Guilty on all charges. Confused the behaviour of static and dynamic arrays with sizeof.

On 25/04/10 21:54, bearophile wrote:
> Bernard Helyer:
>>       glBufferData(GL_ARRAY_BUFFER, vertices.sizeof,
>>                    vertices.ptr, GL_STATIC_DRAW);
>>
>>       glVertexPointer(2, GL_FLOAT, GLfloat.sizeof * 2, cast(void*)0);
>
> Are you sure that vertices.sizeof is right? It can be wrong. Maybe you want something like:
> (vertices[0]).sizeof * vertices.length
>
> That: cast(void*)0
> is better written:
> null
>
> The sizeof of a dynamic array is 2 CPU words.
>
> Bye,
> bearophile