• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

Need help from an OpenGL expert !

Started by Chris Boss, June 23, 2010, 02:54:12 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Chris Boss

I am having a problem with the glDrawPixels command.

It works fine when I use GL_RGBA (I have to swap the R and B bytes in a BGRA DIB first).

It is slow though and I have read that the GL_BGRA (or GL_BGR) extension works faster.

I called OpenGL  to see if the GL_EXT_bgra extension exists and it does, so GL_BGRA, GL_BGR should both work with glDrawPixels, but they don't
(screen is black).

I tested for an error message and I get an Invalid Enum (either format or type parameter is bad).

Now I examined some source code for GLUT (have the OpenGL SuperBible book 2nd edition plus CD) and it used GL_BGR and it works, but it didn't call SetPixelForm with PDF_TYPE_RGBA, but instead uses PFD_TYPE_COLORINDEX instead.

Does the GL_EXT_bgra only work with PFD_TYPE_COLORINDEX ?

I have searched the web and have nothing that would give me a clue to the cause of the problem.

Could there be some state set that prevents OpenGL from being able to use GL_BGRA ?

Other than this, I am doing well in grasping OpenGL. A lot by trial and error though, since I find most documentation quite terse (worse than MS API docs).
The OpenGL SuperBible book has been a great help. Came across it in a GoodWill store (second hand store) for only 25 cents.


Chris Boss

#1
I should also note that I am not using Jose' include files.

I am writing my own from scratch. I use the MS API docs for the format for subs/functions to help me define the declares and use opengl.org for all the specs on constants and extensions. I can compile Gary Beenes examples with no problem.

The constants for the extensions I am tyring to use are:

%GL_BGR                         = &H80E0
%GL_BGRA                        = &H80E1
%GL_ABGR                        = &H8000

One of the reasons I am trying to use the other extensions is to find a way to speed up drawing a bitmap background in an OpenGL window.

I am writing a hybrid graphic control which is a superclass of my existing Canvas control.
I want to be able to update the background with the Canvas current background bitmap every animation cycle (I will then draw OpenGL stuff on top).

On my XP Home PC (2.5 ghz, nvidia gforce4 MX 4000 video) gets about 20 frames/second while my 64 bit Windows 7 Dell PC (2.2 ghz) only gets about 11 fps.




José Roca

Quote
The constants for the extensions I am tyring to use are:

%GL_BGR                         = &H80E0
%GL_BGRA                        = &H80E1
%GL_ABGR                        = &H8000

Don't know if it will make a difference, because I don't know if you have declared the parameters as LONG or DWORD, but these constants are missing the DWORD specifier (without it, they become negative INTEGERs):


%GL_BGR                         = &H80E0???
%GL_BGRA                        = &H80E1???
%GL_ABGR                        = &H8000???


Chris Boss

#3
Thank you, thank you, thank you!

Why I forgot that I don't know.

I changed it to:


%GL_BGR                         = &H000080E0
%GL_BGRA                        = &H000080E1
%GL_ABGR                        = &H00008000


I like the extra zeros rather than the three question marks.

As far as the SUB/FUNCTION declares, I use the following table for converting the GL variable types to PB types:


' GLboolean     is BYTE (character)
' GLbyte        is BYTE (character)
' GLubyte       is BYTE (character)
' GLenum        is DWORD
' GLbitfield    is DWORD
' GLuint        is DWORD
' GLint         is LONG
' GLsizei       is LONG
' GLshort       is INTEGER
' GLushort      is WORD
' GLfloat       is SINGLE
' GLclampf      is SINGLE
' GLdouble      is DOUBLE
' GLclampd      is DOUBLE


Now all the extensions work with glDrawPixels.

Now on my XP machine, all the different formats (RGBA , BGRA, ABGR) all work at the exact same speed.

Do you think some machines will have an improved speed with any one of those formats ?

The OpenGL SuperBible says BGR works faster (tried that), but no difference on my XP machine.

Is there any way to speed up the copying of a Bitmap to an OpenGL buffer ?

I am copying a 640 x 448 pixel DIB section to an OpenGL BACK buffer.
I get about 20 frames per second on my XP Home PC.

My Dell gets even worse (about 11 fps)

-  32 bit XP Home PC (2.5 ghz, nvidia gforce4 MX 4000 video) gets about 20 frames/second
-  64 bit Windows 7 Dell PC (2.2 ghz with onboard video) only gets about 11 frames/second






Chris Boss

If I have to I can live with the slow draw speed, since the control won't always have to update a background bitmap.

It would be nice to have it faster though.

The control is a Hybrid control.

It is a superclass of EZGUI's Canvas control so it automatically gets all its features including 2D sprites.

The canvas control can animate the same animation ( 140 x 140 pixel sprites) at about 150 frames/second so when fast speed is needed it can be used.

What is nice about the OpenGL Hybrid control is that it can do the double buffer so it is in sync with the vertical retrace, it can do some really fancy on the fly effects on the image, such as scale it and brighten/darken it. The next step is to add OpenGl 3D object drawing on top. That should be fast.


Petr Schreiber

Chris,

I am not an expert, but it is maybe better to use texture mapped polygon with alpha (for irregular shape) to get better rendering performance.
The fastest texture format should be BGRA with 8 bits per each component, but OpenGL implementations convert to suitable format anyway.

Create one texture buffer on the beginning, and then just update it, not recreate. There will be always performance hit when combining the Windows 2D graphics with OpenGL, as there is some bus traffic involved. On PCI-E boards it is usually faster.

Quote
...What is nice about the OpenGL Hybrid control is that it can do the double buffer so it is in sync with the vertical retrace...
Chris, one thing - I said it in the PB post, but maybe you overlooked it. OpenGL double buffer does not automatically mean "in sync with vertical retrace". You have to enable V-sync explicitly using OpenGL extension.


Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

#6
Chris

What you are trying to do, is what i am doing since the first release of GDImage 5.00+.

From my own experience, you will never be able to get the same speed writing to a private DC, than using direct OpenGL RC.

And, because you are doing most of your development on XP, you will probably encounter extra problems running it in composited mode on a DWM DirectDraw surface. I learned this the hard way when VISTA was first released, breaking most of the work i have done in ZAP Image Solution (and WinLIFT) for graphic, audio, and video.

Since that time, i am always using a recent computer with the latest OS, and i force myself to learn what has changed in the Windows SDK API (currently v7.0) to conform my code to the latest specifications.

Creation of advanced graphic library is very dependant on the underlaying OS, because Windows itself is a graphic engine!

Anyway, as i said already several times, you will never need a FPS higher than 60, because this is the refresh rate of DWM itself and you can't bypass it.
In composited mode (understand AERO mode) everything on the screen is redrawn 60 times per second onto the DirectDraw surface, even OpenGL !

...

 
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Chris Boss

This hybrid control will be used in multiple ways:

(1) The Canvas (GDI) buffer is copied to the OpenGL buffer every cycle (slowest - 20 fps and lower)
This allows the user to integrate the 2D drawing (including my sprite engine) with 3D draw (objects) on top.

(2) The Canvas (GDI) will be copied to a texture and then usable, say on a 3D object. This would be done periodically, only when a change needs to be made, rather than every cycle. Most of the animation will be 3D.

(3) The Canvas won't be used at all and the background will be a solid color drawn on OpenGL buffer. Primary use of the control will be 3D animation.

The control will define the OpenGL buffer drawing on one of three ways (user choice when control created):

(1) Double Buffer OpenGL (RC)  (GDI not allowed, other than Canvas copy which is not a GDI call)
(2) Front Buffer OpenGL (RC)   (GDI not allowed, other than Canvas copy which is not a GDI call)
(3) Front Buffer OpenGL (RC), but allowing GDI drawing onto DC as well

My customers want OpenGL features in EZGUI 5.0 and this hybrid control should offer a number of them.

The control will draw in 4 steps:

(1) If enabled, Canvas image will be copied to current OpenGL buffer (front or back)
(2) a callback can be generated where user can call OpenGL commands directly
(3) a 3D Object macro engine will draw predefined (by user) 3D objects
(4) a callback can be generated where user can call OpenGL commands directly

Most users will not use the callbacks, but they will be there so they can integrate pure opengl code themselves if desired.

This control is also the first of a new type of controls in EZGUI based on EZGUI 5.0's new superclass engine.

The new superclass engine allows me to use an existing control class as the basis for a new class. The EZGUI engine will automatically
recognize the new superclass as if it were the original class and all features (in EZGUI) available to the first class will be available to the superclass.

Superclass instance storage is provided and all the calls necessary to make the superclass work.

To create a superclass of say my Canvas control is as easy as:



SUB RegisterOpenGLClass()
    ' class Macro @CVS forces Canvas class to use the %CS_OWNDC class style required by OpenGL
    ' I can use an actual class name as well
    EZ_SuperClass "MYNEWCLASSNAME", "@CVS", CODEPTR(MyGLClassWndProc)
END SUB


' ------------------------------------
'  Property Index List:
' ------------------------------------
' 1 -
' 2 -
' etc up to 50 properties

FUNCTION MyClassWndProc(BYVAL hWnd   AS LONG, _
                 BYVAL Msg    AS LONG, _
                 BYVAL wParam AS LONG, _
                 BYVAL lParam AS LONG) EXPORT AS LONG

    STATIC OrigAddress AS DWORD
    SELECT CASE Msg
        CASE %WM_CREATE
            IF hWnd=0 THEN
                ' window does not exist yet so hWnd=0
                ' this is sent only once when superclass is create
                ' and before any windows are created
                OrigAddress=EZ_GetSuperAddress
                FUNCTION=1
                EXIT FUNCTION
            END IF
            FUNCTION=EZ_CallSuperProc(OrigAddress, hWnd, Msg, wParam, lParam)
            EZ_InitSuperClassProps hWnd  ' all 50 properties are set to zero
            ' EZ_SetSuperClassProp and EZ_GetSuperClassProp are used to set and get properties
            EXIT FUNCTION
        CASE %WM_DESTROY
            EZ_FreeSuperClassProps hWnd
        CASE ELSE
    END SELECT
    FUNCTION=EZ_CallSuperProc(OrigAddress, hWnd, Msg, wParam, lParam)

END FUNCTION




Chris Boss

Patrice,

I am not drawing to a DC!

I am copying a DIBsection (Canvas stores its own background image in a DIB) to an OpenGL buffer (RC) and then calling swap buffers.

No drawing is normally done to a DC (unless user selected that mode, which will likely be the least used feature).

Development is being done on Windows XP Home, but will be testing on Windows Vista home basic and 64 bit Windows 7.

The openGL will support earlier OpenGL standards such as versions 1.2 to 1.5 in harmony with my purpose of making software usable on as many OS as possible.

It may even be able to run on OpenGL 1.0 on Windows 95, but I don't know yet which will be the lowest denominator.

For example, I have working code using glDrawPixels which just uses the standard RGBA format with DIB's. I just run through the DIB and swap the R and B bytes and then use RGBA drawing. The time spent doing this is negliable compared to the slow speed of glDrawPixels. I am testing for extensions (BGRA, ABGRA) and providing alternate ways to support glDrawPixels with DIBs using them, but I don't see any speed improvement (at least on XP).


Patrice Terrier

Chris

There is new OpenGL section on the PowerBASIC forum, perhaps better to ask the new experts there, and speak of your new graphic control to those who need it on XP.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Brice Manuel

Chris:  Another good OpenGL book is: OpenGL Game Programming by Kevin Hawkins and Dave Astle.  It is published by Premier Press.

I realize this is OT, but I haven't had access to the official PowerBASIC forums for months so posting here is the best I can do ;)  IMHO, this book is better than the Redbook.  Amazon has a used copy listed for $9.99 + S/H with the CD still sealed.

Chris Boss

I am finding working with Lighting in OpenGl to be a real pain.

The problem is when you have multiple objects with multiple transformations (sizing, multiple rotations).

You just can't define the location of the light source. The light source is effected by transformations (ie. rotations) so the light ends up not in the right place.

What is the key to controlling the position of a light source, when you have multiple objects rotating in their own axis, rotating also on a larger axis (center of scene) and changing perspective (getting closer and then further away) ?


Charles Pegge


Chris: you just need to do your lighting before any of the object transformations. Then the the light sources will maintain a fixed position in the scene.

Charles

Frank Brübach

#13
QuoteChris: you just need to do your lighting before any of the object transformations.

well, charles that's right.

hi chris, my tip with lighting setup, although I am not openGL profi:

a) use setupScene for lights and texture, they are fixed. only if you are embedding with openGL primitives they will have kind of rotating, sizing or translation effects

b) take better separately using for creation openGL objects (quads, spheres, triangles and so on) with another sub ("drawScene")

SUB SetupScene (BYVAL hwnd AS DWORD, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG)

  LOCAL hr AS LONG
  LOCAL strTextureData AS STRING
  LOCAL TextureWidth, TextureHeight AS LONG
  DIM   TextureHandles(2) AS DWORD
  DIM   LightAmbient(3) AS SINGLE
  DIM   LightDiffuse(3) AS SINGLE
  DIM   LightPosition(3) AS SINGLE

  p1 = 0 : p2 = 1 : zoom = -5.0!

  ARRAY ASSIGN LightAmbient()  = 0.5!, 0.5!, 0.5!, 1.0!
  ARRAY ASSIGN LightDiffuse()  = 1.0!, 1.0!, 1.0!, 1.0!
  ARRAY ASSIGN LightPosition() = 0.0!, 0.0!, 2.0!, 1.0!

  ...

'----> texture handling

' Create Nearest Filtered Texture
  glBindTexture %GL_TEXTURE_2D, TextureHandles(0)
  glTexParameteri %GL_TEXTURE_2D, %GL_TEXTURE_MAG_FILTER, %GL_NEAREST
  glTexParameteri %GL_TEXTURE_2D, %GL_TEXTURE_MIN_FILTER, %GL_NEAREST
  glTexImage2D %GL_TEXTURE_2D, 0, 3, TextureWidth, TextureHeight, 0, _
               %GL_RGBA, %GL_UNSIGNED_BYTE, BYVAL STRPTR(strTextureData)  

...

End Sub


SUB DrawScene (BYVAL hwnd AS DWORD, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG)

  ' Clear the screen buffer
  glClear %GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT
  ' Reset the view
  glLoadIdentity

  glTranslatef 0.0!, 0.0!, zoom
  glRotatef xrot, 1.0!, 0.0!, 0.0!
  glRotatef yrot, 0.0!, 1.0!, 0.0!
  glBindTexture %GL_TEXTURE_2D, TextureHandles(filter)

  SELECT CASE nObject

        glBegin %GL_QUADS
        ' Front face
        glNormal3f 0.0!, 0.0!, 1.0!
        glTexCoord2f 0.0!, 0.0! : glVertex3f -1.0!, -1.0!,  1.0!
        glTexCoord2f 1.0!, 0.0! : glVertex3f  1.0!, -1.0!,  1.0!
        glTexCoord2f 1.0!, 1.0! : glVertex3f  1.0!,  1.0!,  1.0!
        glTexCoord2f 0.0!, 1.0! : glVertex3f -1.0!,  1.0!,  1.0!    

... etcpp (and so on..) .

End Sub


best regards, frank

Chris Boss

Sadly, it does not work to set the lighting before drawing the primitives or any transformations. I tried that first thing before any transformations of any kind (projection or modelview)
and I don't get the results I require.

If I define the lighting and one light (0) at certain position and then start drawing objects with transformations the light acts differently with every object as
if it is in a different place for each object and it changes every iteration (rotation changes). I am animating the scene and moving objects around and I can't get it right.

Because OpenGL allows you to define a different position for the light for each object (a good example is the solar system example) since the light for each object may come from a different direction, it obviously is effected by transformations (whether set before or after the transformation).

Now I don't know if I am having a problem because I am not using "Normals" yet. I am still reading up on how "normals" work.
Do the glu calls (ie. gluSphere) automatically define all the normals ?