MiniB3d for FreeBasic

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
Gunslinger
Posts: 111
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

Yes i found a other maybe bug.
i scale a sprite with

Code: Select all

scalesprite tmp, 10,10
now very big and problems happening around screen edge.
sprite disappears when center is about 10% of screen.

Also with scale 2 x 2 had problem at like 50% of screen disappearing.
maybe scalesprite is only for making smaller than 1?
also seem to crash sometimes can be something else making random crash.
angros47
Posts: 2369
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

It's not a bug... ScaleSprite doesn't affect frustum culling.
Try with

Code: Select all

MeshCullRadius tmp, 10
About the "crash sometimes" there are thousands of possible causes, so it's almost impossible to find the causes if the behavior is not consistent
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

Hello everybody!

I try to make a small FPS game with openb3d.bi, but I have a problem with imagecreate() command, because it seems create always similar images.
So, in my progam I make a player's HUD as follows:

Code: Select all

#Include "openb3d.bi"
#include "fbgfx.bi"
Using FB

const ksz=800 : const km=600

ScreenRes ksz,km,32,,&h10002
Graphics3d ksz,km
(...)
imagetohud=imagecreate(128,32,32)

hudimage=CreateSprite(camera)
MoveEntity hudimage,3.8,2.5,5 'Upper right corner of the screen.
hudmessagetex=CreateTexture(128,32)
EntityTexture hudimage,hudmessagetex

Do
(...)
	Line imagetohud,(0,0)-(127,31),RGB(150,10,0),BF
	draw string imagetohud,(1,1),"Health: "+str(player.health)
	BufferToTex hudmessagetex,imagetohud,1

	updateworld
        renderworld
        Flip
Loop Until MultiKey(sc_q)
But it is produce a blue square in all cases, I give any value, always with same side lengths.
I would like a screen-width HUD in my game, but I don't know the screen width (and height) value either in 3D world.
angros47
Posts: 2369
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

Two things: the line:

Code: Select all

BufferToTex hudmessagetex,imagetohud,1
passes a pointer to the header of a FreeBasic image to OpenB3D, that instead expects a raw pixel buffer. A FreeBasic image contains the pixel buffer, but before it there is a small header (32 bytes) that describes the image format, and you should skip. You didn't include the DIM that declares the variable "hudmessagetex", if it is an "ANY PTR", you should use:

Code: Select all

BufferToTex hudmessagetex,imagetohud+32,1
Or the image will be shifted, in the texture

Also, seeing the line:

Code: Select all

Line imagetohud,(0,0)-(127,31),RGB(150,10,0),BF
I assume you planned to make the hud as a red square: unfortunately, FreeBasic uses the formar BGR, for the images, while OpenB3d expects RGB, so the red and blue channels are swapped.

So, try:

Code: Select all

Line imagetohud,(0,0)-(127,31),RGB(0,10,150),BF
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

Thanks, Angros47, I tried it, but unfortunately the size of the background image of the HUD is unchanged. It is a square in the corner. But I still experimenting with it.
And yes, the "hudmessagetex" is an ANY PTR.
But more two small questions:
1. The HUD image placed in front of the camera:

Code: Select all

hudimage=CreateSprite(camera)
MoveEntity hudimage,3.8,2.5,5
But sometimes instances in the game (e.g. trees, enemies) are cover it. How can I place the HUD before everything with its strings and images?
2. I can't check whether an enemy is in front of the camera?
I try this code:

Code: Select all

if (entityyaw#(enemy(i).img)>=(entityyaw#(camera)-180)-45) and (entityyaw#(enemy(i).img)<=(entityyaw#(camera)-180)+45) then
  moveentity enemy(i).img,0,0,enemy(i).speed*deltatime
end if
So, is entityyaw() for this? Or how can I determine this condition in the 3D world?
angros47
Posts: 2369
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

1) the command EntityOrder is what you need:

Code: Select all

EntityOrder hudimage,-10
2)There is the command EntityInView for that

Code: Select all

if entityInView(enemy(i).img, camera) then .....
Or you want to know if the entity is exactly in front of the camera, not just in the field of view?
In that case, you might need either DeltaYaw and DeltaPitch, or CameraProject
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

Thank you for your answers, Angros47, I will try these.
Unfortunately I'm not yet completely familiar with coordinates in 3D world (e.g. what is 1 unit in 3D in pixels on the screen?), therefore I have to practice a lot what to put where.
angros47
Posts: 2369
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

You are welcome. Coordinates in 3D are completely different from coordinates in 2D, and they are mapped on the screen according to distance from the camera, camera zoom factor and other parameters: so, the length of 1 unit in 3d can be of several pixels if the object is close to the camera, or less than one pixel if it's distant.
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

I have already managed to do many things, but there are some things I don't understand:

1. Some element in the game are not real 3D objects, but 2D sprites, and these sprites would change their sub-images according to their direction. Just like in game Doom I. and II.
But how can I get the actual direction of a game object?
I tried so:

Code: Select all

subimg(0)=monsterrunback(enemy(e).subimg)
subimg(1)=monsterrunbackright(enemy(e).subimg)
subimg(2)=monsterrunright(enemy(e).subimg)
subimg(3)=monsterrunforwardright(enemy(e).subimg)
subimg(4)=monsterrunforward(enemy(e).subimg)
subimg(5)=monsterrunforwardleft(enemy(e).subimg)
subimg(6)=monsterrunleft(enemy(e).subimg)
subimg(7)=monsterrunbackleft(enemy(e).subimg)
tex=subimg(int(entityyaw#(enemy(e).img)*8/360)) '???

entitytexture enemy(e).img,tex
But I get strange results, and besides, when the enemy shoot based on enemy's direction, the bullets often go into wrong direction, so probably I set the direction wrong:

Code: Select all

turnentity enemybullet(numofenbullets).img,entitypitch#(enemy(e).img),entityyaw#(enemy(e).img),entityroll#(enemy(e).img)
Which command gives me the direction of the object?

2. I tried to make a simple program to check these things (angle, direction, etc.), but I can't display the results as a text on the screen. I can display texts hardly and I can't clear the HUD when I write onto it.
Besides, I tried to rotate the cone towards sphere with its tip, but I couldn't done it.

Code: Select all

#Include "openb3d.bi"
#include "fbgfx.bi"

Using FB

ScreenRes 800,600,32,,&h10002
Graphics3d 800,600

dim shared as any ptr hudimage,hudstringtex,camera,imgtohud,cone,sphere
dim shared as integer pitch,yaw,roll

camera=createCamera()
var light=createLight()

cone=CreateCone(16)
PositionEntity cone,0,0,5
sphere=CreateSphere(16)
PositionEntity sphere,-3,0,5

imgtohud=imagecreate(128,32,32)

hudimage=CreateSprite(camera)
MoveEntity hudimage,3.8,2.5,5
EntityOrder hudimage,-1
hudstringtex=CreateTexture(128,32)
EntityTexture hudimage,hudstringtex

Do
        roll=0
        pitch=0
        yaw=0
        if multikey(sc_up) then
            roll+=1
        end if
        if multikey(sc_down) then
            roll-=1
        end if
        if multikey(sc_left) then
            pitch-=1
        end if
        if multikey(sc_right) then
            pitch+=1
        end if
        if multikey(sc_e) then
            yaw+=1
        end if
        if multikey(sc_d) then
            yaw-=1
        end if
        
        'TurnEntity cone,pitch,yaw,roll
        
        do
            turnentity cone,0,deltayaw#(cone,sphere),0
        loop until (deltayaw#(cone,sphere)>-8) and (deltayaw#(cone,sphere)<8)
        
        draw string imgtohud,(1,1),"P.: "+str(pitch)
        BufferToTex hudstringtex,imgtohud,1
        draw string imgtohud,(1,10),"Y: "+str(int(entityyaw#(cone)))
        BufferToTex hudstringtex,imgtohud,1
        draw string imgtohud,(1,20),"R: "+str(roll)
        BufferToTex hudstringtex,imgtohud,1
        
        updateworld
        renderworld
        Flip
Loop Until MultiKey(sc_q)
So, my questions:

1. How can I determine the right directions of the game objects?
2. How can I set the right subimage to the game objects based on those directions?
3. What is the simplest and best way of display texts on the screen? Can I clear the buffer of hudstringtex or imgtohud somehow?
angros47
Posts: 2369
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

The commands EntityPitch, EntityYaw and EntityRoll return the pitch/yaw/roll, but they don't take account of the position of the camera: if the camera is at the side of an object, it will see one side, if it's behind, it will see the back, even if the object has not rotated.

I think the commands you are looking for are DeltaYaw and DeltaPitch (there is no DeltaRoll, it's not a mistake). Those commands return the angles an object should be rotated to face another object. Use them on the enemy, adding the camera as parameter, and I think with some attempts you should achieve what you need.

About your last example: the reason why the cone is not pointed at the sphere is that by default the cone has the tip that goes up, not forward: so, your program will just rotate the base of the cone, and no difference is visible. All you need to do is to rotate the mesh (attention: the mesh, not the entity) so the tip will be forward. Basically, after the "CreateCone" command, add the line:

Code: Select all

rotatemesh cone,-90,0,0
To clear the HUD, just use something like:

Code: Select all

	line imgtohud, (0,0)-(128,32),0,bf
It draws a black full rectangle over the whole image buffer, erasing it.
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

Thank you for your helpful suggestions, Angros47!
Now, I go back to coding and try these.
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

Okay, only one question remains (I hope... :mrgreen: ):
I would like align a 2D sprite exactly to the bottom of the screen, according to height of this sprite, but I don't know the exact height size of that sprite in 3D space.
As you can see in my piece of code below, I tried to add a small number (-0.6) in the positionentity command, but it results a thin, empty space below it.
I need an exact value that gives me the height size of the sprite, that determines the distance from the bottom of the screen.
Or should I use Put command to draw a 2D sprite? Is this possible in 3D?

Code: Select all

weapon=createsprite(camera)
scalesprite weapon,0.2,0.2
entitytexture weapon,machineguntex(0)
positionentity weapon,entityx#(camera),entityy#(camera)-0.6,entityz#(camera)+1.1
angros47
Posts: 2369
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

There is no command to do what you need, since the size of the sprite is affected by the distance and by the camera zoom factor. To place it exactly in 2D you should disable 3d, using some direct OpenGL commands, and it's not so easy.

By the way, you don't need to use:

Code: Select all

positionentity weapon,entityx#(camera),entityy#(camera)-0.6,entityz#(camera)+1.1
instead, use:

Code: Select all

positionentity weapon,0, -.6,1
The sprite has the camera as parent, so its position is already related to the camera (unless you use the "global" flag, the last ",1" in your code)

To use PUT and other 2d commands you would need, before you set the screen mode, to use the command "screencontrol 150,1" (that allows to mix OpenGL and FreeBasic graphics), and then, between the RenderWorld command and the Flip command, you can put some commands to restore the 2d mode, with something like:

Code: Select all

	renderworld
  glColor4f(1.0, 1.0, 1.0, 1.0)
  glDisable(GL_CULL_FACE)
  glDisable(GL_NORMALIZE)
  glActiveTexture(GL_TEXTURE0)
  glClientActiveTexture(GL_TEXTURE0)
  glDisable(GL_DEPTH_TEST)
	glBindBuffer(GL_ARRAY_BUFFER,0)
  glEnable(GL_BLEND)
  glEnable(GL_ALPHA_TEST)
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)

	flip
	glEnableClientState(GL_NORMAL_ARRAY)
Mixing OpenGL and 2d graphics has always been a pain, unfortunately.
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

Thanks for your advice, Angros47!
I tried place the sprite so:

Code: Select all

positionentity weapon,0, -.6,1
and it seems much better in terms of location, but sometimes produces blinking.
Once more, much-much thanks for your advice!
ITomi
Posts: 179
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: MiniB3d for FreeBasic

Post by ITomi »

There is one question left: I trying to do positioning an object to another one. It is important in my program when an object rotates towards the player (camera).
But I still can't achieve this. Something like that:

Code: Select all

do
	turnentity enemy(i).img,[b]???[/b],[b]???[/b],[b]???[/b]
loop until enemy(i).img [b]facing the camera object[/b]
I have wrote a program for this purpose, in which you can move a cone around another cone and the another cone would point to that. But I'm totally confused, as is the program.
What is the correct solution to object rotation?

Code: Select all

#Include "openb3d.bi"
#include "fbgfx.bi"

Using FB

ScreenRes 800,600,32,,&h10002
Graphics3d 800,600

dim shared as any ptr hudimg,hudtex,camera,imgtohud,cone,cone2

sub movecone(xp as double, yp as double)
    moveentity cone,xp,yp,0
    RotateEntity cone2,0,DeltaYaw#(cone2,cone),0
    'RotateMesh cone2,0,DeltaYaw#(cone2,cone),0
end sub

camera=createCamera()
var light=createLight()

cone=CreateCone(16)
PositionEntity cone,0,0,5
cone2=CreateCone(16)
PositionEntity cone2,-3,0,5
RotateEntity cone2,90,35,-90
'RotateMesh cone2,90,0,-90

imgtohud=imagecreate(128,128,32)

hudimg=CreateSprite(camera)
ScaleSprite hudimg,8,1
MoveEntity hudimg,3,2.7,5
EntityOrder hudimg,-1
hudtex=CreateTexture(128,128)
EntityTexture hudimg,hudtex

Do      
        if multikey(sc_up) then
            movecone(0,0.01)
        end if
        if multikey(sc_down) then
            movecone(0,-0.01)
        end if
        if multikey(sc_left) then
            movecone(-0.01,0)
        end if
        if multikey(sc_right) then
            movecone(0.01,0)
        end if
        
        line imgtohud,(0,0)-(127,127),255,bf
        draw string imgtohud,(1,1),"X: "+str(entityx#(cone))
        BufferToTex hudtex,imgtohud,1
        draw string imgtohud,(1,10),"Y: "+str(entityy#(cone))
        BufferToTex hudtex,imgtohud,1
        draw string imgtohud,(1,20),"Z: "+str(entityz#(cone))
        BufferToTex hudtex,imgtohud,1
        draw string imgtohud,(1,30),"DP.: "+str(deltapitch#(cone2,cone))
        BufferToTex hudtex,imgtohud,1
        
        'updateworld
        renderworld
        Flip
Loop Until MultiKey(sc_q)
Post Reply