Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

OpenGL Fireworks

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • OpenGL Fireworks

    Ok. The artifacting seems to be gone now (new image), and I
    introduced a timer-event into the message-pump in order to
    reduce the processor overhead...

    Take care!

    Scott

    ------------------------------------------------------------
    Original Message: July 4, 2006
    ------------------------------------------------------------
    Hi there!

    I came across an interesting Delphi demo earlier today, and in light of
    it being the Fourth of July and all, I thought I'd try my hand at doing
    a quick port of it to PowerBASIC. There are a few things I want to tweak
    in the next day or two, but it's still fun to watch as-is...

    Take care, and Happy Fourth!

    Scott Martindale
    [email protected]
    ------------------------------------------------------------

    Code:
    '-----------------------------------------------------------------------------------------
    '-----------------------------------------------------------------------------------------
    ' OpenGL Fireworks:
    '-----------------------------------------------------------------------------------------
    ' July 6, 2006 (Original July 4, 2006)
    ' PowerBASIC port by Scott Martindale [email protected]
    '
    ' Based on Delphi Code by Jan Horn:
    ' http://www.sulaco.co.za/opengl2.htm 
    '
    '-----------------------------------------------------------------------------------------
    ' METASTATEMENTS AND INCLUDES: |
    '------------------------------'
        #COMPILE EXE
        #DIM ALL
        #INCLUDE "Win32API.INC"
    
    '-----------------------------------------------------------------------------------------
    ' OpenGL Equates & Functions (From "gl.inc"): |
    '---------------------------------------------'
        MACRO GL_UNSIGNED_BYTE               = &h1401&
        MACRO GL_QUADS                       = &h0007&
        MACRO GL_COLOR_BUFFER_BIT            = &h4000&
        MACRO GL_DEPTH_BUFFER_BIT            = &h0100&
        MACRO GL_MATRIX_MODE                 = &h0BA0&
        MACRO GL_MODELVIEW                   = &h1700&
        MACRO GL_PROJECTION                  = &h1701&
        MACRO GL_TEXTURE_ENV                 = &h2300&
        MACRO GL_TEXTURE_ENV_MODE            = &h2200&
        MACRO GL_SMOOTH                      = &h1D01&
        MACRO GL_DEPTH_TEST                  = &h0B71&
        MACRO GL_SRC_ALPHA                   = &h0302&
        MACRO GL_ONE                         = &h0001&
        MACRO GL_BLEND                       = &h0BE2&
        MACRO GL_LINEAR                      = &h2601&
        MACRO GL_PERSPECTIVE_CORRECTION_HINT = &h0C50&
        MACRO GL_NICEST                      = &h1102&
        MACRO GL_TEXTURE_2D                  = &h0DE1&
        MACRO GL_TEXTURE_MAG_FILTER          = &h2800&
        MACRO GL_TEXTURE_MIN_FILTER          = &h2801&
        MACRO GL_MODULATE                    = &h0021&
        MACRO GL_RGBA                        = &h1908&
        MACRO GL_LUMINANCE                   = &h1909&
    
        MACRO glSub   =       DECLARE SUB
        MACRO gl32Lib =       LIB "opengl32.dll" ALIAS
        MACRO bvDWD   =       BYVAL DWORD
        MACRO bvLNG   =       BYVAL LONG
        MACRO bvSNG   =       BYVAL SINGLE
        MACRO bvDBL   =       BYVAL DOUBLE
    
        glSub glEnd           gl32Lib "glEnd"
        glSub glPushMatrix    gl32Lib "glPushMatrix"
        glSub glPopMatrix     gl32Lib "glPopMatrix"
        glSub glLoadIdentity  gl32Lib "glLoadIdentity"
        glSub glBegin         gl32Lib "glBegin"        (bvLNG)
        glSub glClear         gl32Lib "glClear"        (bvDWD)
        glSub glEnable        gl32Lib "glEnable"       (bvDWD)
        glSub glDisable       gl32Lib "glDisable"      (bvDWD)
        glSub glClearDepth    gl32Lib "glClearDepth"   (bvDBL)
        glSub glShadeModel    gl32Lib "glShadeModel"   (bvDWD)
        glSub glMatrixMode    gl32Lib "glMatrixMode"   (bvDWD)
        glSub glHint          gl32Lib "glHint"         (bvDWD, bvDWD)
        glSub glBlendFunc     gl32Lib "glBlendFunc"    (bvLNG, bvLNG)
        glSub glTexCoord2f    gl32Lib "glTexCoord2f"   (bvSNG, bvSNG)
        glSub glBindTexture   gl32Lib "glBindTexture"  (bvDWD, bvDWD)
        glSub glGenTextures   gl32Lib "glGenTextures"  (bvLNG, bvDWD)
        glSub glTexParameteri gl32Lib "glTexParameteri"(bvDWD, bvDWD, bvLNG)
        glSub glTexEnvi       gl32Lib "glTexEnvi"      (bvDWD, bvDWD, bvLNG)
        glSub glVertex3f      gl32Lib "glVertex3f"     (bvSNG, bvSNG, bvSNG)
        glSub glTranslatef    gl32Lib "glTranslatef"   (bvSNG, bvSNG, bvSNG)
        glSub glColor3f       gl32Lib "glColor3f"      (bvSNG, bvSNG, bvSNG)
        glSub glFrustum       gl32Lib "glFrustum"      (bvDBL, bvDBL, bvDBL,_
                                                        bvDBL, bvDBL, bvDBL)
        glSub glTexImage2D    gl32Lib "glTexImage2D"   (bvDWD, bvLNG, bvLNG,_
                                                        bvLNG, bvLNG, bvLNG,_
                                                        bvDWD, bvDWD, bvDWD)
        glSub glColor4f       gl32Lib "glColor4f"      (bvSNG, bvSNG, bvSNG, bvSNG)
        glSub glViewport      gl32Lib "glViewport"     (bvLNG, bvLNG, bvLNG, bvLNG)
        glSub glClearColor    gl32Lib "glClearColor"   (bvSNG, bvSNG, bvSNG, bvSNG)
    
    
        MACRO gluPerspective(fovy, nAspect, zNear, zFar)
            MACROTEMP xmin, xmax, ymin, ymax
            DIM xmin AS DOUBLE : DIM xmax AS DOUBLE
            DIM ymin AS DOUBLE : DIM ymax AS DOUBLE
            ymax = zNear * TAN(fovy * 0.00872664626)
            ymin = -ymax
            xmin = ymin * nAspect
            xmax = ymax * nAspect
            glFrustum xmin, xmax, ymin, ymax, zNear, zFar
        END MACRO
    '------------------------------------------------------------------------------
    ' Other Macros: |
    '---------------'
        MACRO EXPLOSION_SIZE = 0.8
        MACRO glTrue = -1
        MACRO glFalse = 0
    
    '------------------------------------------------------------------------------
    ' Firework UDTs: |
    '----------------'
        TYPE stParticle
           'X, Y and Z coordinates
                x  AS SINGLE
                y  AS SINGLE
                z  AS SINGLE
           'Amount of change in X, Y and Z direction
                dx AS SINGLE
                dy AS SINGLE
                dz AS SINGLE
           'Color of the particle
                r  AS SINGLE
                g  AS SINGLE
                b  AS SINGLE
        END TYPE
    
        TYPE stFirework
          'Particles in the explosion
               Particle(127) AS stParticle
          'Particles in the tail
               Trail(15) AS stParticle
          'When the firework was set off
               StartTime AS LONG
          'How long it should last
               Duration AS LONG
          'Visual style of firework
               nStyle AS LONG
          'X and Y coordinates
               x  AS SINGLE
               y  AS SINGLE
          'Change in X and Y direction
               dx AS SINGLE
               dy AS SINGLE
          'Explode Flag
               isExploding AS LONG
        END TYPE
    
    '-----------------------------------------------------------------------------------------
    ' GLOBAL VARIABLES:   |
    '---------------------'
        GLOBAL hWnd, g_HDC, DemoStart AS DWORD, msg AS tagMsg, drawRect AS RECT, _
               viewport() AS LONG, glKeyPressed() AS LONG
    
        GLOBAL ElapsedTime AS DWORD,      _ 'Elapsed time between frames
               ParticleTex AS DWORD,      _ 'Particle Texture Handle
               Fireworks   AS LONG,       _ 'Number of fireworks on screen at one time
               Firework()  AS stFirework    'Array of stFirework UDT structures
    
    '-----------------------------------------------------------------------------------------
    'Forward Declarations:|
    '---------------------'
        DECLARE SUB glInit
        DECLARE SUB drawFireworks
        DECLARE SUB makeFireworksTexture
        DECLARE SUB SetupFirework    (n AS LONG)
        DECLARE SUB FireworkTail     (n AS LONG)
        DECLARE SUB FireworkExplode  (n AS LONG)
        DECLARE SUB glResizeWnd (nWidth AS LONG, nHeight AS LONG)
        DECLARE SUB SetupPixelFormat (hDC AS DWORD)
        DECLARE SUB glBuildFont2D    (FontBase AS DWORD, FontName AS STRING, _
                                      BYVAL FontSize AS LONG)
    
    '-----------------------------------------------------------------------------------------
    'WINMAIN Function:    |
    '---------------------'
     FUNCTION WINMAIN (BYVAL hInstance     AS DWORD, _
                       BYVAL hPrevInstance AS DWORD, _
                       BYVAL lpCmdLine     AS ASCIIZ PTR, _
                       BYVAL iCmdShow      AS LONG) AS LONG
    
        DIM viewport(3)
        LOCAL wce AS WndClassEx, ClassName AS ASCIIZ * 80
        LOCAL LastTime AS DWORD
        ClassName         = "OpenGL"
        wce.cbSize        =  SIZEOF(wce)
        wce.style         = %CS_HREDRAW OR %CS_VREDRAW
        wce.lpfnWndProc   =  CODEPTR(WndProc)
        wce.cbClsExtra    =  0
        wce.cbWndExtra    =  0
        wce.hInstance     =  hInstance
        wce.hIcon         =  LoadIcon(hInstance, "OGL")
        wce.hCursor       =  LoadCursor(%NULL, BYVAL %IDC_ARROW)
        wce.hbrBackground = %NULL
        wce.lpszMenuName  = %NULL
        wce.lpszClassName =  VARPTR(ClassName)
        wce.hIconSm       =  LoadIcon(hInstance, BYVAL %IDI_APPLICATION)
    
        IF ISFALSE(RegisterClassEx(wce)) THEN
            MSGBOX "Unable to Register Window Class."
            EXIT FUNCTION
        END IF
    
      'Create a window using the registered class
            hWnd = CreateWindowEx(%NULL, ClassName, "Happy Forth of July!",_
                                  %WS_OVERLAPPEDWINDOW OR %WS_VISIBLE OR   _
                                  %WS_SYSMENU, 000,000, 800,600,           _
                                  %NULL, %NULL, hInstance, BYVAL %NULL)
    
            IF hWnd = 0 THEN
                MSGBOX "Unable to create window"
                EXIT FUNCTION
            END IF
    
      'Display the window on the screen, and set window's OpenGL attributes
            ShowWindow hWnd, iCmdShow
            UpdateWindow hWnd
            SetForegroundWindow hWnd
            SetFocus hWnd
            glInit
            DemoStart = GetTickCount
            settimer hWnd, 1, 10, %NULL
         'Main message loop:
            DO
                IF PeekMessage(msg, hWnd, 0, 0, %PM_NOREMOVE) THEN
                    IF GetMessage(msg, hWnd, 0, 0) THEN
                        TranslateMessage msg
                        DispatchMessage  msg
                        ELSE
                            EXIT DO
                    END IF
                    LastTime    =  ElapsedTime
                    ElapsedTime =  GetTickCount-DemoStart
                    ElapsedTime = (LastTime+ElapsedTime)/2
                    drawFireworks
                    SwapBuffers(g_HDC)
                ELSE
                    waitmessage
                END IF
            LOOP
            killtimer hWnd, 1
        FUNCTION = msg.wParam
    END FUNCTION
    
    
    '------------------------------------------------------------------------------
    'WndProc Function:    |
    '---------------------'
     FUNCTION WndProc (BYVAL hWnd AS DWORD,  BYVAL wMsg AS DWORD, _
                       BYVAL wParam AS LONG, BYVAL lParam AS LONG)AS LONG
    
        STATIC hDC AS DWORD, hRC AS DWORD
    
        SELECT CASE wMsg
    
            CASE %WM_CREATE
                hDC   = GetDC(hWnd)
                g_hDC = hDC
                SetupPixelFormat(hDC)
                hRC = wglCreateContext(hDC)
                wglMakeCurrent hDC, hRC
                GetWindowRect hWnd, drawRect
            CASE %WM_CLOSE
                wglMakeCurrent hDC, %NULL
                wglDeleteContext hDC
                PostQuitMessage 0
            CASE %WM_KEYDOWN
                SELECT CASE wParam
                    CASE %VK_UP
                        INCR Fireworks
                        Fireworks = MIN(Fireworks, UBOUND(Firework))
    
                    CASE %VK_DOWN
                        DECR Fireworks
                        Fireworks = MAX(fireworks, LBOUND(Firework))
    
                    CASE %VK_ESCAPE
                        wglMakeCurrent hDC, %NULL
                        wglDeleteContext hDC
                        PostQuitMessage 0
                END SELECT
    
    
            CASE %WM_SIZE
               glResizeWnd(LOWRD(lParam),HIWRD(lParam))
    
            CASE ELSE
                FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
    
        END SELECT
    
    END FUNCTION
    
    '------------------------------------------------------------------------------
        SUB SetupPixelFormat(hDC AS DWORD)
            LOCAL pfd AS PIXELFORMATDESCRIPTOR
    
            pfd.nSize           =  SIZEOF(PIXELFORMATDESCRIPTOR)
            pfd.nVersion        =  1
            pfd.dwFlags         = %PFD_DRAW_TO_WINDOW OR _
                                  %PFD_SUPPORT_OPENGL OR _
                                  %PFD_DOUBLEBUFFER
            pfd.iPixelType      = %PFD_TYPE_RGBA
            pfd.cColorBits      =  32
            pfd.cAlphaBits      = %NULL
            pfd.cDepthBits      =  16
            pfd.iLayerType      = %PFD_MAIN_PLANE
    
       'Set pixel format to device context.
            SetPixelFormat(hDC, ChoosePixelFormat(hDC, pfd), pfd)
        END SUB
    
    '------------------------------------------------------------------------------
    'Initializes/reinitializes firework variables
    '------------------------------------------------------------------------------
    SUB SetupFirework(n AS LONG)
        LOCAL ii AS LONG, fireworkColor AS LONG, rndParam AS SINGLE,_
              pParticle AS stParticle PTR
    
       'Reset exploding-flag.
            RESET Firework(n).isExploding
    
       'Select a firework color. 0=red,  1=green,  2=blue
            fireworkColor = RND(0,2)
    
       'Set initial firework values
            Firework(n).StartTime =   ElapsedTime
            FireWork(n).Duration  =   RND(0,1000) + 3000
            Firework(n).x         =  (RND*20)   - 10
            Firework(n).y         =  -20
            Firework(n).dx        = ((RND*2)-1)/80
            Firework(n).dy        =  (RND +1.5)/80
            Firework(n).nStyle     =  RND(0, 10)
    
       'Exploding particles
            pParticle = VARPTR(Firework(n).Particle(0))
            FOR ii = 0 TO 127
                IF Firework(n).nStyle < 2 THEN
                    rndParam = ((RND * 0.1667) + 0.40) * EXPLOSION_SIZE * 0.1
                ELSE
                    rndParam = ((RND * 0.1000) - 0.05) * EXPLOSION_SIZE
                END IF
                @pParticle.dx = rndParam * COS(ii/10)
                @pParticle.dy = rndParam * SIN(ii/10)
                @pParticle.dz = rndParam * COS(ii/04)
                @pParticle.x  = @pParticle.dx
                @pParticle.y  = @pParticle.dy
                @pParticle.z  = @pParticle.dz
    
                SELECT CASE AS LONG fireworkColor
                    CASE 0
                        @pParticle.r = ((RND * 0.3333) + 0.70)
                        @pParticle.g = ((RND * 0.3333) + 0.40)
                        @pParticle.b = ((RND * 0.3333) + 0.40)
                    CASE 1
                        @pParticle.r = ((RND * 0.3333) + 0.40)
                        @pParticle.g = ((RND * 0.3333) + 0.70)
                        @pParticle.b = ((RND * 0.3333) + 0.40)
                    CASE 2
                        @pParticle.r = ((RND * 0.3333) + 0.40)
                        @pParticle.g = ((RND * 0.3333) + 0.40)
                        @pParticle.b = ((RND * 0.3333) + 0.70)
                    CASE ELSE
                        @pParticle.r = ((RND * 0.3333) + 0.70)
                        @pParticle.g = ((RND * 0.3333) + 0.70)
                        @pParticle.b = ((RND * 0.3333) + 0.40)
                END SELECT
                INCR pParticle
            NEXT
    
       'Tail particles
            pParticle = VARPTR(Firework(n).Trail(0))
            FOR ii = 0 TO 15
                @pParticle.x  =  0
                @pParticle.y  =  0
               'Z will be used as particle "duration"
                @pParticle.z  =  50 + RND(0,50)
                @pParticle.dx = -0.7*Firework(n).dx
                @pParticle.dy = -(RND/20)-0.001
                SELECT CASE AS LONG fireworkColor
                    CASE 0
                        @pParticle.r = RND/3 + 0.8
                        @pParticle.g = RND/3 + 0.4
                        @pParticle.b = RND/3 + 0.4
                    CASE 1
                        @pParticle.r = RND/3 + 0.4
                        @pParticle.g = RND/3 + 0.8
                        @pParticle.b = RND/3 + 0.4
                    CASE 2
                        @pParticle.r = RND/3 + 0.4
                        @pParticle.g = RND/3 + 0.4
                        @pParticle.b = RND/3 + 0.8
                    CASE ELSE
                        @pParticle.r = RND/3 + 0.8
                        @pParticle.g = RND/3 + 0.8
                        @pParticle.b = RND/3 + 0.4
                END SELECT
                INCR pParticle
            NEXT
    
    END SUB
    
    '------------------------------------------------------------------------------
    'Draw the rocket "trail"
    '------------------------------------------------------------------------------
    SUB FireworkTail(n AS LONG)
        LOCAL ii AS LONG, pParticle AS stParticle PTR
    
       'The main part of the rocket.
            glTranslatef(Firework(n).x, Firework(n).y, 0)
            glColor3f(1.0, 1.0, 1.0)
            glBegin GL_QUADS
                glTexCoord2f(0.0, 0.0): glVertex3f(-1.0,-1.0, 0.0)
                glTexCoord2f(1.0, 0.0): glVertex3f( 1.0,-1.0, 0.0)
                glTexCoord2f(1.0, 1.0): glVertex3f( 1.0, 1.0, 0.0)
                glTexCoord2f(0.0, 1.0): glVertex3f(-1.0, 1.0, 0.0)
            glEnd
    
       'The tail of the rocket
            glBegin GL_QUADS
                pParticle = VARPTR(Firework(n).Trail(0))
                FOR ii = 0 TO 15
                    glColor4f(@pParticle.r, @pParticle.g, _
                              @pParticle.b, @pParticle.z * 0.01)
                    glTexCoord2f(0.0, 0.0)
                    glVertex3f(@pParticle.x-1.0, @pParticle.y-1.0, 0)
                    glTexCoord2f(1.0, 0.0)
                    glVertex3f(@pParticle.x+1.0, @pParticle.y-1.0, 0)
                    glTexCoord2f(1.0, 1.0)
                    glVertex3f(@pParticle.x+1.0, @pParticle.y+1.0, 0)
                    glTexCoord2f(0.0, 1.0)
                    glVertex3f(@pParticle.x-1.0, @pParticle.y+1.0, 0)
                    @pParticle.x = @pParticle.x + @pParticle.dx
                    @pParticle.y = @pParticle.y + @pParticle.dy
                    @pParticle.z = @pParticle.z - 1
                    IF ISFALSE(@pParticle.z) THEN
                        @pParticle.x  = 0
                        @pParticle.y  = 0
                        @pParticle.z  = 50 + RND(0,50)
                    END IF
                    INCR pParticle
                NEXT
            glEnd
    END SUB
    
    
    '------------------------------------------------------------------------------
    'Draw the explosion-plume
    '------------------------------------------------------------------------------
    MACRO halfPI = 1.5707963267948966192313216916398
    MACRO qtrPI  = 0.7853981633974483096156608458199
    SUB FireworkExplode(n AS LONG)
        DIM i AS LONG, slowDown AS SINGLE
    
        glTranslatef(Firework(n).x, Firework(n).y, 0)
    
        slowDown = ((ElapsedTime-Firework(n).StartTime-1000) - _
                     SQR(1000+Firework(n).StartTime-ElapsedTime)/5000)/6
    
        glBegin GL_QUADS
            FOR i = 0 TO 127
                glColor4f(Firework(n).Particle(i).r, _
                          Firework(n).Particle(i).g, _
                          Firework(n).Particle(i).b, _
                          1.8-(ElapsedTime-Firework(n).StartTime-1000)/1200)
                glTexCoord2f(0.0, 0.0)
                glVertex3f(Firework(n).Particle(i).x-1.0, _
                           Firework(n).Particle(i).y-1.0, _
                           Firework(n).Particle(i).z)
                glTexCoord2f(1.0, 0.0)
                glVertex3f(Firework(n).Particle(i).x+1.0, _
                           Firework(n).Particle(i).y-1.0, _
                           Firework(n).Particle(i).z)
                glTexCoord2f(1.0, 1.0)
                glVertex3f(Firework(n).Particle(i).x+1.0, _
                           Firework(n).Particle(i).y+1.0, _
                           Firework(n).Particle(i).z)
                glTexCoord2f(0.0, 1.0)
                glVertex3f(Firework(n).Particle(i).x-1.0, _
                           Firework(n).Particle(i).y+1.0, _
                           Firework(n).Particle(i).z)
    
               'Calculate the new coords based on the change, dx, in a direction
               'and slow the change down as time goes by.
                Firework(n).Particle(i).x =Firework(n).Particle(i).dx * slowDown
                Firework(n).Particle(i).y =Firework(n).Particle(i).dy * slowDown
                Firework(n).Particle(i).z =Firework(n).Particle(i).dz * slowDown
    
            NEXT
      glEnd
    
    END SUB
    
    '------------------------------------------------------------------------------
    'Render to Screen
    '------------------------------------------------------------------------------
    SUB drawFireworks
        LOCAL  n, et AS LONG, slowDown AS SINGLE
        STATIC initFlag&
    
        glClear GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT
        glMatrixMode GL_MODELVIEW
        glLoadIdentity
        glTranslatef(0.0, 0.0, -50.0)
    
        IF ISFALSE(initFlag) AND ((GetTickCount-DemoStart)>1000) THEN initFlag = -1
    
        FOR n = 0 TO Fireworks-1
           'Save-off base drawing-position:
                glPushMatrix
           'Display the firework:
                IF ElapsedTime-Firework(n).StartTime < 1000 THEN
                    FireworkTail(n)
                    RESET Firework(n).isExploding
                ELSEIF initFlag THEN
                    FireworkExplode(n)
                    Firework(n).isExploding = -1
                END IF
           'Check to see if we need to create a new firework:
                IF ElapsedTime-Firework(n).StartTime-FireWork(n).Duration >=0 THEN
                    SetupFirework(n)
                END IF
           'Keep moving and slowing-down firework:
                IF ISFALSE(Firework(n).isExploding) THEN
                    et       = (ElapsedTime-Firework(n).StartTime)
                    slowDown =  SQR(Firework(n).StartTime-ElapsedTime)
                    Firework(n).x = Firework(n).dx * (et-slowDown/7000)
                    Firework(n).y = Firework(n).dy * (et-slowDown/4500)-20
                END IF
           'Restore to base drawing-position:
                glPopMatrix
        NEXT
    
    END SUB
    
    '------------------------------------------------------------------------------
    'Initialize OpenGL attributes
    '------------------------------------------------------------------------------
        SUB glInit
            DIM i AS LONG
            glClearColor 0.0, 0.0, 0.0, 0.0  'Black Background
            glShadeModel GL_SMOOTH           'Enables Smooth Color Shading
            glClearDepth 1.0                 'Depth Buffer Setup
            glDisable GL_DEPTH_TEST
            glBlendFunc GL_SRC_ALPHA, GL_ONE
            glEnable GL_BLEND
    
            glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
            glEnable GL_TEXTURE_2D
    
           'Create "particle" texture from image data
                makeFireworksTexture
    
           'Max number of fireworks. Change to suit...
                DIM Firework(9)
    
           'Set random-number seed.
                RANDOMIZE TIMER
    
           'Initial number of fireworks.
                Fireworks = 3
    
           'Initialize fireworks
                FOR i = 0 TO Fireworks-1
                    SetupFirework(i)
                    Firework(i).StartTime = -1000*i
                NEXT
    
        END SUB
    
    '------------------------------------------------------------------------------
    'Process window-resizing event
    '------------------------------------------------------------------------------
        SUB glResizeWnd(nWidth AS LONG, nHeight AS LONG)
          nHeight = MAX&(nHeight, 1)
          glViewport 0, 0, nWidth, nHeight
          glMatrixMode GL_PROJECTION
          glLoadIdentity
          gluPerspective(45.0, nWidth/nHeight, 1.0, 100.0)
          glMatrixMode GL_MODELVIEW
          glLoadIdentity
        END SUB
    
    '------------------------------------------------------------------------------
    'Assign embedded image-data to firework texture.
    '------------------------------------------------------------------------------
        SUB makeFireworksTexture
    
            glGenTextures   (1, ParticleTex)
            glBindTexture   (GL_TEXTURE_2D,  ParticleTex)
            glTexEnvi       (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
            glTexParameteri (GL_TEXTURE_2D,  GL_TEXTURE_MAG_FILTER, GL_LINEAR)
            glTexParameteri (GL_TEXTURE_2D,  GL_TEXTURE_MIN_FILTER, GL_LINEAR)
            glTexImage2D    (GL_TEXTURE_2D,  0, GL_RGBA, 64, 64, 0, _
                             GL_LUMINANCE,   GL_UNSIGNED_BYTE, CODEPTR(imageData))
            EXIT SUB
    
            imageData:
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h1E1C0000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h281D0000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h2A1A0000,&h0000001E,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h2B190000,&h001F0023,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h36190000,&h0027202C,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h37000000,&h002A2634
               !DD &h1A000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h311D0000
               !DD &h002B2545,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h1D000000
               !DD &h2D280000,&h00302954,&h19000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h1C000000,&h342C0028,&h00333858,&h00240000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h3F291A30,&h1B364C58,&h002F0000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h4F263232,&h2540595D
               !DD &h002B0000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h4C2A4D28
               !DD &h30576B70,&h00261D00,&h00000000,&h00000000,&h00000000
               !DD &h001B0000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h47465600,&h35638086,&h001D2100,&h00000000,&h00000000
               !DD &h00000000,&h00001919,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h4B6B4200,&h3A6F997F,&h00002200,&h00000000
               !DD &h00000000,&h22000000,&h00000000,&h001C0000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h67782300,&h4480AA76,&h00002300
               !DD &h00000000,&h00001B1D,&h001F1E00,&h1C000000,&h00001F23
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h824D0000,&h4F97B579
               !DD &h1D002D00,&h1E000019,&h00001A22,&h00001D22,&h2C2E2200
               !DD &h0000001D,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h001B0000,&h791E0000
               !DD &h5FAAB288,&h31232B1D,&h2D21001B,&h251C1824,&h2800001B
               !DD &h232A393B,&h00001A1D,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h21000000
               !DD &h3F000021,&h73C1B489,&h363B3A2B,&h32412E18,&h19292721
               !DD &h54543E1E,&h40383640,&h00002036,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h1E000000,&h19193030,&h91CFB66C,&h3856514B,&h3D4E5436
               !DD &h48292937,&h5D65706B,&h37485356,&h0000001C,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h1A000000,&h274E492C,&hACCF9D3C,&h51657378
               !DD &h485F7673,&h8B7B5741,&h5E6A7C81,&h00002F4A,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h1A000000,&h1B1E1C1D,&h686E4A28,&hBDC26F3F
               !DD &h88779BA8,&h6A667B9A,&h7E99A08A,&h1F325069,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h201C0000,&h2E302826,&h3233282A,&h9276503B
               !DD &hCAAB6C7E,&hB3A8B7C6,&hAA9388A1,&h31516D99,&h0000001C
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h3326201A,&h5549443F
               !DD &hA98C7763,&hD5B1A5B7,&hC9D2D4D9,&h669FB1B8,&h00001937
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h46302000,&hAD91765A,&hE1D3CFC3,&hD1E6E8E6,&h34648DB6
               !DD &h00002128,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h694F331B,&hEDE0B98A,&hE0F5F6F3
               !DD &h637592B8,&h2D354356,&h00002123,&h19000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h1D000000,&h382C2A25,&hA8835D46,&hF4EEE1C9
               !DD &hF1FCFBF8,&h3F6793C5,&h0000002B,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h30230000,&h37373732,&h3C343337,&hB088644C
               !DD &hF6F6F3DB,&hFBFAFBF5,&h5E99D3ED,&h00001F3F,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h29220000,&h2E2F2D2C,&h001A1B22,&h281A0000
               !DD &hB1886C44,&hEAF0ECDE,&hF1EFEED3,&h5D8EC8E3,&h001C2C40
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h001C1900,&h00000000,&h00000000
               !DD &h4B290000,&hC494765F,&hBCD6C8D6,&hCCE3BF95,&h5D83B8CF
               !DD &h0000203A,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h574C3000,&hB09E7552,&h84AEA095,&hAED9927E
               !DD &h5B8FB79E,&h00002A42,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h25000000,&h2F394B46,&h697C754D,&h5A77835B
               !DD &hABB66C7B,&h6CA78873,&h00242B3A,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h53482100,&h341B1C3C,&h314C544C
               !DD &h484C684B,&hAA83537C,&h90745073,&h1F1C2158,&h00000019
               !DD &h00000000,&h001C1B00,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h244F583C,&h2E220000
               !DD &h13273332,&h3A40444A,&h964C4F74,&h6A344874,&h191F477E
               !DD &h00001A1A,&h00000000,&h00000000,&h00000019,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h502E0000,&h00002C4D
               !DD &h201D1C00,&h1B001920,&h2A3C214D,&h6F1C5668,&h262A4670
               !DD &h1E49785E,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h3546391C
               !DD &h00000000,&h00000000,&h30000000,&h1A360E47,&h46005D5B
               !DD &h00263E63,&h3D6A601A,&h0000001A,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h2F000000
               !DD &h00002D3B,&h00000000,&h00000000,&h4A000000,&h00370F2B
               !DD &h1D00684E,&h0025354E,&h5C4F0000,&h00001E38,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h2C2F1D00,&h00000019,&h00000000,&h00000000,&h50240000
               !DD &h00371B00,&h00006743,&h001B3235,&h4D1A0000,&h001C2D4F
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00001E00,&h00000000,&h00000000,&h00000000
               !DD &h3A450000,&h002F1E00,&h00195A2E,&h00002D19,&h00000000
               !DD &h00244745,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h20541E00,&h00281E00,&h001A541F,&h00002200
               !DD &h00000000,&h1E3A3E00,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h004C4000,&h00222000,&h00205000
               !DD &h00191900,&h00000000,&h3A3B0000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00305700,&h00202500
               !DD &h002D5200,&h00000000,&h00000000,&h32000000,&h00000026
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h0000532E
               !DD &h001A2600,&h003C4900,&h00000000,&h00000000,&h00000000
               !DD &h0000212A,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00003847,&h00002400,&h00433B00,&h00000000,&h00000000
               !DD &h00000000,&h00202500,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h1E000000,&h00001B4E,&h00002400,&h00432F00,&h00000000
               !DD &h00000000,&h00000000,&h001B0000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h34000000,&h0000003A,&h00001E00,&h003E2500
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h3E000000,&h00000021,&h00000000
               !DD &h1D3B2300,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h311F0000,&h00000000
               !DD &h00000000,&h1D321D00,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h1F2B0000
               !DD &h00000000,&h00000000,&h002B1B00,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00290000,&h00000000,&h00000000,&h00230000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h001B1C00,&h00000000,&h00000000,&h00230000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00001900,&h00000000,&h00000000
               !DD &h001E0000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000,&h00000000
               !DD &h00000000,&h00000000,&h00000000,&h00000000
        END SUB
    '------------------------------------------------------------------------------
    '------------------------------------------------------------------------------
    [This message has been edited by Scott J. Martindale (edited July 06, 2006).]
    Scott Martindale
    [email protected]

  • #2
    Cool! Looks Awesome. Only thing I noticed right away is the Square
    at explosion which is also somewhat visible when they are flying.

    Fix that and add some smoke and other leftovers/artifacts and it will
    look pretty cool.

    ------------------
    If you aim at nothing...you will hit it.
    sigpic
    Mobile Solutions
    Sys Analyst and Development

    Comment


    • #3
      Scott,
      I am working on a 3d project and have found your Opengl demos
      very useful indeed. Can I make a little contribution here:

      Your demo uses 100% CPU processing power - generating about 400 frames
      per sec (on my PC). Also the app will not terminate properly with an AltF4
      or the escape key.

      These problems are resolved with the 4 changes below. Then the CPU processor
      loading drops to a modest 4% even on a full 1280x1024 screen. You will also
      find that you dont get artefacts when you resize the screen by dragging.

      In the past, The PCs video card got terminally roasted, mostly due to inadequate
      ventilation in the casing but I suspect feeding it unlimited frames didnt help.

      In my project, I am using 3d + collision physics + real time wave synth so
      good multitasking performance is essential.

      <code>
      '1 GLOBALise ElapsedTime

      '2 replace customised WinMain loop with a timer and a regular loop:

      SetTimer hWnd,1,10,%NULL ' the minimum timer is probably around 16 ie. 1/64 sec
      DO WHILE GetMessage(Msg, %NULL, 0, 0)
      TranslateMessage Msg
      DispatchMessage Msg
      LOOP

      '3 in WndProc add:

      CASE %WM_TIMER
      IF wParam=1 THEN
      LastTime = ElapsedTime
      ElapsedTime = GetTickCount-DemoStart
      ElapsedTime = (LastTime+ElapsedTime)/2
      drawFireworks
      SwapBuffers(g_HDC)
      END IF

      '4 replace PostQuitMessage 0 wherever it occurs
      ' with:
      KillTimer hWnd,1: PostQuitMessage 0
      </code>

      ------------------
      Charles
      oxygenbasic.org

      Comment


      • #4
        Hi there!

        Thanks for the preliminary feedback. The reason for me posting it
        as-is rather than a "more polished" version, was that I just came
        across the Delphi-code (which I don't program in) earlier that
        afternoon; and given the short turn-around time needed to pull a
        PB-port off (and still have it ACTUALLY be the "Fourth"), there
        simply wasn't enough time everything as nice as I would have liked
        on the first go around. Unfortunately, missing things like the not
        utilizing a timer to free-up resources was one of them.

        Regarding the artifacting; the image which I used unmodified from
        the original, apparently has a near-zero luminance value (4 on a
        0-255 scale) that is causing most if not all of the problem.

        That said, I'll address these concerns and several of my own as
        well either later on tonight, or tomorrow evening.

        Thanks!!

        ------------------
        Scott Martindale
        [email protected]

        [This message has been edited by Scott J. Martindale (edited July 05, 2006).]
        Scott Martindale
        [email protected]

        Comment


        • #5
          Hello again,

          The aforementioned problems seem to be fixed now, and are reflected
          in the code listed above...

          Thanks!


          ------------------
          Scott Martindale
          [email protected]
          Scott Martindale
          [email protected]

          Comment

          Working...
          X