Sign in to follow this  
n4gix

Open GL

Recommended Posts

Hi there,I am a professional 3D programmer, but new to the flight simulation scene. At the moment, I am learning how to create vector gauges and have a question for experienced FS programmers:I want to create the vector gauges (only 2D) in OpenGL and display them on the given hdc by the STATIC_ELEMENT; or directly to the graphics card. This should be no problem, but I wonder if this will cause a very bad performance or any other problems. Shall I better use GDI+? Does Open GL offer any advantages to GDI+ (exept 3D capability)? What experiences did you make? Does it worth working more on this issue?Kind RegardsFrank

Share this post


Link to post
Share on other sites
Help AVSIM continue to serve you!
Please donate today!

I made a foray with this recently, not with OpenGL but with DirectX. While I was very successful in drawing things in DirectX and obtaining a surface to draw on, etc, I got into a significant issue:The FS rendering engine is oblivious to your changes, and will overwrite things at it sees fit. The best I was able to get to was an incredible flickering effect as the the battle for the window control took place. No crashes though, just no cooperation, and it has to do with how the other windows are rendered I'm pretty sure.Things would be a lot better if DirectX allowed you more than one window in full screen mode (one device) but that doesn't appear to be the case right now. Not sure about OpenGL.GDI+, while not stellar in performance, is probably the simpler way to go because it is clear from the callbacks allowed in the SDK that the design team never intended for DirectX (or OpenGL) calls directly into the FS window space (multiple windows = different story, but most people run in full screen mode). The only thing that appears legal at this time in the SDK, and itself not without its challenges is that IMAGE_CREATE_DIB flag. Stray away and be prepared for some very strange behavior.Even with GDI+, FS will tend to decide when and how to render the bitmap you've created on the device context, which causes all kinds of problems of its own. Simple things like panel shading at night become a significant ordeal to plow through. IMAGE_NO_TRANSLATION is a good companion flag to IMAGE_CREATE_DIB.So until the SDK allows you to tell FS not to play with the contents of your own windows, I'm not sure a good solution will exist. GDI+ can be slow and hits the frame rate pretty heftily.I am hoping that this will be addressed with FS10, because it would be nice to have access to the speed of DirectX or OpenGL.

Share this post


Link to post
Share on other sites

Hi Frank,I was delving into the same problem, but have to spend my time somewhere else at the moment. However, I'm still interested in persuing this.I'm not too sure about the answers to your questions either. Have you succeeded using OpenGL yet?Some advantages I can think of (GDI+ cannot do either of these):full alpha blending (for transparency, shadows, highlights, etc)GDI+ cannot use alpha blending as far as I know, as the GDI colour space doesn't support alpha values (or RGBA to be precise, I may be proven wrong though).multitexturing GDI+ renders bitmap after bitmap. Mostly, you need to whack several bitmaps together, so doing this in one pass would be great.shadersYou can write some fancy shaders for bumpmapping, etc...What I have found so far:The way to implement this is to grab the hdc of the STATIC_ELEMENT and render to that. I haven't succeeded in doing this yet (I'm trying bitmaps). It seems that the hdc supports a DIBSECTION, but ChoosePixelFormat fails on me. I may have to create a new HDC with PFD_SUPPORT_GDI and then copy. One thing I have heard though is that drawing to DIBSECTION using PFD_SUPPORT_GDI doesn't support the hardware features on the card, which would be a bummer. In that case, one would need to write to graphics card memory (have to find out how to do that still) and then copy into the DIBSECTION.Any thoughts?If you get the basics set up (ChoosePixelFormat, SetPixelFormat, wglCreateContext) you're ahead of me.Cheers, Christianmy (relevant) code so far:void FSAPI m803_callback ( PGAUGEHDR pgauge, SINT32 service_id, UINT32 extra_data ){ PELEMENT_STATIC_IMAGE pelement = (PELEMENT_STATIC_IMAGE)(pgauge->elements_list[0]->next_element[0]); HGLRC hrc ; switch (service_id) { case PANEL_SERVICE_PRE_INSTALL: { HDC hdc = pelement->hdc; PIXELFORMATDESCRIPTOR pfd ; int pixel_format; int res; memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)) ; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1 ; pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 32; pfd.iLayerType = PFD_MAIN_PLANE ; // THIS FAILS!!! pixel_format = ChoosePixelFormat(hdc, &pfd); res = SetPixelFormat(hdc, pixel_format, &pfd); hrc = wglCreateContext(hdc); } break; }}MAKE_STATIC( m803_line, BMP_CLOCK_LINE, NULL, NULL, IMAGE_USE_ERASE | IMAGE_CREATE_DIBSECTION, 0, 11, 55)PELEMENT_HEADER m803_line_list[] ={ &m803_line.header, NULL};

Share this post


Link to post
Share on other sites

This is a very interesting discussion. I just have a little question:What is the meaning of the IMAGE_NO_TRANSLATION flag?I couldn't find any help in the SDK...Thanks.Eric

Share this post


Link to post
Share on other sites

quick update on my opengl research.It's not a good idea to enable GDI rendering in OpenGL as this is indeed mostly software accelerated.The way to apparently do this is to render to a pbuffer and use glcopyteximage. There are several ways using a pbuffer, but i'm not quite sure yet if this will work ok. To take advantage of alpha values the texture will need to be copied from RGBA to RGB (GDI doesn't know alpha values), which is potentially slow. Also, pbuffers use extra video memory, but at 256x256x4 per texture this may not be significant.For DX people, there may also be a pixel buffer to use to do something similar...Christian

Share this post


Link to post
Share on other sites

If you want to copy directly, the bitmaps are directly available to copy to. This was the GDI drawing the "old" way, without the "DIB" section enabled. I can check my old sources if you are interested.Arne Bartels

Share this post


Link to post
Share on other sites

Do you mean you can have access to the bitmap wihtout have to create a DIB section?I am HIGHLY interested !! Please let me know how you do this...Thanks.Eric

Share this post


Link to post
Share on other sites

>Some advantages I can think of (GDI+ cannot do either of>these):>>full alpha blending (for transparency, shadows, highlights,>etc)>GDI+ cannot use alpha blending as far as I know, as the GDI>colour space doesn't support alpha values (or RGBA to be>precise, I may be proven wrong though).Er, certainly GDI+ supports ARGB in the "Color" structure...// Create color object from ARGBColor redColor = Color.FromArgb(120, 255, 0, 0);This will create a translucent pure red Color object... :)The Color structure represents ARGB colors in GDI+. This class has a static member property for almost every possible color. For example, Color.Black and Color.Red represents the colors black and red, respectively. Besides these static properties, this structure includes read-only properties - A, R, G and B - that represent the alpha, red, green and blue components respectively.The Color structure also provides some methods. The FromArgb method creates a color from the four ARGB components. This method has different overloaded forms with which an application can create a Color object from an alpha value only; from an alpha value with a Color object only; from three values (red, green, and blue); and from all four values (A, R, G, & :(.*Note: The above is from "Graphics Programming with GDI+" which is part of the Microsoft .Net Development Series by Mahesh Chand. It's an invaluable resource and I highly recommend it! :)

Share this post


Link to post
Share on other sites

There is at least one IMAGE_SET for each element which contains the bitmap data, at least it was the last time I tried it (FS2000), also the STRING element doesn't have it.Assume a ELEMENT_STATIC *pelement (NOTE: the dynamic version, NOT the defined, named element you know the drill).PIMAGE pimg=pelement->image_data.final;pimg->image is the bitmap buffer pimg->len is the byte countpimg->format is the image format usually IMG_15_BIT I never needed more than this, since I made 1-1 copies, no GDI drawing. There are some further params in PIMAGE you might need, have a look.For the "old" GDI programming you still needed a DIB, to draw to and then copy from DIB to pimg->image somehow (memory not the best here). In terms of frame rates it was not a good solution. Bit per bit copying and then a forcibly redraw is definetely a frame rate eater, but it is possible, yes. After copying you have to force the redrawing I think.Arne Bartels

Share this post


Link to post
Share on other sites

Thanks for the education :) I must have not read this correctly in the MS docs.I'd like to confirm though if this indeed enabled alpha blending (ie can I mix two textures)? As far as I remember, the MS docs were saying that this isn't supported in GDI+ (eg something about drawing in the RGBA colour space doesn't work, hence DBI bitmaps don't have an alpha value).What I'm trying to get at: GDI+ can read alpha values, but can it actually use them for drawing?Then again, maybe I need to read the docs more carefully.Cheers, Christian

Share this post


Link to post
Share on other sites

Hi Arno,just trying to get my head around what you're saying.I was planning on doing something like this:1) draw image(s) into OpenGL pbuffer (do fancy texture blending, etc).2) create new bitmap data (in memory)3) use glCopyTexImage2D() to copy from pbuffer to new bitmap (this should be fast)4) draw new bitmap with GDI+Are you saying that I actually don't have to draw the bitmap, but something like:pelement->image_data.final->image = &(new bitmap);is all that needs to be done? (if by reference works, doing a memcpy would be way too slow).I know you can access both HDC and image seperatly, but have to look into the details again...Theoretically, one can even configure the pbuffer for staight texture use (copy to main memory is eliminated), but I doubt this will work, as that'll be OpenGL specific textures (and we're breaking out of the opengl render pipeline here).Cheers,Christian

Share this post


Link to post
Share on other sites

I'm pretty sure you can't redirect the image pointer, or only with great care, including restoring the original pointer just before destruction. You have to us memcpy or similar. In my experience the actual redrawing of the new bitmap has the deepest impact on frames. An intelligent use of SET_OFF_SCREEN or REDRAW_IMAGE can rise the frames significantly.Arne Bartels

Share this post


Link to post
Share on other sites

>Thanks for the education :) I must have not read this>correctly in the MS docs.>>I'd like to confirm though if this indeed enabled alpha>blending (ie can I mix two textures)? As far as I remember,>the MS docs were saying that this isn't supported in GDI+ (eg>something about drawing in the RGBA colour space doesn't work,>hence DBI bitmaps don't have an alpha value).>>What I'm trying to get at: GDI+ can read alpha values, but can>it actually use them for drawing?>>Then again, maybe I need to read the docs more carefully.Actually, I'd suggest you invest ~$55 in the book I cited... :) It's a worthwhile investment, particularly if you intend to stick with GDI+...Brushes, Pens, and Alpha Blending (From page 460, Advanced 2D Graphics)The process of alpha blending involves three simple steps. First, an application creates a color with transparency (the alpha component). The following line creates a Color object with alpha component value 40:Color clr = Color.FromArgb(40, 255, 255, 255);The second step is to create a brush or pen using that color. The following lines create a transparent pen and a brush:Pen transPen = new Pen(clr, 10);SolidBrush semiTransBrush = new SolidBrush(clr);Finally, the application uses the transparent brush or pen to fill and draw graphics shapes, lines, and curves. The following code uses the Pen and Brush objects created in the previous steps to draw a line and to draw and fill a rectangle:g.DrawLine(transPen, 10, 30, 200, 30);g.FillRectangle(semiTransBrush, rect);======================================Now, I freely confess that I'm still a complete Noob with regards to translating the above into an actual gauge application, but I present the information in the hope that it will help someone else... I'll eventually get to this point myself, someday! :)

Share this post


Link to post
Share on other sites

As a followup to the question of Alpha Blending, it appears that the current DIB Structure does NOT support this:Bit FormatsThe header defines the format of the bits, but all formats share the following rules: Every scanline is DWORD-aligned. The scanline is buffered to alignment; the buffering is not necessarily 0. The scanlines are stored upside down, with the first scan (scan 0) in memory being the bottommost scan in the image. This is another artifact of Presentation Manager compatibility. GDI automatically inverts the image during the Set and Get operations. 64K segment boundaries are not respected; scanlines can cross such boundaries (unlike the device-dependent bitmap format that is buffered to 64K boundaries). Each format has the following specifics: 1-bit DIBs are stored using each bit as an index into the color table. The most significant bit is the leftmost pixel. 4-bit DIBs are stored with each 4 bits representing an index into the color table. The most significant nibble is the leftmost pixel. 8-bit DIBs are the easiest to store because each byte is an index. 24-bit DIBs have every 3 bytes representing a color, using the same ordering as the color table. This format is especially tricky during processing because a 64K boundary can exist in the middle of a color triple

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this