PDA

View Full Version : GDI+ to OpenGL



appdeveloper
10-09-2009, 02:25 AM
I have the crazy task of changing all code made in GDI+, for several years to OpenGL in 3 weeks, but i don't know how to easily do that. All code is made in visual basic 2005 and i'm trying to use the taoframework, to quicly change the code, but for what i can see the taoframework is not very well supported for quick doubts. The GDI+ graphics are being drawn on a picturebox control. I've only used OpenGL on "C" and console mode. This is an MDI project made under Visual Basic 2005. Can anyone give me an hint on how to implement OpenGL on an MDI form in visual basic?

My thanks in advanced

ZbuffeR
10-09-2009, 02:56 AM
I would not like to be in your postion :)
This link seem interesting with samples, did you read/used it ?
http://nio.astronomy.cz/vb/opengl.html

appdeveloper
10-09-2009, 04:33 AM
First of all, thank you for your answer.
The site you've mentioned was the site where i discovered the
http://www.taoframework.com/
unfortunatly i can't get the taoframework to work with textures. That's the reason for my previous post

ZbuffeR
10-09-2009, 05:22 AM
Well you should be more specific then.
Can you try this ?
http://www.opentk.com/

appdeveloper
10-09-2009, 06:55 AM
Thanks a lot for your help ZbuffeR. Have you ever been in those situations that you look at something several times and the answer is right there, in front of your eyes? I've already seen the links you've been referencing, for several times, but after looking at them again i found the problem. Couldn't find the solution without you!!!

the problem lies here, in those two lines:
Dim m_data As BitmapData = mBitmap.LockBits(New Rectangle(0, 0, mBitmap.Width, mBitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb)

Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, mBitmap.Width, mBitmap.Height, 0, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, m_data.Scan0)


After following your links i've tried to change the image being referenced, to the one on the example of NeHe lesson8, and it works. So i found that the problem had to do with the image being referenced. So i changed those lines to:

Dim m_data As BitmapData = mBitmap.LockBits(New Rectangle(0, 0, 128, 128), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb)

Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, 128, 128, 0, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, m_data.Scan0)

Notice that on the picture height and width i've changed to 128, such as NeHe image.
Now my actual problem lies on resizing the image so that all the image is seen on the polygon, not just part of the image (128/128). Do you know how?
I've been trying values above 128 and it doesn't work

appdeveloper
10-09-2009, 08:28 AM
once again, the answer is on NeHe web site:
"the image dimensions are a power of 2. Remember that in order to use an image as a texture the image needs to be 128x128, 256x256, etc. Under the image menu, select image size, uncheck the constraint proportions checkbox, and resize the image to a valid texture size. If your image is 100X90, it's better to make the image 128x128 than 64x64"

appdeveloper
10-09-2009, 08:46 AM
Although a problem persists.
If my image is 1360 height and 2045 width and when i try to set the size used by glTexImage2D to 2048 in order see the image "as is", not loosing resolution, i get an error message saying:
"AccessViolationException was unhandled",...
"Tried to read or write on protected memory,..."
If i try a minor size, like for instance 1024, the image is not clear of what it is. You can just understand an image is there but not understand what's it like

dletozeun
10-09-2009, 10:42 AM
Although a problem persists.
If my image is 1360 height and 2045 width and when i try to set the size used by glTexImage2D to 2048 in order see the image "as is", not loosing resolution, i get an error message saying:
"AccessViolationException was unhandled",...
"Tried to read or write on protected memory,..."
If i try a minor size, like for instance 1024, the image is not clear of what it is. You can just understand an image is there but not understand what's it like

Your hardware does not support NPOT (Non Power Of Two) textures natively. But it may support ARB_texture_rectangle (http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt) which allow you to load NPOT texture using the GL_TEXTURE_RECTANGLE_ARB target in glTexImage2D.

If it does not, the only solution is to resize your texture to a POT one. glTexImage2D won't do it for you and it can't because it does not know the initial texture size.

So when you try to load a 1360x2045 texture as 2048x2048 with glTexImage, the driver expects that picture data contains 2048*2048 pixels. This will lead inevitably to a memory access violation.
And if you tell that it is a 1024x1024 image. The driver will read each picture row consecutively with row size equal to 1024 pixels. So the 1st row will be correct, but the second will correspond to a part of the first and a part of the second and so on.

The only thing you can do is save the picture on the hard disk with POT dimensions and then use special texture coordinates to map the picture exclusively.

appdeveloper
10-09-2009, 03:18 PM
do you know any way for me to load an image and save it with the desired dimentions?

James W. Walker
10-09-2009, 04:11 PM
Perhaps the function gluScaleImage would help.

dletozeun
10-10-2009, 02:15 AM
You can also take a look at DevIL (http://openil.sourceforge.net). This library is very useful to load almost any picture format and I think that there are some scaling functions.

Stephen A
10-11-2009, 02:33 PM
do you know any way for me to load an image and save it with the desired dimentions?

Simple: use GDI+!

Load your first image into a Bitmap object. Create a second Bitmap object of the desired size (e.g. 2048x2048). Finally, create a Graphics object from the first Bitmap (use Graphics.FromImage()) and call DrawImage() to copy the image into the second Bitmap. Done!

There are a few options you can set in the Graphics class to improve quality (and decrease speed). Moreover, don't forget to call Dispose() on the Graphics and Bitmap objects once you are done with them!

I wouldn't recommend using DevIL from C# (you should minimize unmanaged dependencies if at all possible). GDI+ is simpler to use and comes installed by default - much better! The only thing you lose is DDS support, but that is simple to solve (I am working on a DDS loader that will be usable by both OpenTK and the Tao Framework).

IovPizza
10-14-2009, 10:45 AM
Hi,

A moth ago I ported an app from GDI+ to OpenGL. It was very rewarding because drawing 500000 lines/textures/text characters now takes less than one second in a HD4650, while it took minutes in GDI+. It took me two weeks.

I started in http://www.colinfahey.com/opengl/csharp.htm, there i found a OpenGL wrapper that made my life easy. Also I recomend to use Tao to learn how to load textures into video memory.

To get the exact coordinate space than in GDI+ I recomend to use GL.glOrtho(0, width, height, 0, -1, 1);

Good luck.

appdeveloper
10-15-2009, 03:56 AM
IovPizza, did you ever changed a GDI+ project to use OpenGL, using TAO and SimpleOpenGLControl? I would like to know if even drawing OpenGL on a Windows Control is faster than drawing GDI+ on a picturebox. That's the big reason why i'm changing my project from GDI+ to OpenGL using the TAO SimpleOpenGLControl

IovPizza
10-15-2009, 04:03 AM
appDeveloper, you can download an example project containing a basic multilayered GDI OpenGL wrapper without support for textures and text (i cannot release theese features publicly). It can draw lines and polygons. It can be a good starting point for your proyect.

Source code is made in C# and Visual Studio 2008 and can be downloaded from:
http://www.filefactory.com/file/a0hf87h/n/MSB_zip

With this program you can select the mode you want to render GDI or OpenGL.