ppu.spu's picture

Problem in using glDrawArrays() and glTexImage2D() under C# wrapper.

Hi All,
I am developing a CSharp wrapper over OpenGL ES 1.1, Everything works fine but I am stuck at an API NativeMethods.glTexImage2D(NativeConstants.GL_TEXTURE_2D, 0, NativeConstants.GL_RGBA, g_i32TexSize, g_i32TexSize, 0, NativeConstants.GL_RGBA, NativeConstants.GL_UNSIGNED_BYTE, intPtr);
While using the API I am getting run time error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." at NativeMethods.glDrawArrays(NativeConstants.GL_TRIANGLES, 0, 3);
The last parameter of NativeMethods.glTexImage2D() intPtr points to the array storing the Texture values. When I change the second last parameter to NativeConstants.GL_BYTE then I get the geometry rendred without the texture.what i get The Expected output(from the actual C++ sample) is thisExpected output
Below is the siganture of the function.

    /// Return Type: void
    ///target: unsigned int
    ///level: int
    ///internalformat: int
    ///width: int
    ///height: int
    ///border: int
    ///format: unsigned int
    ///type: unsigned int
    ///pixels: void*
    [System.Runtime.InteropServices.DllImportAttribute("libgles_cm", EntryPoint="glTexImage2D")]
public static extern  void glTexImage2D(uint target, int level, int internalformat, int width, int height, int border, uint format, uint type, System.IntPtr pixels) ;

I have struggled a lot and cannot find how to overcome this issue.
Thanks.

Inline Images
Expected output
with NativeConstants.GL_BYTE
Final Textured triangle using Lighting as well

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

The error message indicates that OpenGL is trying to read data outside the bounds of the array. Can you provide an example of how you are using glTexImage2d or glDrawArrays? (Including the data structures you are passing).

It could also indicate that the GC has moved the array and the pointer is no longer valid. (To take a pointer to a .Net object, you need to pin the object with a GCHandle and call AddrOfPinnedObject() - that's the IntPtr you need to pass. Do note that this should only be done on "blittable" types, otherwise strange things will happen. (OpenTK has a class called BlittableValueType that can be used to check whether is blittable).

Take a look at the ES 1.1 wrapper in OpenTK (the source can be browsed online - or just download the library). In ES.cs, line 8135 you'll see how glTexImage2d is handled. (The code is under the MIT/X11 license so you can use it / hack it / integrate it into your project without issue).

OpenTK also comes with a binding generator that you could use or hack to meet your requirements. It takes the C headers for ES and spits out a C# wrapper (let me know if you need usage instructions, it may not be very intuitive to use).

ppu.spu's picture

C++ code :

  // Creates the data as a 32bits integer array (8bits per component)	
unsigned int* pTexData = new unsigned int[g_i32TexSize*g_i32TexSize];
	for(int i = 0; i < g_i32TexSize; ++i)
	{
		for(int j = 0; j < g_i32TexSize; ++j)
		{
			// Fills the data with a fancy pattern
			unsigned int col = (255<<24) + ((255-j*2)<<16) + ((255-i)<<8) + (255-i*2);
 
			if( ((i*j)/8) % 2 == 1 )
				col = 0xffff00ff;
 
			pTexData[j*g_i32TexSize+i] = col;
		}
	}
   //using the data
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_i32TexSize, g_i32TexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData);

My C# Implementations

           // Creates the data as a 32bits integer array (8bits per component)
            UInt32[] pTexData = new UInt32[g_i32TexSize * g_i32TexSize];
            for (int i = 0; i < g_i32TexSize; ++i)
            {
                for (int j = 0; j < g_i32TexSize; ++j)
                {
                    // Fills the data with a fancy pattern
                    UInt32 col = (UInt32)((255 << 24) + ((255 - j * 2) << 16) + ((255 - i) << 8) + (255 - i * 2));
                    if (((i * j) / 8) % 2 == 0)
                        col = 0xffff00ff;
                    pTexData[j * g_i32TexSize + i] = col;
                }
            }
 
                int size = sizeof(UInt32) * pTexData.Length;
                IntPtr ptr = Marshal.AllocHGlobal(size);
                Marshal.Copy((int[])(object)pTexData, 0, ptr, pTexData.Length);
                //Hexvalue of #define GL_UNSIGNED_BYTE                  0x1401 : DECIMAL ->5121
                NativeMethods.glTexImage2D(NativeConstants.GL_TEXTURE_2D, 0, NativeConstants.GL_RGBA, g_i32TexSize, g_i32TexSize, 0, NativeConstants.GL_RGBA, NativeConstants.GL_UNSIGNED_BYTE, ptr);

I have the entire VS 2008 project ready but do not know how to send it to you.

ppu.spu's picture
the Fiddler wrote:

OpenTK also comes with a binding generator that you could use or hack to meet your requirements. It takes the C headers for ES and spits out a C# wrapper (let me know if you need usage instructions, it may not be very intuitive to use).

Kindly, provide the instructions for the binding generator ....( Hope you have read my previous reply )
Thanks.

ppu.spu's picture

Got some improvement, the actual problem was never in the marshaling but in the VBO operations. Still I have some issues but the code is running with the texture over it. The current issue is in porting the following C++ code to C#,
glTexCoordPointer(2,GL_FLOAT,sizeof(float)*5, (void*)(sizeof(float) * 3));
When I do this,
IntPtr tx = Marshal.AllocHGlobal(sizeof(int));
Marshal.WriteInt32(tx, sizeof(float) * 3);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5, tx);

the application shoots error.But, when I use
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5,IntPtr.Zero);
then the C# app runs similar to C++ code with similar last param i.e.
glTexCoordPointer(2,GL_FLOAT,sizeof(float)*5, 0);
The error lies in passing C# equivalent of (void*)(sizeof(float) * 3) in the final parameter (as IntPtr) of glTexCoordPointer(). Kindly Help...

ppu.spu's picture

Finally Overcame all the problems and rendered the triangle successfully.Thanks a ton for your humble support.
Successful output.