Looking for help...

Vircop

Member
Licensed User
Longtime User
Hello, i'm looking for someone who is willing to help me with "Off Screen Rendering". I have created a sprite class, a image class, a own graphics class etc. but somehow it's not working properly. Because that would be too much to share everything here as code i would like to have a contact to someone who is interested in this topic. Mybe we can exchange a couple of ideas...

For example i'm using low level operations to manipulate the graphics. Here's a short part of my image class that you get some idea:

B4X:
Sub Class_Globals
   Dim c_w          As Int
   Dim c_h          As Int
   Dim c_depth       As Int
   Dim c_pixels()       As Int
   Dim c_pixels_8()    As Byte
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub

Public Sub setimage24(pixels() As Int, w As Int, h As Int)
   Log("-> image::setimage24 (" & w & " x " & h & ")")
   c_w = w
   c_h = h
   c_depth = 24
   c_pixels = pixels
   c_pixels_8 = Null
End Sub

Public Sub setimage8(pixels_8() As Byte, w As Int, h As Int)
   Log("-> image::setimage8 (" & w & " x " & h & ")")
   c_w = w
   c_h = h
   c_depth = 8
   c_pixels = Null
   c_pixels_8 = pixels_8
   Log(" Anzahl: " & c_pixels_8.Length )
   Log(" Test1: " & c_pixels_8(1) )
End Sub

Public Sub image24( jimg As Bitmap, force_depth As Int ) ' OK!
   Dim I As Int
   Dim x As Int
   Dim y As Int
   Dim s As Int
   Dim r As Byte
   
   c_w = jimg.Width
   c_h = jimg.Height
   c_depth = force_depth

   Dim c_pixels(c_w * c_h) As Int
   
   ' Workaround for the java function pixelgrabber
   Log("=== Pixelgrabber (" & c_w & "x" & c_h & ") " & force_depth & "bpp ===")
   
   s = 0
   For y = 0 To c_h-1
      For x = 0 To c_w-1
         c_pixels(s) = jimg.GetPixel(x,y)
         s = s +1
      Next
   Next
   If force_depth = 8 Then
      Log("Switching into 8 bit color depth image size: " & c_w & "x" & c_h)
      Dim c_pixels_8(c_w * c_h) As Byte
      I = 0
      For y = 0 To c_h-1
         For x = 0 To c_w-1
            r = Bit.And(c_pixels(I),0x000000FF)
            If c_pixels(I) <> 0 Then
               'Log("c_pixel("&I&") = " & c_pixels(I))
            End If
            c_pixels_8(I) = r ' Set Pixel
            If c_pixels_8(I) <> 0 Then
               'Log("Testing..")
            End If
            I = I + 1 ' Next!
         Next
      Next
      c_pixels = Null ' Delete 24Bit Pixel Array because we have now 8 Bit
   End If
End Sub

Public Sub imagexx(jimg As Bitmap) ' Wrapper for use without specific depth
   image24(jimg,24)
End Sub
 

Vircop

Member
Licensed User
Longtime User
And here is one of the main class funtion from graphics

B4X:
Sub image_draw( img As image, sx As Int, sy As Int, sw As Int, sh As Int, x As Int, y As Int, col1 As Int, col2 As Int )
   Dim iox, ioy, ix, iy As Int
   Dim iw, ih, icw, ich As Int
   Dim sstride As Int
   Dim Var1, Var2, Var3, Var4, Var5 As Int
   
   Dim des() As Int
   Dim src() As Int

   'Log (" IMG: " & img.c_w )
   
   sstride = img.c_w
   iox    = sx
   ioy    = sy
   iw       = sw
   ih       = sh
   
   'Log("image_draw: c_w = " & c_w & " c_h = " & c_h & " - x = " & x & " y = " & y)
   If (x >= c_w) OR (y >= c_h) Then
      Log("image_draw: Return #1!")
      Return
   End If
   
   If (x + iw <= 0) OR (y + ih <= 0) Then
      Log("image_draw: Return #2!")
      Return
   End If
   
   If ( x + iw > c_w ) Then
      icw = c_w - x
   Else
      icw = iw
   End If
   
   If ( y + ih > c_h ) Then
      ich = c_h - y
   Else
      ich = ih
   End If
   
   If ( x < 0 ) Then
      iox = iox - x
      icw = icw + x
      x = 0
   End If

   If ( y < 0 ) Then
      ioy = ioy - y
      ich = ich + y
      y = 0
   End If

   ' Hier...
   'Log (" Debug1: " & img.c_pixels_8.Length)
   des = c_pixels
   src = img.c_pixels
   
   Dim d_i, d_ii As Int
   Dim s_i, s_ii As Int
   
   s_i = ioy * sstride
   d_i = y * c_w

   If ( img.c_depth = 8 ) Then
      'Log("image_draw: depth = 8")

      ' ---------------------
      Dim src8() As Byte
      src8 = img.c_pixels_8
      'Log("img8: " & img.c_pixels_8.Length)
      ' ---------------------
      
      If ( col1 <> 0 ) Then
         If ( col2 <> 0 ) Then
            Dim r1, g1, b1 As Int
            Dim r2, g2, b2 As Int
            Dim dr, dg, db As Int
            Dim ooh As Int
            
            ooh = 65536 / sh
            
            r1 = Bit.ShiftRight(Bit.And(col1,0x00ff0000), 16)
            g1 = Bit.ShiftRight(Bit.And(col1,0x0000ff00), 8)
            b1 = Bit.ShiftRight(Bit.And(col1,0x000000ff), 0)
            r2 = Bit.ShiftRight(Bit.And(col2,0x00ff0000), 16)
            g2 = Bit.ShiftRight(Bit.And(col2,0x0000ff00), 8)
            b2 = Bit.ShiftRight(Bit.And(col2,0x000000ff), 0)
            
            dr = (r2 - r1) * ooh
            dg = (g2 - g1) * ooh
            db = (b2 - b1) * ooh
            
            r1 = Bit.ShiftLeft(r1,16)
            g1 = Bit.ShiftLeft(g1,16)
            b1 = Bit.ShiftLeft(b1,16)
            
            For iy = ich To 0 Step -1
               Dim row_col As Int
               s_ii = s_i + iox
               d_ii = d_i + x
               s_i = s_i + sstride 
               d_i = d_i + c_w
               
               Var1 = Bit.And( r1, 0x00ff0000 )
               Var2 = Bit.And( Bit.ShiftRight( g1, 8 ), 0x0000ff00 )
               Var3 = Bit.And( Bit.ShiftRight( b1, 16 ), 0x000000ff )
               Var4 = Bit.Or(Var1,Var2)
               row_col = Bit.Or(Var4,Var3)
               
               For ix = icw To 0 Step -1
                  If src8(s_ii) <> 0 Then
                     des(d_ii) = row_col
                     'Log("RowCol " & row_col)
                  End If
                  s_ii = s_ii + 1
                  d_ii = d_ii + 1
               Next
               
               r1 = r1 + dr
               g1 = g1 + dg
               b1 = b1 + db
            Next
         Else
            For iy = ich To 0 Step -1
               s_ii = s_i + iox
               d_ii = d_i + x
               s_i = s_i + sstride
               d_i = d_i + c_w
               
               For ix = icw To 0 Step -1
                  Dim c As Int
                  'Log ("Debug : " & src8(1))
                  c = Bit.And(src8(s_ii),0x000000ff) 
                  s_ii = s_ii + 1
                  If ( c <> 0 ) Then
                     des(d_ii) = col1
                  End If
                  d_ii = d_ii + 1
               Next
            Next
         End If ' col2 <> 0
         
      Else
         Log("image_draw:24bit: ich=" & ich & " icw=" &icw)
         For iy = ich To 0 Step - 1
            s_ii = s_i + iox
            d_ii = d_i + x
            s_i = s_i + sstride
            d_i = d_i + c_w
            For ix = icw To 0 Step -1
               Dim c As Int
               c = Bit.And(src8(s_ii),0x000000ff) : s_ii = s_ii + 1
               If ( c <> 0 ) Then
                  ' des[d_ii] = c | (c << 8) | (c << 16)
                  Log(" TODO!!!!!!!!!!! ")
                  des(d_ii) = 0
               End If
               d_ii = d_ii + 1
            Next 
         Next
      End If ' col1 <> 0

   Else
      Log("image_draw: depth = 24")
      For iy = ich To 0 Step -1
         s_ii = s_i + iox
         d_ii = d_i + x
         s_i = s_i + sstride
         d_i = d_i + c_w   
         For ix = icw To 0 Step -1
            Dim c As Int
            c = src(s_ii) : s_ii = s_ii + 1
            Log("C=" & c)
            If Bit.And(c, 0xff000000) = 0xff000000 Then
               des(d_ii) = c
               Log("SetBit")
            End If
            d_ii = d_ii + 1
         Next
      Next
      
      
   End If

   c_pixels = des
   'Log("kasldfjkejw " & des.Length)
   
   'Dim x1 As Int
   'For x1 = 0 To des.Length-1
   '   If des(x1) <> 0 Then
   '      Log(" Pixel: " & des(x1))
   '   End If
   'Next
End Sub
 
Upvote 0

Vircop

Member
Licensed User
Longtime User
Update: I think i found some strange behavior... I have a Paint function that actually constructs out of an (int) color array a bitmap that i should then draw.

I put a couple of debug stuff inbetween and there are pixels with different color than black. However, it's just drawing a black bitmap on the screen..

B4X:
Sub mypaint( g As graphics )
   Dim a As Bitmap
        Log("[MAIN]::mypaint()")

        lap_draw( g ) <--- Here text is written on the buffer

   a = btmpex.createBitmap5(g.c_pixels, g.c_w, g.c_h, "RGB_565")
   Dim mn As Long
   Dim mm As Int
   For mn = 0 To g.c_pixels.Length-1
      mm = g.c_pixels(mn)
      If mm <> 0 Then 
         Log("Pixel: " & mn & " = " & mm)
      End If
   Next

   Log("Rect = " & myrect.Right)
   can1.DrawBitmap(a,Null,myrect)

For some strange reason can1.DrawBitmap (can1 is Canvas) doesn't display anything...
 
Upvote 0

Vircop

Member
Licensed User
Longtime User
How do get with B4A a random number between 0.0 and 1.0 (as float)?

In java is that Math.random() as far as i remember. (yes i know there is RND for int but is there something for float as well?)
 
Upvote 0

Vircop

Member
Licensed User
Longtime User
Thanks! I'm almost done with the GFX Stuff now and it works. But...

How can i use vectors in B4A?

for example:

Vector c_vehicles;

...

c_vehicles.removeAllElements()

...

Dim v as vehicle

v.Initialize( c_start_frame_sprite, (150+-500) * 1024, 150, 0, false )

c_vehicles.addElement( v )

etc..
 
Upvote 0

Vircop

Member
Licensed User
Longtime User
Hi Klaus,

i had a try with List but no luck. The Problem is the following:

At the Beginning i declare v_vehicles as List.
c_vehicles is a class that holds data.

Now i try to add the c_vehicle objects to that list via:

B4X:
Dim x As vehicle

x.vehicle_init(c_start_frame, (150+-500)*1024, 150, 0, False)    
 
v_vehicles.Add(x) 

x.vehicle_init(c_rqueen1, (150+-610)*1024, 100, 0, False)    

v_vehicles.Add(x)

So basically i add several elements of class c_vehicle. (just 2 here as example)

However, if i try to get the data later via

B4X:
Dim testv As vehicle
testv = v_vehicles.Get(0) ' Should read the first vehicle data
Log("testv = " & testv.c_start_pos )

i ALWAYS get the data from the last added vehicle, no matter what index i use for .Get( idx )

For that said example it should print "150" but it always prints "100" - even if i use .Get(1) instead of .Get(0)

Very strange...
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
You must Dim x As vehicle each time:
B4X:
Dim x As vehicle
x.vehicle_init(c_start_frame, (150+-500)*1024, 150, 0, False)     
v_vehicles.Add(x) 

Dim x As vehicle
x.vehicle_init(c_rqueen1, (150+-610)*1024, 100, 0, False)     
v_vehicles.Add(x)
This is needed to initiate each time a new instance of x otherwise you add always the same instance and this one holds the last value you gave it.

Best regards.
 
Upvote 0
Top