How to use use glVertexPointer?
public class Point3D
{
public double x;
public double y;
public double z;
public Point3D(double p1,double p2,double p3)
{
x = p1;
y = p2;
z = p3;
}
}
Point3D[] temp = new Point3D[4];
temp[0] = new Point3D(0, 0, 0);
temp[1] = new Point3D(10, 0, 0);
temp[2] = new Point3D(10, 10, 0);
temp[3] = new Point3D(0, 10, 0);
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
//Support by Tao 1.3.
//Gl.glVertexPointer(3,Gl.GL_DOUBLE,0,ref temp[0].x); Gl.glDrawArrays(Gl.GL_LINES,0,temp.Length); Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
I face a problem on how to convert and pass an IntPtr to glVertexPointer(). Can anyone help me? Thanks.

// Easiest: double[]
// Easiest:
double[] pointlist = new double[]{0,0,0, 10,0,0, 10,10,0, 0,10,0};
// Or:
public STRUCT Point3D
{
public double x;
public double y;
public double z;
}
Point3D[] pointlist = new Point3D[4];
pointlist[1].x = 10;
pointlist[2].x = 10;
pointlist[2].y = 10;
pointlist[3].y = 10;
// Then:
GCHandle gch = GCHandle.Alloc(pointlist, AllocType.Pinned); // don't know the second enum by heart...
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glVertexPointer(3, Gl.GL_DOUBLE, 3*8, gch.AddrOfPinnedObj());
Gl.glDrawArrays(... etc.
gch.Free();
If you decide to use Vertex
If you decide to use Vertex Arrays, keep in mind that you *must* keep the array pinned for as long as you use (this might cover the whole lifetime of the program). "glVertexPointer" maintains an internal pointer to your data structure - if the GC happens to move it the effects will be disastrous.
The other solution is to call glVertexPointer to update the internal pointer just before rendering the VA (this approach is outlined above). This *could* decrease performance, as the driver will have to update its state every time you try to draw.
You can avoid this with Vertex Buffer Objects. With VBO's, the object is copied in (unmanaged) server memory and you are free to discard the original instance.
------
OpenTK
GCHandle gch =
GCHandle gch = GCHandle.Alloc(pointlist, GCHandleType.Pinned); throw exception !!!
Ok, let me try my psychic
Ok, let me try my psychic debugging skils... You need to add the StructLayoutAttribute to your Point3D class:
[StructLayout(LayoutKind.Sequential)]
public class Point3D
{
[...]
What kind of exception does GCHandle.Alloc() throw? Please paste the exact message here, our psychic debugging skills are not *that* advanced.
------
OpenTK
I am sorry, actually
I am sorry, actually SeaEagle1's suggestion is correct. I just wonder if I change the Point3D to class type it will throw an exception of "Object contains non-primitive or non-blittable data." at "GCHandle gch = GCHandle.Alloc(temp, GCHandleType.Pinned);" What should I do if I want to use a class type of Point3D instead of struct type? Thanks.
Another question. Why did
Another question. Why did Tao 2.0 remove the previous overload function glVertexPointer(3,Gl.GL_DOUBLE,ref double); (about 32 overload function) and replace with the slow GCHandle.Alloc()? Any way to keep the previous overload method?
You can't do it with a
You can't do it with a class, since an array of classes will be a list of pointers, not of the data itself. The glVertexPointer(int,int,ref double) overload is flawed for the reason explained above: you'll need to make the data that you point to available to OpenGL from glVertexPointer until glDisableClientState. Tao's overloads give OpenGL a pointer and remove it immediatly after the OpenGL call. If you don't want to use the GCHandle you can also use a
unsafe{ fixed(){ //your code } }style to get a pointer.GCHandle gch =
GCHandle gch = GCHandle.Alloc(...
Gl.glVertexPointer(...
Gl.glDrawArrays(...
gch.Free();
This will lead to crashes if used with larger arrays and/or expensive shaders, unless you call GL.Finish() after the draw command. By the time the call to drawarrays returns, the GPU will NOT be done reading from the array!
This might work in situations where your app only draws a very simple/short vertex array and the pin/release takes longer than the actual draw, but you are still facing the problem that the GC will move the array as it sees fit.
Is there any reason why not to use VBO? It is supported on OpenGL 1.5 devices and up, and completely avoids pinning after glBufferData.
Edit: There seems to be an Extension workaround mentioned 2006 http://www.opengl.org/pipeline/article/vol001_6/