• Advertisement

Archived

This topic is now archived and is closed to further replies.

structs and arrays in c++ and c#...

This topic is 5098 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I do this in c++:
typedef struct mdx_face_s
{
	int vertIndex[3];
} mdx_face_t;

...

mdx_face_t *m_pFace = new mdx_face_t[numFaces];

...

glDrawElements(GL_TRIANGLES, numFaces*3, GL_UNSIGNED_INT, m_pFace->vertIndex);
In c#:
public class mdx_face_t
{
     public int[] vertIndex = new int[3];
}

...

mdx_face_t[] m_pFace= new mdx_face_t[numFaces];

...

glDrawElements(GL_TRIANGLES, numFaces*3, GL_UNSIGNED_INT, WHAT DO I PUT HERE???????);
What do I put there? Thanks

Share this post


Link to post
Share on other sites
Advertisement
it won''t work, because arrays are not allocated inline.

define mdx_face_t as:
public struct mdx_face_t //also important so we make an array of value types, which are allocated inline
{
int i1,i2,i3;
}
mdx_face_t[] m_pFace= new mdx_face_t[numFaces];
then you should be able to call
glDrawElements(GL_TRIANGLES, numFaces*3, GL_UNSIGNED_INT, m_pFace);
or
glDrawElements(GL_TRIANGLES, numFaces*3, GL_UNSIGNED_INT, &m_pFace[0]);

depending on the signature of glDrawElements

Share this post


Link to post
Share on other sites
I don''t think this is allowed:

glDrawElements(GL_TRIANGLES, numFaces*3, GL_UNSIGNED_INT, m_pFace);


And this would just draw the first face, right?

glDrawElements(GL_TRIANGLES, numFaces*3, GL_UNSIGNED_INT, &m_pFace[0]);





Share this post


Link to post
Share on other sites
quote:
Original post by xyz And this would just draw the first face, right?

glDrawElements(GL_TRIANGLES, numFaces*3, GL_UNSIGNED_INT, &m_pFace[0]) ;


It should draw numFaces face from numFaces consecutive indices in memory, starting at &m_pFace[0]. But it kind of depends on what the ogl wrapper you are using is doing.

Share this post


Link to post
Share on other sites
BTW: it''s possible to "fake" an inline array in a struct by using the StructLayout Attribute with LayoutKind.Explicit and the Size parameter. Say you have to marshal a struct that contains 2 ints an dan array of 126 floats, then you could do


[StructLayout(LayoutKind.Explicit, Size=512)]
struct SampleStruct
{
[FieldOffset(504)]
public int Integer1;
[FieldOffset(508)]
public int Integer2;
[FieldOffset(0)]
public float BigChunk;
}


In unsafe code, you can access the float like this:

unsafe
{
SampleStruct s = new SampleStruct();

// access the 76th float:
(&s.BigChunk)[75] = 34.4f;
}


Attention: this is no good style at all and should be used only for internal cases, but sometimes it''s very handy (and necessary) to know such things.

Regards,
VizOne

Share this post


Link to post
Share on other sites
but isn''t there a "normal", managed, safe way of doing this?

Share this post


Link to post
Share on other sites
quote:
Original post by xyz
but isn''t there a "normal", managed, safe way of doing this?


What OGL wrapper are you using?(or are you PInvoking it?) What are you supposed to pass to glDrawElements?

Share this post


Link to post
Share on other sites
I''m using Tao... I can pass:

void*
IntPtr
uint[]
ushort[]
float[]
int[]
short[]
double[]
byte[]

Share this post


Link to post
Share on other sites
Yes there is a better way, with a little help of a GCHandle.

example:

[StructLayout(LayoutKind.Sequential)]
public struct Triangle {
int x1, x2, x3;
}

...

public class Mesh {

public Triangle[] Triangles;
private GCHandle triangleHandle;
public IntPtr TrianglePointer;

public Mesh(Triangle[] triangles) {
this.Triangles = triangles;
AllocateHandles();
}

public void AllocateHandles() {
triangleHandle = GCHandle.Alloc(Triangles, GCHandleType.Pinned);
TrianglePointer = triangleHandle.AddrOfPinnedObject();
}

public void FreeHandles() {
triangleHandle.Free();
TrianglePointer = IntPtr.Zero;
}

~Mesh() {
FreeHandles();
}

...

Mesh mesh = new Mesh(...);

...

Gl.glDrawElements(Gl.GL_TRIANGLES, mesh.Triangles.Length*3, Gl.GL_UNSIGNED_INT, mesh.TrianglePointer);

You have to lock the managed memory somehow, otherwise the GC could move it.




[edited by - Xanthos on March 8, 2004 3:50:35 PM]

Share this post


Link to post
Share on other sites

  • Advertisement