www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing dynamic arrays into C.

reply Bernard Helyer <b.helyer gmail.com> writes:
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.
Apr 25 2010
next sibling parent reply "Daniel Murphy" <yebblies nospamgmail.com> writes:
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. 
Apr 25 2010
parent Bernard Helyer <b.helyer gmail.com> writes:
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.
Apr 25 2010
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
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
Apr 25 2010
parent Bernard Helyer <b.helyer gmail.com> writes:
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
Apr 25 2010