
VB.NET and interleaving problem
Posted Thursday, 20 January, 2011 - 02:11 by vmelkon inRendering with immediate code works, however that was only a test. I need to render my vertex structure with regular vertex arrays.
glGetError() returns 0, so there is no error.
I have posted the entire code but the relevant part starts with Call GL.EnableClientState(ArrayCap.VertexArray).
Also notice my "Structure TVertex_VNTC"
and
"Public Structure TVertex_VNTC2".
Imports OpenTK Imports OpenTK.GLControl Imports OpenTK.Platform Imports OpenTK.Graphics.OpenGL Public Class Form1 Public Structure TVertex_VNTC Dim x As Single Dim y As Single Dim z As Single Dim nx As Single Dim ny As Single Dim nz As Single Dim S As Single Dim T As Single Dim mcolor As Color Dim garbage0 As Single Dim garbage1 As Single Dim garbage2 As Single Dim garbage3 As Single Dim garbage4 As Single Dim garbage5 As Single End Structure Public Structure TVertex_VNTC2 Dim x As Single Dim y As Single Dim z As Single Dim nx As Single Dim ny As Single Dim nz As Single Dim S As Single Dim T As Single Dim red As Byte Dim green As Byte Dim blue As Byte Dim alpha As Byte Dim garbage0 As Single Dim garbage1 As Single Dim garbage2 As Single Dim garbage3 As Single Dim garbage4 As Single Dim garbage5 As Single End Structure Private MyTextureID As Integer Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim TextureID As Integer TextureID = 100 GL.GenTextures(1, TextureID) GL.DeleteTextures(1, TextureID) Dim res() As String = GetType(Form1).Assembly.GetManifestResourceNames() PictureBox1.Image = New System.Drawing.Bitmap(GetType(Form1).Assembly.GetManifestResourceStream(res(2))) CreateFontTexture(MyTextureID) End Sub Private Sub GlControl1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles GlControl1.Paint Dim pVertex(4) As TVertex_VNTC2 Dim pIndex16Bit(6) As Short GL.ClearColor(1.0, 1.0, 0.0, 0.0) GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit) GL.Color4(1.4F, 1.4F, 1.0F, 0.0F) GL.BindTexture(TextureTarget.Texture2D, MyTextureID) GL.Enable(EnableCap.Texture2D) pVertex(0).x = -1.0F pVertex(0).y = -1.0F pVertex(0).z = 0.5F pVertex(0).S = 0.0F pVertex(0).T = 0.0F pVertex(0).nx = 0.0F pVertex(0).ny = 0.0F pVertex(0).nz = 0.0F 'pVertex(0).mcolor = Color.FromArgb(CType(255, Byte), CType(255, Byte), CType(255, Byte), CType(255, Byte)) pVertex(0).red = 255 pVertex(0).green = 255 pVertex(0).blue = 255 pVertex(0).alpha = 255 pVertex(1).x = 1.0F pVertex(1).y = -1.0F pVertex(1).z = 0.5F pVertex(1).S = 1.0F pVertex(1).T = 0.0F pVertex(1).nx = 0.0F pVertex(1).ny = 0.0F pVertex(1).nz = 0.0F 'pVertex(1).mcolor = Color.FromArgb(CType(255, Byte), CType(255, Byte), CType(255, Byte), CType(255, Byte)) pVertex(1).red = 255 pVertex(1).green = 255 pVertex(1).blue = 255 pVertex(1).alpha = 255 pVertex(2).x = -1.0F pVertex(2).y = 1.0F pVertex(2).z = 0.5F pVertex(2).S = 0.0F pVertex(2).T = 1.0F pVertex(2).nx = 0.0F pVertex(2).ny = 0.0F pVertex(2).nz = 0.0F 'pVertex(2).mcolor = Color.FromArgb(CType(255, Byte), CType(255, Byte), CType(255, Byte), CType(255, Byte)) pVertex(2).red = 255 pVertex(2).green = 255 pVertex(2).blue = 255 pVertex(2).alpha = 255 pVertex(3).x = 1.0F pVertex(3).y = 1.0F pVertex(3).z = 0.5F pVertex(3).S = 1.0F pVertex(3).T = 1.0F pVertex(3).nx = 0.0F pVertex(3).ny = 0.0F pVertex(3).nz = 0.0F 'pVertex(3).mcolor = Color.FromArgb(CType(255, Byte), CType(255, Byte), CType(255, Byte), CType(255, Byte)) pVertex(3).red = 255 pVertex(3).green = 255 pVertex(3).blue = 255 pVertex(3).alpha = 255 pIndex16Bit(0) = 0 pIndex16Bit(1) = 1 pIndex16Bit(2) = 2 pIndex16Bit(3) = 2 pIndex16Bit(4) = 1 pIndex16Bit(5) = 3 #If 0 Then GL.Begin(BeginMode.Quads) GL.TexCoord2(0.0, 0.0) GL.Vertex3(-1.0F, -1.0F, 0.5F) GL.TexCoord2(0.0, 1.0) GL.Vertex3(1.0F, -1.0F, 0.5F) GL.TexCoord2(1.0, 1.0) GL.Vertex3(1.0F, 1.0F, 1.0F) GL.TexCoord2(1.0, 0.0) GL.Vertex3(-1.0F, 1.0F, 1.0F) GL.End() #End If Call GL.Disable(EnableCap.CullFace) Call GL.EnableClientState(ArrayCap.VertexArray) Call GL.EnableClientState(ArrayCap.NormalArray) Call GL.EnableClientState(ArrayCap.TextureCoordArray) Call GL.EnableClientState(ArrayCap.ColorArray) Dim q = System.Runtime.InteropServices.Marshal.SizeOf(pVertex(0)) Call GL.VertexPointer(3, VertexPointerType.Float, q, pVertex(0).x) Call GL.NormalPointer(NormalPointerType.Float, q, pVertex(0).nx) Call GL.TexCoordPointer(2, TexCoordPointerType.Float, q, pVertex(0).S) ' Call GL.ColorPointer(4, ColorPointerType.UnsignedByte, q, pVertex(0).mcolor.R) Call GL.ColorPointer(4, ColorPointerType.UnsignedByte, q, pVertex(0).red) Call GL.DrawElements(BeginMode.Triangles, 6, DrawElementsType.UnsignedShort, pIndex16Bit(0)) Dim ddd = GL.GetError() GlControl1.SwapBuffers() End Sub Private Sub GlControl1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles GlControl1.Resize 'Dim glrc As HGLRC 'glrc = wglGetCurrentContext() ResizeGL() End Sub Private Sub ResizeGL() GL.Viewport(0, 0, GlControl1.Width, GlControl1.Height) GL.MatrixMode(MatrixMode.Projection) ' Select The Projection Matrix GL.MatrixMode(MatrixMode.Modelview) ' Select The Modelview Matrix GL.LoadIdentity() ' Reset The Modelview Matrix End Sub Private Sub CreateFontTexture(ByRef textureid As Integer) 'Dim textureid As Integer Dim bmp As Bitmap 'Dim gfx As Graphics Dim data As System.Drawing.Imaging.BitmapData Dim res() As String = GetType(Form1).Assembly.GetManifestResourceNames() Call GL.GenTextures(1, textureid) Call GL.BindTexture(TextureTarget.Texture2D, textureid) 'Call GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero) Call GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureMinFilter.Linear) Call GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureMagFilter.Linear) 'Get the bitmap resource into this picture box control 'The picture control has been made non-visible using its the IDE 'PictureBox1.Image = New System.Drawing.Bitmap(GetType(Form1).Assembly.GetManifestResourceStream(res(2))) bmp = New System.Drawing.Bitmap(GetType(Form1).Assembly.GetManifestResourceStream(res(1))) 'PictureBox1.Image. 'bmp = New Bitmap(width, height) 'bmp. 'gfx = Graphics.FromImage(bmp) ' Use gfx.DrawString() to print the characters you need 'Upload bmp into the OpenGL texture data = bmp.LockBits( _ New System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), _ System.Drawing.Imaging.ImageLockMode.ReadOnly, _ System.Drawing.Imaging.PixelFormat.Format32bppArgb) 'GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, bmp.Width, bmp.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0) GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0) Call bmp.UnlockBits(data) End Sub End Class


Comments
Re: VB.NET and interleaving problem
Vertex arrays will not work correctly in .Net, unless you pin the arrays. Don't do that: use vertex buffer objects instead!
Re: VB.NET and interleaving problem
I can't because I have to use GL 1.1
Re: VB.NET and interleaving problem
In that case, either pin the arrays after you create them:
or, if the data is immutable, use display lists which don't suffer from this issue.
Re: VB.NET and interleaving problem
What exactly is "pinned". Does the array move around because of some memory allocator?
Also, I am declaring the array on the stack. I don't see why the array's location would change between a call from
glVertexPointer and glDrawElements. It could even cause a crash.
Re: VB.NET and interleaving problem
Managed arrays are always allocated on the heap in .Net.
The .Net GC is a compacting garbage collector, which means it will move memory around to improve performance. This is perfectly fine in pure .Net programs, where the collector knows precisely where each piece of memory lies and ensures that all memory references are valid.
Once you pass a managed piece of memory to unmanaged code, however, these guarantees go out the window. This can cause crashes if you are not careful, which is why Vertex Arrays are generally not recommended (VBOs and display lists do not suffer from this issue). The solution is to either (a) pin the memory yourself for as long as the unmanaged code will be using it or (b) allocate unmanaged memory via
Marshal.AllocHGlobal()and store your arrays there (the second solution is rather annoying to use, since you have to use Marshal.Read/Write*() methods to access those arrays).Re: VB.NET and interleaving problem
Ok, so I tried 1 VBO and 1 IBO and it still is not rendering.
Re: VB.NET and interleaving problem
You are not specifying texcoord and color offsets for the VBO code.
Check the "VBO Static" sample in the OpenTK Example Browser.
Re: VB.NET and interleaving problem
You are right, I was uploading pVertex
I changed
Call GL.BufferData(BufferTarget.ArrayBuffer, q * 4, pVertex, BufferUsageHint.StaticDraw)
to
Call GL.BufferData(BufferTarget.ArrayBuffer, 12 * 4, pvv, BufferUsageHint.StaticDraw)
and also
Call GL.VertexPointer(3, VertexPointerType.Float, 12, New IntPtr(0))
Call GL.DrawElements(BeginMode.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero)
I'm not using texcoord or color.
Still not getting any triangles and glGetError() returns 0.
Re: VB.NET and interleaving problem
I use GLIntercept to see what is happening.
**** Never mind, there is some sort of problem with GLIntercept
Re: VB.NET and interleaving problem
Try gDEBugger. They offer a free download now and it generally works better than glIntercept.