MiniB3d for FreeBasic

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
ITomi
Posts: 113
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Postby ITomi » Jul 10, 2018 15:54

Hello!

I have a little problem. I would like build up a 3D world on the basis of a 2D map. Everything OK, all trees, enemies are visible - except the player's weapon.
Here is my code:

Code: Select all

dim as ubyte w,h,value,x,z
    select case which
    case 1
        restore level1
    end select
    read w
    read h
    x=1 : z=1
    for i as ubyte=1 to h
        for j as ubyte=1 to w
            read value
            select case value
            (...)
            case 3 'player
                positionentity camera,x*xspace,entityy#(camera),z*zspace '[b]!!![/b]
                weapon=createsprite(camera)
                scalesprite weapon,0.2,0.2
                entitytexture weapon,weapontex(0)
                positionentity weapon,entityx#(camera),entityy#(camera)-0.6,entityz#(camera)+1.1

If I remove the marked line with three exclamation marks, the weapon become visible at last, but in this case I can't place it, because its coordinates at 0,0,0, but I would like place it an other place. The camera already exists; I did it outside of that subprogram.
Haubitze
Posts: 30
Joined: May 20, 2016 8:42

Re: MiniB3d for FreeBasic

Postby Haubitze » Sep 29, 2018 12:20

hey there,

i have an problem with my CubeSphere. if i generate it from scratch it looks okay but if i cenerate it fom an own "cubemap" texture it is
craked. can anyone help me to fix that please?
i stole the code to generate the sphere from Krischan from the BB3D forum. but he only uses textures on it and dont modify the
vertex positions.

my texture looks this
Image
and the generator is this

Code: Select all

Function LoadCubeSphere(filename As String, scale As Single=0.25,mode As Integer = 0) As Any Ptr'only supports bmp
   

    Dim As Integer filenum, bmpwidth, bmpheight
    Dim As Any Ptr img

    '' open BMP file
    filenum = FreeFile()
    If Open( filename For Binary Access Read As #filenum ) <> 0 Then Return NULL

        '' retrieve BMP dimensions
        Get #filenum, 19, bmpwidth
        Get #filenum, 23, bmpheight

    Close #filenum

    '' create image with BMP dimensions
    img = ImageCreate( Abs(bmpwidth), Abs(bmpheight) )

    If img = NULL Then Return NULL

    '' load BMP file into image buffer
    If BLoad( filename, img ) <> 0 Then ImageDestroy( img ): Return NULL

   Dim segments As Integer=(Abs(bmpwidth)-1)
   'If segments>16 Then segments=16
   Dim As Integer s
   Dim As Integer x,y
   Dim As single vx, vy, vz
   Dim As single magnitude
   Dim As single  vertx, verty, vertz
   Dim As integer vertex
   
   Dim As Any Ptr mesh = CreateMesh()
   Dim As Any Ptr surf
   Dim As Single u,v
   
   For s = 1 To 6
      
      surf = CreateSurface(mesh)
      
      For y = 0 To segments
      
         For x = 0 To segments
            
            Select Case s
            
               Case 1:
                     vx = x - segments / 2
                     vy = segments / 2
                     vz = segments / 2 - y

               Case 2:
                     vx = x - segments / 2
                     vy = segments / 2 - y
                     vz = -segments / 2
                     
               Case 3:
                     vx = x - segments / 2
                     vy = -segments / 2
                     vz = y - segments / 2
                     
               Case 4:
                     vx = -segments / 2
                     vy = segments / 2 - y
                     vz = segments / 2 - x
                     
               Case 5:
                     vx = segments / 2
                     vy = segments / 2 - y
                     vz = x - segments / 2
                     
               Case 6:
                     vx = segments / 2 - x
                     vy = segments / 2 - y
                     vz = segments / 2
                     
            End Select
            
            If mode = 0 Then
            
               magnitude = Sqr(vx * vx + vy * vy + vz * vz)
               vertx = vx / magnitude
               verty = vy / magnitude
               vertz = vz / magnitude
               
            Else
            
               vx = vx / segments * 2
               vy = vy / segments * 2
               vz = vz / segments * 2
               
               vertx = vx * Sqr(1.0 - (vy * vy) / 2.0 - (vz * vz) / 2.0 + ((vy * vy) * (vz * vz) / 3.0))
               verty = vy * Sqr(1.0 - (vz * vz) / 2.0 - (vx * vx) / 2.0 + ((vz * vz) * (vx * vx) / 3.0))
               vertz = vz * Sqr(1.0 - (vx * vx) / 2.0 - (vy * vy) / 2.0 + ((vx * vx) * (vy * vy) / 3.0))
               
            EndIf
            
            u=(x * 1.0 / segments)/2.0
            v=(y * 1.0 / segments)/3.0
            Dim h As Single
            If s=1 Then
               vertz+=vertz*((Point((0.5+u)*bmpwidth,   ((2.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               verty+=verty*((Point((0.5+u)*bmpwidth,   ((2.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               vertx+=vertx*((Point((0.5+u)*bmpwidth,   ((2.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
            EndIf
            If s=3 Then
               vertz+=vertz*((Point((0.0+u)*bmpwidth,   ((2.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               verty+=verty*((Point((0.0+u)*bmpwidth,   ((2.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               vertx+=vertx*((Point((0.0+u)*bmpwidth,   ((2.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
            EndIf

            If s=2 Then
               vertz+=vertz*((Point((0.5+u)*bmpwidth,   ((1.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               verty+=verty*((Point((0.5+u)*bmpwidth,   ((1.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale '-z
               vertx+=vertx*((Point((0.5+u)*bmpwidth,   ((1.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
            EndIf

            If s=6 Then
               vertz+=vertz*((Point((0.0+u)*bmpwidth,   ((1.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               verty+=verty*((Point((0.0+u)*bmpwidth,   ((1.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               vertx+=vertx*((Point((0.0+u)*bmpwidth,   ((1.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
            EndIf

            If s=4 Then
               vertz+=vertz*((Point((0.0+u)*bmpwidth,   ((0.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               verty+=verty*((Point((0.0+u)*bmpwidth,   ((0.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               vertx+=vertx*((Point((0.0+u)*bmpwidth,   ((0.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
            EndIf

            If s=5 Then
               vertz+=vertz*((Point((0.5+u)*bmpwidth,   ((0.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               verty+=verty*((Point((0.5+u)*bmpwidth,   ((0.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
               vertx+=vertx*((Point((0.5+u)*bmpwidth,   ((0.0/3.0)+v)*bmpheight,img) And &hff)/256)*scale   '-z
            EndIf
            If s=4 Then vertextexcoords(surf,vertex,   0.0+u,   (0.0/3.0)+v)'-x
            If s=5 Then vertextexcoords(surf,vertex,   0.5+u,   (0.0/3.0)+v)'+x
            
            vertex = AddVertex(surf, vertx, verty, vertz, x * 1.0 / segments, y * 1.0 / segments)
            VertexNormal(surf,vertex,vertX,vertY,vertZ)
'todo fix the texture mapping
            u=(x * 1.0 / segments)/2.0
            v=(y * 1.0 / segments)/3.0
            If s=1 Then vertextexcoords(surf,vertex,   0.5+u,   (2.0/3.0)+v)'-z
            If s=3 Then vertextexcoords(surf,vertex,   0.0+u,   (2.0/3.0)+v)'+z
            '
            If s=2 Then vertextexcoords(surf,vertex,   0.5+u,   (1.0/3.0)+v)'-y
            If s=6 Then vertextexcoords(surf,vertex,   0.0+u,   (1.0/3.0)+v)'+y
            '
            If s=4 Then vertextexcoords(surf,vertex,   0.0+u,   (0.0/3.0)+v)'-x
            If s=5 Then vertextexcoords(surf,vertex,   0.5+u,   (0.0/3.0)+v)'+x
            
         Next
         
      Next
      
      For y = 0 To segments - 1
      
         For x = 0 To segments - 1
         
            AddTriangle(surf, y * (segments + 1) + x, y * (segments + 1) + x + 1, y * (segments + 1) + x + segments + 2)
            
            AddTriangle(surf, y * (segments + 1) + x, y * (segments + 1) + x + segments + 2, y * (segments + 1) + x + segments + 1)
            
         Next
         
      Next
      
   Next
   ImageDestroy img
   Return mesh
   
End Function


use it like so

Code: Select all

#Include once "fbgfx.bi"
#Include Once "crt.bi"
#Include Once "crt/math.bi"
#Include Once "crt/limits.bi"
#Include Once "gl\gl.bi"
#Include Once "gl\glu.bi"
#Include Once "gl\glext.bi"
#Include "inc/Openb3d.bi"
#Define Render_OpenGL




Using FB

ScreenRes( scrW, scrH, 32,2 , GFX_ALPHA_PRIMITIVES Or GFX_OPENGL Or GFX_MULTISAMPLE)
Graphics3D scrW, scrH, 32

Var cam=createcamera(0)
CameraViewport(cam,0,0,scrW, scrH)
CameraRange(cam,0.01,10000)
CameraClsColor(cam,16,16,32)

Var cubes = LoadCubeSphere(exepath + "/data/cubemap.bmp",0.1,1)



Var lights = CreateLight(1,cam)
LightColor(lights,128,128,255)
ambientLight(32,32,32)
positionentity lights,10,-10,-1

Var tex=LoadTexture( exepath + "/data/cubemap.bmp" )
entitytexture cubes,tex
entityfx cubes,2

   PositionEntity(cubes,0,0,3)

LightRange(lights,10000)


dim angle as single
Do
   GetMouse mx,my,,mb
   rotateentity cubes,0,angle,0
   angle+=0.5
   UpdateWorld
   RenderWorld
   ScreenSync
   Flip
loop until ( MultiKey( fb.sc_escape ))


salute
D.J.Peters
Posts: 7667
Joined: May 28, 2005 3:28

Re: MiniB3d for FreeBasic

Postby D.J.Peters » Dec 22, 2018 10:41

@angros47

in ShadowObject::Update(Camera* Cam) you overwrite the current cls mode of the camera but never restore the old mode.

That means the user of the lib must update the cls mode for all active cameras every frame !

As a small fix you can declare (for internal use only) in "camera.h"

Code: Select all

void CameraGetClsMode(int &color,int &zbuffer);
and add in "camera.cpp"

Code: Select all

void Camera::CameraGetClsMode(int &color,int &zbuffer){
  color=cls_color;
  zbuffer=cls_zbuffer;
}
and use it in shaddow.cpp

Code: Select all

void ShadowObject::Update(Camera* Cam){
  vector<Light*>::iterator it;
  // !!! save current cls mode
  int old_cls_color;
  int old_cls_zbuffer;
  Cam->CameraGetClsMode(old_cls_color, old_cls_zbuffer);

  for(it=Light::light_list.begin();it!=Light::light_list.end();++it){
    Light* Light=*it;
    if (Light->hide==true || Light->cast_shadow==false)
      continue;

    light_x = Light->EntityX(true) * (1 + parallel * 1);
    light_y = Light->EntityY(true) * (1 + parallel * 1);
    light_z = Light->EntityZ(true) * (1 + parallel * 1);
    // overwrite cls mode
    Cam->CameraClsMode(false,false);
    Cam->Update();

    list<ShadowObject*>::iterator it2;
    for(it2=shadow_list.begin();it2!=shadow_list.end();it2++){
      ShadowObject* S=*it2;
      if (S->Parent->hide==false && Light->EntityDistance(S->Parent) < 1/Light->range) {
        VolumeLength = (Cam->range_far - S->Parent->EntityDistance(Cam)) / (S->Parent->EntityDistance(Light) + abs(S->Parent->cull_radius));
       S->ShadowMesh->reset_bounds = true;
       S->ShadowMesh->GetBounds();
       S->UpdateCaster();
       S->Render = true;
      } else {
       S->Render = false;
       }
    }
    // overwrite cls mode again why ?
    Cam->CameraClsMode(false,false);
    ShadowRenderWorldZFail();
  }
  // !!! how ever on end restore the cls mode
  Cam->CameraClsMode(old_cls_color, old_cls_zbuffer);
}
Haubitze
Posts: 30
Joined: May 20, 2016 8:42

Re: MiniB3d for FreeBasic

Postby Haubitze » May 10, 2019 16:34

i made a function to create a spherized Cube. i hope anyone find it usefull.
only problem i cant solve is the texturemapping so you have to solve it by your own :/

Code: Select all

' ----------------------------------------------------------------------------
' Creates a spherized Cube
' ----------------------------------------------------------------------------
Function CreateCubeSphere(segments As Integer = 16, mode As Integer = 0) As Any ptr
   If segments>255 Then segments=255
   If segments<1 Then segments=1
   Dim As Integer s
   Dim As Integer x,y
   Dim As single vx, vy, vz
   Dim As single magnitude
   Dim As single  vertx, verty, vertz
   Dim As integer vertex

   Dim As Any Ptr mesh = CreateMesh()
   Dim As Any Ptr surf
   Dim As Single u,v

   For s = 1 To 6
      surf = CreateSurface(mesh)
      For y = 0 To segments
         For x = 0 To segments
            Select Case s
               Case 1:
                  vx = x - segments / 2
                  vy = segments / 2
                  vz = segments / 2 - y
               Case 2:
                  vx = x - segments / 2
                  vy = segments / 2 - y
                  vz = -segments / 2
               Case 3:
                  vx = x - segments / 2
                  vy = -segments / 2
                  vz = y - segments / 2
               Case 4:
                  vx = -segments / 2
                  vy = segments / 2 - y
                  vz = segments / 2 - x
               Case 5:
                  vx = segments / 2
                  vy = segments / 2 - y
                  vz = x - segments / 2
               Case 6:
                  vx = segments / 2 - x
                  vy = segments / 2 - y
                  vz = segments / 2
            End Select

            If mode = 0 Then
               magnitude = Sqr(vx * vx + vy * vy + vz * vz)
               If magnitude<0.000001 Then magnitude=1'0.000001

               vertx = vx / magnitude
               verty = vy / magnitude
               vertz = vz / magnitude
            Else
               vx = vx / segments * 2
               vy = vy / segments * 2
               vz = vz / segments * 2

               vertx = vx * Sqr(1.0 - (vy * vy) / 2.0 - (vz * vz) / 2.0 + ((vy * vy) * (vz * vz) / 3.0))
               verty = vy * Sqr(1.0 - (vz * vz) / 2.0 - (vx * vx) / 2.0 + ((vz * vz) * (vx * vx) / 3.0))
               vertz = vz * Sqr(1.0 - (vx * vx) / 2.0 - (vy * vy) / 2.0 + ((vx * vx) * (vy * vy) / 3.0))
            EndIf
            vertex = AddVertex(surf, vertx, verty, vertz, x * 1.0 / segments, y * 1.0 / segments)
            VertexNormal(surf,vertex,vertX,vertY,vertZ)
            'todo fix the texture mapping
            u=(x * 1.0 / segments)'/2.0
            v=(y * 1.0 / segments)'/3.0
            
            If u>1 Then u-=1.0
            If v>1 Then v-=1.0
            If u<0 Then u+=1.0
            If v<0 Then v+=1.0
            
            vertextexcoords(surf,vertex,   u,   v)
            'If s=1 Then vertextexcoords(surf,vertex,   0.5+u,   (2.0/3.0)+v)'-y
            'If s=3 Then vertextexcoords(surf,vertex,   0.0+u,   (2.0/3.0)+v)'+y
            ''
            'If s=6 Then vertextexcoords(surf,vertex,   0.5+u,   (1.0/3.0)+v)'-z
            'If s=2 Then vertextexcoords(surf,vertex,   0.0+u,   (1.0/3.0)+v)'+z
            ''
            'If s=4 Then vertextexcoords(surf,vertex,   0.0+u,   (0.0/3.0)+v)'-x
            'If s=5 Then vertextexcoords(surf,vertex,   0.5+u,   (0.0/3.0)+v)'+x
         Next
      Next

      For y = 0 To segments - 1
         For x = 0 To segments - 1
            AddTriangle(surf, y * (segments + 1) + x, y * (segments + 1) + x + 1, y * (segments + 1) + x + segments + 2)
            AddTriangle(surf, y * (segments + 1) + x, y * (segments + 1) + x + segments + 2, y * (segments + 1) + x + segments + 1)
         Next
      Next
   Next
   Return mesh
End Function


salute
angros47
Posts: 1443
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Postby angros47 » May 11, 2019 18:13

Nicely done!

Actually, to texture a cube sphere, you would need 6 different textures, one for each face, or you can "pack" them into a single texture, in a cube map (either a cross-shaped picture, or a "strip" made of 6 square textures). If you use separate textures, you can then apply each one to each face using PaintSurface. Otherwise, you have to decide how faces will be packed in the strip, and you will have to map the UV coordinates according to that.
Haubitze
Posts: 30
Joined: May 20, 2016 8:42

Re: MiniB3d for FreeBasic

Postby Haubitze » May 12, 2019 15:14

hi angros47,

i have a question about your 2d fbgfx patch for opengl.
if you know i use OpenB3D, i also use sGUI from Muttonhead and i have patched the sGUI to work with the old 2d.bi.
the last version of sGUI uses now 32 bit images mostly all cleared to rgba(0,0,0,0) and then painted with sGUI stuff.
if i try your patch in manual sync mode i only get the 3D scene, if i use automatic sync mode i only get the sGUI on the screen.

i use FB 1.06.0 32bit and 64bit, can you tell me eventualy what i make wrong or if the patch does not working with OpenB3D?

thanks and salute


Edit: here the new code for the spheroized cube, now with texturecoordinates.

Code: Select all

' ----------------------------------------------------------------------------
' Creates a spherized Cube
' ----------------------------------------------------------------------------
Function CreateCubeSphere(segments As Integer = 16, mode As Integer = 0,texture_mode as Integer = 1) As Any ptr
   If segments>255 Then segments=255
   If segments<1 Then segments=1
   If mode<0 Then mode=0
   If mode>1 Then mode=1
   If texture_mode<0 Then texture_mode=0
   If texture_mode>1 Then texture_mode=1
   
   Dim As Integer s
   Dim As Integer x,y
   Dim As single vx, vy, vz
   Dim As single magnitude
   Dim As single  vertx, verty, vertz
   Dim As integer vertex

   Dim As Any Ptr mesh = CreateMesh()
   Dim As Any Ptr surf
   Dim As Single u,v

   For s = 1 To 6
      surf = CreateSurface(mesh)
      For y = 0 To segments
         For x = 0 To segments
            Select Case s
               Case 1:
                  vx = x - segments / 2
                  vy = segments / 2
                  vz = segments / 2 - y
               Case 2:
                  vx = x - segments / 2
                  vy = segments / 2 - y
                  vz = -segments / 2
               Case 3:
                  vx = x - segments / 2
                  vy = -segments / 2
                  vz = y - segments / 2
               Case 4:
                  vx = -segments / 2
                  vy = segments / 2 - y
                  vz = segments / 2 - x
               Case 5:
                  vx = segments / 2
                  vy = segments / 2 - y
                  vz = x - segments / 2
               Case 6:
                  vx = segments / 2 - x
                  vy = segments / 2 - y
                  vz = segments / 2
            End Select

            If mode = 0 Then
               magnitude = Sqr(vx * vx + vy * vy + vz * vz)
               If magnitude<0.000001 Then magnitude=0.000001

               vertx = vx / magnitude
               verty = vy / magnitude
               vertz = vz / magnitude
            Else
               vx = vx / segments * 2
               vy = vy / segments * 2
               vz = vz / segments * 2

               vertx = vx * Sqr(1.0 - (vy * vy) / 2.0 - (vz * vz) / 2.0 + ((vy * vy) * (vz * vz) / 3.0))
               verty = vy * Sqr(1.0 - (vz * vz) / 2.0 - (vx * vx) / 2.0 + ((vz * vz) * (vx * vx) / 3.0))
               vertz = vz * Sqr(1.0 - (vx * vx) / 2.0 - (vy * vy) / 2.0 + ((vx * vx) * (vy * vy) / 3.0))
            EndIf
            vertex = AddVertex(surf, vertx, verty, vertz, x * 1.0 / segments, y * 1.0 / segments)
            VertexNormal(surf,vertex,vertX,vertY,vertZ)
           
            if texture_mode=0 then
            'todo fix the texture mapping
            u=(x * 1.0 / segments)/2.0
            v=(y * 1.0 / segments)/3.0
            
            If u>1 Then u-=1.0
            If v>1 Then v-=1.0
            If u<0 Then u+=1.0
            If v<0 Then v+=1.0
            
            If s=5 Then vertextexcoords(surf,vertex,   0.5+u,   (2.0/3.0)+v)'right
            If s=4 Then vertextexcoords(surf,vertex,   0.0+u,   (2.0/3.0)+v)'left
            ''
            If s=6 Then vertextexcoords(surf,vertex,   0.5+u,   (0.0/3.0)+v)'back
            If s=2 Then vertextexcoords(surf,vertex,   0.0+u,   (0.0/3.0)+v)'front
           
            If s=3 Then vertextexcoords(surf,vertex,   0.5+u,   (1.0/3.0)+v)'down
            If s=1 Then vertextexcoords(surf,vertex,   0.0+u,   (1.0/3.0)+v)'up
           
            elseif texture_mode=1 then
            u=(x * 1.0 / segments)/6.0
            v=(y * 1.0 / segments)
             If s=5 Then vertextexcoords(surf,vertex,   (5.0/6.0)+u,   v)'right
            If s=4 Then vertextexcoords(surf,vertex,   (4.0/6.0)+u,   v)'left
            ''
            If s=6 Then vertextexcoords(surf,vertex,   (1.0/6.0)+u,   v)'back
            If s=2 Then vertextexcoords(surf,vertex,   (0.0/6.0)+u,   v)'front
           
            If s=3 Then vertextexcoords(surf,vertex,   (3.0/6.0)+u,   v)'down
            If s=1 Then vertextexcoords(surf,vertex,   (2.0/6.0)+u,   v)'up
             
            endif
            ''
         Next
      Next

      For y = 0 To segments - 1
         For x = 0 To segments - 1
            AddTriangle(surf, y * (segments + 1) + x, y * (segments + 1) + x + 1, y * (segments + 1) + x + segments + 2)
            AddTriangle(surf, y * (segments + 1) + x, y * (segments + 1) + x + segments + 2, y * (segments + 1) + x + segments + 1)
         Next
      Next
   Next
   Return mesh
End Function


it supports 2 cubemap variants like the following ones.
Image
Image
angros47
Posts: 1443
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Postby angros47 » May 12, 2019 18:35

Hard to tell where is the issue without a code example. By the way, with OpenB3D you must use manual sync mode. Also, try removing the RenderWorld command and using only the Flip command to see if the 2d screen appears, in that case

Return to “Libraries”

Who is online

Users browsing this forum: No registered users and 3 guests