• Welcome to Theos PowerBasic Museum 2017.

BassBox

Started by Patrice Terrier, October 08, 2007, 10:57:44 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

Charles,

Great work, thank you very much for this new version!!!

Right now, I am writing a generic BBP_CreateGLTextureFromFile to create on the fly, OpenGL compatible texture, from any of these graphic formats: BMP, DIB, GIF, ICO, JPG, JPEG, PNG, TIF (and whatever the size of the original file is).

Each texture will use full 32-bit ABGR color to support variable opacity like with PNG files.

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

Charles Pegge


Thanks Patrice.

This might be useful to you. It is the module I have been using on my other Opengl progs. As you can see I take a 256x256 thumbnail of the image and use that as the basis of the texture. This works fine for smallish areas. And you can also carry out any preprocessing of the colors at the same time as you do the RB pixel swap.

I use an array of dynamic strings mapref() to hold each of the converted pixmaps.


' ========================================================================================
' Retrieves the path of the calling process.
' ========================================================================================


TYPE colorARGB32
blue  AS BYTE
green AS BYTE
red   AS BYTE
alpha AS BYTE
END TYPE

UNION pix4
whole  AS LONG
colors AS colorARGB32
END UNION

' ========================================================================================


FUNCTION SetTexture(biwidth AS LONG , biHeight AS LONG, ref AS LONG) AS LONG
DIM p AS BYTE PTR
p=STRPTR(pixmap(ref))
glBindTexture GL_TEXTURE_2D, mapref(ref)    ' Bind Texture
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST
'             target      level components width height  border format   datatype      ptr to image data
glTexImage2D GL_TEXTURE_2D, 0,      4, biWidth, biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, @p
END FUNCTION

FUNCTION GDIP_GetTexMap (img AS STRING, ref AS LONG ) AS LONG
   LOCAL hStatus AS LONG
   LOCAL pBitmap AS LONG
   LOCAL pStream AS LONG
   LOCAL pStreamo AS LONG
   LOCAL pThumb  AS LONG
   LOCAL strFileName AS STRING
   LOCAL pix AS pix4
   DIM thumf AS STRING:thumf=UCODE$("thumb.png")
   DIM cParamList AS EncoderParameters
   DIM cParam AS EncoderParameter
   cParamList.Count=0
   strFileName = UCODE$(img)
   hStatus = GdipLoadImageFromFile(strFileName, pBitmap)
   hStatus = GdipGetImageThumbnail ( pBitMap, 256, 256, pThumb, 0, 0 )
   hStatus = GdipImageRotateFlip(pThumb,%RotateNoneFlipY) 'invert
   DIM w AS LONG PTR
   pixmap(ref)=NUL$(4*256*256)
   w=STRPTR(pixmap(ref))
   DIM x AS LONG, y AS LONG
   FOR y=0 TO 255
    FOR x=0 TO 255
     GdipBitmapGetPixel(pThumb, x, y, pix.whole)
     SWAP pix.colors.red, pix.colors.blue
     @w=pix.whole: INCR w
    NEXT
   NEXT
   SetTexture(256,256,ref)
   IF pBitmap THEN GdipDisposeImage(pBitmap)
   IF pThumb  THEN GdipDisposeImage(pThumb)
   FUNCTION = 1
END FUNCTION

Patrice Terrier

#107
Thank you Charles,

The one I have done (same as in GDImage) is able to use a picture from any size and create a texture of a specific square or rectangular size:

Note: The function below is not the final version, thus please wait until I post a new patch.


FUNCTION BBP_CreateGLTextureFromFile (zFullName AS ASCIIZ, Xin AS LONG, Yin AS LONG, PixelArray() AS BYTE)
    LOCAL bi AS MYBITMAPINFO
    LOCAL bm AS BITMAP
    LOCAL fd AS WIN32_FIND_DATA
    LOCAL pBits AS BYTE PTR
    LOCAL hFind, So, K, hIC, hDC, hTmpDC, Img, imgW, imgH, xP, yP, xS, yS, hDIB, ARGBcolor AS LONG
    LOCAL A, R, G, B AS BYTE, scale AS SINGLE, sDot AS STRING, graphics AS LONG

    Xin = 0: Yin = 0: imgW = 0: imgH = 0
    sDot = "."

  ' Check if file exist
    So = INSTR(-1, zFullName, sDot)
    IF So THEN
       IF LEN(zFullName) THEN
          hFind = FindFirstFile(zFullName, fd)
          IF hFind <> -1 THEN
             CALL FindClose(hFind)
          ELSE
             So = 0
          END IF
       END IF
    END IF

    IF So THEN
       ImgType$ = UCASE$(MID$(zFullName, So)) + sDot
       ImageType& = INSTR(".BMP.DIB.GIF.ICO.JPG.JPEG.PNG.TIF.TIFF.", ImgType$)
       IF ImageType& THEN
        ' Load the image
          IF GdipLoadImageFromFile((UCODE$(zFullName)), Img) = 0 THEN
           ' Get the image height and width
             CALL GdipGetImageWidth(Img, imgW)
             CALL GdipGetImageHeight(Img, imgH)

             DIM P(1 TO 11) AS LONG
             P(1)= 2: P(2) = 4: P(3) = 8: P(4) = 16: P(5) = 32: P(6) = 64: P(7) = 128: P(8)= 256: P(9) = 512: P(10) = 1024: P(11) = 2048
             FOR K = UBOUND(P) TO LBOUND(P) STEP -1
                 IF Xin = 0 AND imgW > P(K) - 1 THEN Xin = P(K)
                 IF Yin = 0 AND imgH > P(K) - 1 THEN Yin = P(K)
             NEXT

             'IF DoNotSquareTexture(0,0) THEN
             '   CALL DoNotSquareTexture(0, 1)
             'ELSE
             '   Xin = MAX&(Xin, Yin): Yin = Xin
             'END IF

           ' Perform scale adjustment (zIconise(imgW, imgH, Xin, Yin, xP, yP, xS, yS))
           ' ------------------------------------------------------------------------
             IF imgW THEN scale = Xin / imgW
             IF scale > 1 THEN scale = 1
             xS = imgW * scale: yS = imgH * scale
             ' In case Height > Yin compute new scale factor
             IF yS > Yin THEN
                IF imgH THEN scale = Yin / imgH
                xS = imgW * scale: yS = imgH * scale
             END IF
             xP = (Xin - xS) \ 2: yP = (Yin - yS) \ 2
           ' ------------------------------------------------------------------------
                         
             hIC = CreateIC("DISPLAY", BYVAL 0, BYVAL 0, BYVAL 0)
             hDC = CreateCompatibleDC(hIC)
             
             bi.bmiHeader.biSize = SIZEOF(bi.bmiHeader)
             bi.bmiHeader.biWidth = Xin
             bi.bmiHeader.biHeight = Yin
             bi.bmiHeader.biPlanes = 1
             bi.bmiHeader.biBitCount = 32
             bi.bmiHeader.biCompression = 0 ' %BI_RGB
             hDIB = MyCreateDIBSection(hDC, bi, %DIB_RGB_COLORS, 0, 0, 0)
                         
             CALL SelectObject(hDC, hDIB)
         
           ' Draw image
             IF GdipCreateFromHDC(hDC, graphics) = 0 THEN
              ' Set up stretching QualityMode
                CALL GdipSetInterpolationMode(graphics, 2)
         
              ' Fill the background with color of pixel(0,0)
                CALL GdipBitmapGetPixel(img, 0, 0, ARGBcolor)
                CALL BBP_SplitColorARGB(ARGBcolor, A, R, G, B)
                CALL GetObject(hDIB, SIZEOF(bm), bm)
                pBits = bm.bmBits
                FOR K = (Xin * Yin) TO 1 STEP - 1
                    @pBits[3] = A
                    @pBits[2] = R
                    @pBits[1] = G
                    @pBits[0] = B
                    pBits = pBits + 4
                NEXT
         
              ' Draw image
                IF GdipDrawImageRectRectI(graphics, img, _
                                          xP, yP, xS, yS, _
                                          0, 0, imgW, imgH, %UnitPixel, _
                                          0) = 0 THEN ' This is an optional parameter
                   REDIM PixelArray(0 TO Xin * Yin * 4 - 1) AS BYTE
                   IF GetDIBits(hTmpDC, hDIB, 0, Yin, PixelArray(0), BYVAL VarPtr(bi), 0) THEN
                   '  Perform Red and Green permutation
                      pBits = VARPTR(PixelArray(0))
                      FOR K& = (Xin * Yin) TO 1 STEP - 1
                          R? = @pBits[2]: @pBits[2] = @pBits[0]: @pBits[0] = R?: pBits = pBits + 4
                      NEXT
                      FUNCTION = -1 '// All went fine
                   END IF
                END IF
              ' Cleanup
                CALL GdipDeleteGraphics(graphics)
             END IF
             CALL GdipDisposeImage(img): img = 0
             CALL DeleteObject(hDIB)
             IF hDC THEN CALL DeleteDC(hDC)
             IF hIC THEN CALL DeleteDC(hIC)

          END IF
       END IF
    END IF

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

Petr Schreiber

Hi,

new version of plugin looks very cool, good work !


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

psch.thinbasic.com

Charles Pegge

#109
Well I've got another one hear which uses light modulation, and several sources of light. Per object illumination its very useful to provide highlights.

The zip below contains PLUGIN003.DLL which overwrites the previous plgin003. Source code is also included as PLUGIN003b.bas but the opengl macro folder is not included this time, being the same as the previous.

Petr Schreiber

Even better,

thanks for sharing!


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

psch.thinbasic.com

Patrice Terrier

#111
This patch introduces a new BBPlugin.inc with built-in 32-bit ABGR OpenGL texture builder.

The structure of the BBPlugin folder now includes two special folders:

  • BBPlugin\Include (put all include files there)
  • BBPlugin\Texture (put all texture files there)

32-bit ABGR OpenGL texture

BBPlugin.inc has a new procedure: BBP_CreateGLTextureFromFile
to create full 32-bit ABGR texture from any .BMP .DIB .GIF .ICO .JPG. JPEG .PNG .TIF .TIFF
if the size of the graphic source file doesn't match a ^2, then the procedure adjusts it, to match OpenGL requirement.

FUNCTION BBP_CreateGLTextureFromFile ( _
zFullPath AS ASCIIZ, _               '// The graphic file that wil be used to create the texture.
BYREF Xin AS LONG, _                '// Return the width of the new texture
BYREF Yin AS LONG, _                '// Return the height of the new texture.
PixelArray() AS BYTE, _             '// Byte array that will store the new texture.
BYVAL SquareTexture AS LONG _'// %TRUE if you want to force texture creation to a square size.
) AS LONG


FUNCTION BBP_CreateGLTextureFromFile (zFullPath AS ASCIIZ, Xin AS LONG, Yin AS LONG, PixelArray() AS BYTE, BYVAL SquareTexture AS LONG) AS LONG
    LOCAL bi AS MYBITMAPINFO, bm AS BITMAP
    LOCAL pBits AS BYTE PTR, scale AS SINGLE
    LOCAL K, xP, yP, xS, yS, So, hDIB, hFind, hIC, hDC, Img, imgW, imgH, ImgAttr AS LONG
    LOCAL sImgName, sPathName AS STRING
    LOCAL ARGBcolor AS LONG, A, R, G, B AS BYTE

    Xin = 0: Yin = 0: imgW = 0: imgH = 0
   
  ' Make sure that a full path is being used.
    sImgName = zFullPath
    CALL BBP_SplitN(BBP_ExeName, sPathName, "")
    IF INSTR(sImgName, sPathName) = 0 THEN sImgName = sPathName + sImgName

    So = INSTR(-1, sImgName, $Dot)
    IF So AND NOT BBP_Exist((sImgName)) THEN So = 0
    IF So THEN
       ImgType$ = UCASE$(MID$(sImgName, So)) + $Dot
       ImageType& = INSTR(".BMP.DIB.GIF.ICO.JPG.JPEG.PNG.TIF.TIFF.", ImgType$)
       IF ImageType& THEN
        ' Load the image
          IF GdipLoadImageFromFile((UCODE$(sImgName)), Img) = 0 THEN
           ' Get the image height and width
             CALL GdipGetImageWidth(Img, imgW)
             CALL GdipGetImageHeight(Img, imgH)
   
             DIM P(1 TO 11) AS LONG
             P(1)= 2: P(2) = 4: P(3) = 8: P(4) = 16: P(5) = 32: P(6) = 64: P(7) = 128: P(8)= 256: P(9) = 512: P(10) = 1024: P(11) = 2048
             FOR K& = UBOUND(P) TO LBOUND(P) STEP -1
                 IF Xin = 0 AND ImgW > P(K&) - 1 THEN Xin = P(K&)
                 IF Yin = 0 AND ImgH > P(K&) - 1 THEN Yin = P(K&)
             NEXT
         
             IF SquareTexture AND Xin <> Yin THEN
                Xin = MAX&(Xin, Yin): Yin = Xin
             ELSE
                SquareTexture = 0
             END IF
     
           ' Perform scale adjustment (zIconise(imgW, imgH, Xin, Yin, xP, yP, xS, yS))
           ' ------------------------------------------------------------------------
             IF imgW THEN scale = Xin / imgW
             IF scale > 1 THEN scale = 1
              xS = imgW * scale: yS = imgH * scale
             ' In case Height > Yin compute new scale factor
             IF yS > Yin THEN
                IF imgH THEN scale = Yin / imgH
                xS = imgW * scale: yS = imgH * scale
             END IF
             xP = (Xin - xS) \ 2: yP = (Yin - yS) \ 2
            ' ------------------------------------------------------------------------
     
             hIC = CreateIC("DISPLAY", BYVAL 0, BYVAL 0, BYVAL 0)
             hDC = CreateCompatibleDC(hIC)
     
             bi.bmiHeader.biSize = SIZEOF(bi.bmiHeader)
             bi.bmiHeader.biWidth = Xin
             bi.bmiHeader.biHeight = Yin
             bi.bmiHeader.biPlanes = 1
             bi.bmiHeader.biBitCount = 32
             bi.bmiHeader.biCompression = 0 ' %BI_RGB
             hDIB = MyCreateDIBSection(hDC, bi, 0, 0, 0, 0)
     
             CALL SelectObject(hDC, hDIB)
           ' Draw image
             IF GdipCreateFromHDC(hDC, graphics&) = 0 THEN
         
              ' Set up stretching QualityMode
                CALL GdipSetInterpolationMode(graphics&, 2)

              ' Fill the background with color of pixel(0,0)
                IF SquareTexture THEN
                   CALL GdipBitmapGetPixel(img, 0, 0, ARGBcolor)
                   CALL BBP_SplitColorARGB(ARGBcolor, A, R, G, B)
                   CALL GetObject(hDIB, SIZEOF(bm), bm)
                   pBits = bm.bmBits
                   FOR K = (Xin * Yin) TO 1 STEP - 1
                       @pBits[3] = A
                       @pBits[2] = R
                       @pBits[1] = G
                       @pBits[0] = B
                       pBits = pBits + 4
                   NEXT
                END IF
               
              ' We remove the magenta transparent color
                'IF GdipCreateImageAttributes(ImgAttr) = 0 THEN
                '   DIM map(0 TO 1) AS COLORMAP
                '   map(0).cmFrom = %ZI_MAPCOLORFROM ' ZD_ColorARGB(255, RGB(128,127,128))
                '   map(0).cmTo   = %ZI_MAPCOLORTO   ' ZD_ColorARGB(255, RGB(128,128,128))
                '   map(1).cmFrom = ZD_ColorARGB(255, %ZD_TRANSCOLOR) ' &HFFFF00FF
                '   map(1).cmTo   = ZD_ColorARGB(0,  %ZD_TRANSCOLOR)
                '   CALL GdipSetImageAttributesRemapTable (ImgAttr, %ColorAdjustTypeBitmap, %TRUE, 2, map(0))
                'END IF
         
              ' Draw image
                IF GdipDrawImageRectRectI(graphics&, Img, _
                                    xP, yP, xS, yS, _
                                    0, 0, ImgW, ImgH, %UnitPixel, _
                                    ImgAttr) = 0 THEN ' This is an optional parameter
                   bi.bmiHeader.biSize        = SIZEOF(bi.bmiHeader)
                   bi.bmiHeader.biWidth       = Xin
                   bi.bmiHeader.biHeight      = Yin
                   bi.bmiHeader.biPlanes      = 1
                   bi.bmiHeader.biBitCount    = 32
                   bi.bmiHeader.biCompression = 0 ' %BI_RGB
                   REDIM PixelArray(0 TO Xin * Yin * 4 - 1) AS BYTE
                   IF GetDIBits(hDC, hDIB, 0, Yin, PixelArray(0), BYVAL VARPTR(bi), 0) THEN
                   '  Perform Red and Green permutation
                      pBits = VARPTR(PixelArray(0))
                      FOR K = (Xin * Yin) TO 1 STEP - 1
                          R = @pBits[2]: @pBits[2] = @pBits[0]: @pBits[0] = R: pBits = pBits + 4
                      NEXT
                      FUNCTION = -1
                   END IF
                END IF
              ' Cleanup
                'IF ImgAttr THEN CALL GdipDisposeImageAttributes(ImgAttr)
                CALL GdipDeleteGraphics(graphics&)
             END IF
             CALL DeleteObject(hDIB)
             IF hDC THEN CALL DeleteDC(hDC)
             IF hIC THEN CALL DeleteDC(hIC)
          END IF
          CALL GdipDisposeImage(Img): Img = 0
       END IF   
    END IF

END FUNCTION


Note: A texture is not limited to square size, you can create a rectangular one as well.
Texture width and height can be any combination of these (in pixel):
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048.


Because the texture are 32-bit ABGR (Alpha, Blue, Green, Red) they can be used to produce progressive opacity,
Thus I am looking forward to see more plugins using it ;)

The latest PolyHedra which uses light modulation has been added as plugin #5. (Thank you Charles!)

See below BassPatch31.zip

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

Kent Sarikaya

Gets better and betters guys, thanks for all the work!!

Patrice Terrier

#113
This version of BassBox brings up two new important features:

1 - FFT support

FFT is widely used to perform visual audio sound representation, and BassBox makes it simple to use.

In the BBPLUGIN structure there are two new members for that purpose:


    FFTdata      AS DWORD       '// DWORD pointer to the FFT() AS SINGLE array.
    FFTsize      AS WORD        '// Size of the FFT array.


and to use it inside of your plugin, you just need to get the data during the %BBP_RENDER message, like this:


         '// This is where the magic happens:
         '// BBP.FFTsize returns a pointer to an area of memory containing an array of 256 singles.
         '// This is then mapped to the fft() array where it can be accessed.
         DIM fft(BBP.FFTsize) AS SINGLE AT BBP.FFTdata
         DIM SoundBuffer(BBP.FFTsize) AS SINGLE



2 - Mouse support

BassBox, allows you handle ALL the mouse messages occuring inside of the OpenGL control.

In the BBPLUGIN structure there are three new members for that purpose:


    WinMsg       AS LONG        '// True Windows message.
    wParam       AS LONG        '// wParam
    lParam       AS LONG        '// lParam



And there is a new %BBP_MOUSE message that you handle in your plugin like this:


    CASE %BBP_MOUSE
         '// Handle all Windows mouse messages there
         Msg = BBP.WinMsg: wParam = BBP.wParam: lParam = BBP.lParam
         SELECT CASE LONG Msg
         CASE %WM_MOUSEMOVE
              x = LO(WORD, lParam): y = HI(WORD, lParam)
              IF MDown = %MK_LBUTTON THEN
                 Cy = Cy + (x - Mx)
                 Cx = Cx + (y - My)
                 IF Cy < -90 THEN Cy = -90
                 IF Cy >  90 THEN Cy =  90
              ELSEIF MDown = %MK_RBUTTON THEN
                 Cy = Cy + (x - Mx)
                 Cz = Cz + (y - My)
              END IF
              Mx = x: My = y

         CASE %WM_LBUTTONDOWN, %WM_RBUTTONDOWN      ', %WM_MBUTTONDOWN, %WM_XBUTTONDOWN
              Mx = LO(WORD, lParam): My = HI(WORD, lParam)
              IF wParam = %MK_LBUTTON OR wParam = %MK_RBUTTON THEN MDown = wParam

         CASE %WM_LBUTTONUP, %WM_RBUTTONUP          ', %WM_MBUTTONUP, %WM_XBUTTONUP
              MDown = 0

         'CASE %WM_LBUTTONDBLCLK, %WM_RBUTTONDBLCLK ', %WM_MBUTTONDBLCLK, %WM_XBUTTONDBLCLK
         'CASE %WM_MOUSEWHEEL
         END SELECT



And to show you everything in context, I have added a new visual plugin: Magic spectrum

Magic spectrum uses the left mouse button to change the camera angle, and the right mouse button to zoom in out.

Screen shot:




And YES, it is always coming better  ;D

See below BassPatch32.zip

...

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

Petr Schreiber

I don't know what to say,

this is very cool again ;D

Just one issue - when I select one of Charles's plugins and move mouse to area where visualisation is rendered, that objects immediately disappear.


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

psch.thinbasic.com

Patrice Terrier

QuoteJust one issue - when I select one of Charles's plugins and move mouse to area where visualisation is rendered, that objects immediately disappear.

This is because I forget to recompile Charles's  ;)

The solution: either recompile the plugins yourself or download the zip file again (it has been updated).

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

Charles Pegge

Patrice, Here is an updated plugin005 that maintains the correct aspect ratio when BassBox is stretched. It also contains a replacement for plugin 003 (003c) which uses the wood texture included.

The new 003, as you will see causes a slight problen with your excellent fireworks and fft plugins. It causes the particle textures to become enlarged, and is triggered when I setup the texture for 003 just after getting the  the image. Some of the texture parameters seem to persist, and may not be respecified when your plugins bind their textures.




Patrice Terrier

#117
Charles,

Please use "\" anti-slash instead of slash "/" to specify the folder name path, because I am using "\" to parse them, thank you.

I don't know what is the OpenGL parameter you are using that is causing havoc with other plugins.

The solution would be to reset everything to default, when switching from one plugin to another, however I don't know all the OpenGL settings that should be turned off.

Could you help on this?

The place where to reset the code in BassBox is there:


'// Reset OpenGL plugin
SUB BBP_Reset()
    LOCAL BBP AS BBPLUGIN
    BBP.Msg = %BBP_CREATE
    CALL BBP_Plugin(BBP)
    IF BBP.RenderTo = %BBP_OPENGL THEN
       CALL glDisable(%GL_BLEND)
       CALL glDisable(%GL_TEXTURE_2D)
       CALL glDisable(%GL_DEPTH_TEST)
    END IF
END SUB


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

Kent Sarikaya

Star Orion plays nicely and looks great with the newest plugin, really nice, thanks!!

Charles Pegge

Hi Patrice,

No, reseting those things did not work. And I have also made my texture binding identical to yours - using the same Opengl calls and settings

It's something quite subtle - corruption of texture mapping in some way. If I dont delete my texture, it shows up in your fireworks, so you get panels of wood instead of starry particles. But since you delete your texture ref before generating the texture, that should not happen anyway. But clicking a second time on 004 clears the problem.

A good night's sleep is needed.

Enjoyed Star Orion v. much. Great music.