OpenB3D Questions

Started by Krischan, January 04, 2019, 23:33:07

Previous topic - Next topic

markcwm

#30
Hi Krischan,

QuoteThere is still no crash, but a new bug in LOF: switching the resolution with keys 1-4 creates a "black bar" on the screen and the camera positioning goes wrong. This worked before.

Engine workflow: Key Press > call SetResolution(x,y) in main file > function SetResolution in include/system.bmx > calls SetGadgetShape, CameraViewport, CameraZoom

well this isn't actually a bug in Openb3dmax, it's because you're not updating TGlobal.height[0]=height before CameraViewport, so either do that in TCam Update() or System SetResolution().

It worked before because CameraViewport was bottom-up OpenGL coords, I tested with minib3d/tex_render and it's now top-down screen coords like Minib3d. To invert we need to use "vy=TGlobal.height-h-vy" which is why it has to be updated when switching graphics resolution.

I've pushed a commit with some convenience functions to help make this clearer, they are GlobalResolution(w,h) to set, and GlobalWidth, GlobalHeight to get. I also moved GraphicsInit back to where it was, before states are set in Global::Graphics.

Krischan

That's why I wrote "a bug in LOF" ;D Adding TGlobal.Height[0] = Height or GlobalResolution(width, Height) to the TCam Update() function fixed the problem, thanks.

But there is another issue I can't fix without your help. Switch to higher resolutions (keys 3,4) and the second magic sphere camera and the hand light vanish. Going back to lower resolutions (1,2) and they are there again. Hmm... They are stored in the MINIMAP_CAMERA and MINIMAP_HANDLIGHT variables, init at GUI.bmx, function InitMinimap(), update occurs in TPlayer.bmx UpdateMinimap() function using the BackBufferToTex() function. Z-Order is off for the hand pivot children to make the hand visible over the rest of the 3D stuff. The compass (switch with key M) works. Could be a problem grabbing the texture in a higher resolution with wrong camera settings.
Kind regards
Krischan

Windows 10 Pro | i7 9700K@ 3.6GHz | RTX 2080 8GB]
Metaverse | Blitzbasic Archive | My Github projects

markcwm

Hi Krischan,

well I get the spheremap on keys 1,2 and 4 but not on 3 where it's also not even shown on screen, I had to drop the camera zoom to see it. I found out the resolution you're setting wasn't right, when I changed 1920,1200 to 1920,1080 then the spheremap worked.

Krischan

#33
I think I must rethink my second camera concept. Strange enough it worked before but it fails now in higher resolutions. The texture grabbing seems to work, it looks like the camera position goes totally wrong but I dunno why. When I start the game from the beginning in the higher resolutions (the ones which fail later) - everything is fine, until I switch to a lower and back.

EDIT: I think I've found a workaround. I must call CameraViewport(MINIMAP_CAMERA, 0, 0, MINIMAP_RESOLUTION, MINIMAP_RESOLUTION) in the PositionMinimap() function which is called in the SetResolution() function. It only repositions the hand according to the current/new aspect ratio. But the MINIMAP_RESOLUTION value never changes even after switching the resolution (it is always 512) so it shouldn't be necessary there.
Kind regards
Krischan

Windows 10 Pro | i7 9700K@ 3.6GHz | RTX 2080 8GB]
Metaverse | Blitzbasic Archive | My Github projects

markcwm

Quote2) Line 111 / 257 / TQuad Type: why are the vertex coordinate changes in CopyEntity not copied to all children meshes live like in MiniB3D? I manipulate the quads only in the source mesh, but the copies are ignored? Is it a bug? Or still not implemented? This is IMHO a very important feature of 3D graphics.

Hi Krischan,

I've fixed CopyEntity in the latest commit, Angros had it working with RepeatMesh but he made a mistake with CopyEntity thinking it was CopyMesh that did instancing in Blitz3d but it's not, well that or the docs are wrong.

So I made CopyMesh what CopyEntity was and made CopyEntity instance surfaces, this causes issues when using FreeEntity, I tried managing it with a list of surfaces but it was too complex so I decided the rule is you can't free a mesh before the copies or it will crash (unless you free them all at the same time).

CopyMesh in Minib3d doesn't copy entity data so I replaced it. Then RepeatMesh instances both surfaces and anim surfaces, I'm not sure what Angros was doing there as animation appears to not be smooth, but it works with FreeEntity now.

Krischan

#35
That's good news Mark - instancing is very important. A quick miniB3D/OpenB3D comparison shows 108FPS vs. 133FPS @ 3840x1600 here - so OpenB3D is about 25% faster. Great. I only had to fix the code in Line 739 in the initial post to make it work again to CameraViewport tempcam, 0, 0, size, size.

What's not so great: LOF crashes again loading the next level (last Log entry is "Shaders deleted") :-((( Debug Error is "EXCEPTION BREAKPOINT" in the TEntity -> FreeEntity Method.

Another thing which is not a bug in OpenB3D but perhaps you or somebody else knows the answer - the OpenB3D starfield demo is not running smoothly, it has some kind of microstuttering when moving. I've played around with many of the nVidia settings but nothing helped. Flip true or false makes no difference, Fast/Quality settings neither. The MiniB3D demo has the same problem. But: starting a game like Everspace (D3D) or the old Wolfenstein Enemy Territory (OpenGL) with the same settings always run incredible smooth. The stuttering is best visible when moving the mouse around while moving. What could be the problem here?

Here's the modifed code to run with the latest OpenB3D commit:

Code (Blitzmax) Select
SuperStrict

Import openb3dmax.B3dglgraphics

Graphics3D DesktopWidth() / 1.0, DesktopHeight() / 1.0, 32, 2

ClearTextureFilters()

Global STARS:Int = 50000        ' number of stars per cluster part
Global DIMENSION:Int = 2000     ' cluster dimension
Global DISTRIBUTION:Float = 0.99' star distribution (0...1 = random...clustered)
Global SPEED:Float = 1.0        ' overall move speed multiplicator
Global BRAKE:Float = 0.95       ' brake multiplicator
Global VSYNC:Int = True        ' Vertical Sync
Global HOMING:Int = True        ' turn homing on/off
Global COLORED:Int = False      ' colorize clusters
Global TEXTURED:Int = True      ' use star texture
Global Scale:Float = 0.5        ' star scale factor
Global FADE:Int = True          ' fade distant clusters
Global INSTANCING:Int = True    ' duplicate source mesh

Global DEBUGLEVEL:Int = 0       ' 0=off, 1=no instancing, 2=colored, 3=scene

If DEBUGLEVEL > 0 Then

STARS = 1000
Scale = 1.6
DISTRIBUTION = 0.5
INSTANCING = False

If DEBUGLEVEL > 1 Then

COLORED = True
TEXTURED = False

If DEBUGLEVEL > 2 Then

HOMING = False
FADE = False

EndIf

EndIf

EndIf

' ----------------------------------------------------------------------------
' Global variables
' ----------------------------------------------------------------------------
Global localx:Float, localy:Float, localz:Float
Global globalx:Float, globaly:Float, globalz:Float
Global simx:Float, simy:Float, simz:Float
Global xspeed:Float, yspeed:Float, zspeed:Float, rspeed:Float
Global xadd:Float, yadd:Float, zadd:Float, radd:Float, tadd:Float

Global FPS:TFPS = New TFPS
Global MS:Int = MilliSecs()

' ----------------------------------------------------------------------------
' Init scene
' ----------------------------------------------------------------------------
Global masterpivot:TPivot = CreatePivot()

Global cam:TCamera = CreateCamera()
CameraRange cam, 1, DIMENSION * 8
PositionEntity cam, 0, 0, 0

Local tex:TTexture = CreateSunTexture(512, 128, 128, 128)
TextureBlend tex, 3

' ----------------------------------------------------------------------------
' Duplicate Quad mesh in a 9x9x9 matrix
' ----------------------------------------------------------------------------
Global meshlist:TList = CreateList()
Global quadlist:TList = CreateList()
Global quadsourcelist:TList = CreateList()
Global lx:Float, ly:Float, lz:Float

Local entities:TEntity[9, 9, 9]
Local meshes:TMesh[9, 9, 9]

Local mesh:TMesh

' star cluster properties
mesh = CreateMesh()
EntityFX mesh, 1 + 2
EntityBlend mesh, 3
If TEXTURED Then EntityTexture mesh, tex
HideEntity mesh

' create blueprint star cluster
For Local i:Int = 1 To STARS

CreateStar(mesh)

Next

' fix for OpenB3D to enable Texture Blending and Alpha?
SetBlend ALPHABLEND

' create 5x5x5 = 125 cluster
For Local x:Int = 0 To 4 Step 1

For Local y:Int = 0 To 4 Step 1

For Local z:Int = 0 To 4 Step 1

' create a mesh and duplicate its properties = FAST
If INSTANCING Then

entities[x, y, z] = CopyEntity(mesh)

PositionEntity entities[x, y, z], (x - 2) * DIMENSION, (y - 2) * DIMENSION, (z - 2) * DIMENSION

If COLORED Then

EntityColor entities[x, y, z], Rand(64, 255), Rand(64, 255), Rand(64, 255)

Else

EntityColor entities[x, y, z], 255, 255, 255

EndIf

ListAddLast(meshlist, entities[x, y, z])

' create many unique meshes without instancing = SLOW
Else

' new mesh
meshes[x, y, z] = CreateMesh()
EntityFX meshes[x, y, z], 1
EntityBlend meshes[x, y, z], 3
If TEXTURED Then

EntityTexture meshes[x, y, z], tex
EntityFX meshes[x, y, z], 1 + 2

EndIf

' duplicate blueprint cluster
For Local s:TQuad = EachIn quadsourcelist

Local q:TQuad = New TQuad

q.mesh = meshes[x, y, z]
q.x = s.x
q.y = s.y
q.z = s.z
q.scalex = s.scalex
q.scaley = s.scaley
q.RGB = s.RGB

q.Add()
q.Update(cam)

ListAddLast(quadlist, q)

Next

PositionEntity meshes[x, y, z], (x - 2) * DIMENSION, (y - 2) * DIMENSION, (z - 2) * DIMENSION

If COLORED Then

EntityColor meshes[x, y, z], Rand(128, 255), Rand(128, 255), Rand(128, 255)

Else

EntityColor meshes[x, y, z], 255, 255, 255

EndIf

ListAddLast(meshlist, meshes[x, y, z])

EndIf

RenderWorld

Flip False

Next

Next

Next

' Fix to really center the mouse (otherwise it "jumps" a little bit initially)
MoveMouse(GraphicsWidth() / 2, GraphicsHeight() / 2) ; Flip
MouseX()
MouseY()
MouseXSpeed()
MouseYSpeed()
Flip

Global timer:TTimer = CreateTimer(60)

MS = MilliSecs() - MS

' ----------------------------------------------------------------------------
' Main Loop
' ----------------------------------------------------------------------------
While Not AppTerminate()

If KeyHit(KEY_ESCAPE) Then End

' axis rotation
Local pitch:Float = Normalize(MouseY(), 0, GraphicsHeight() - 1, -2, 2)
Local yaw:Float = Normalize(MouseX(), 0, GraphicsWidth() - 1, 2, -2)
Local roll:Int = KeyDown(KEY_Q) - KeyDown(KEY_E)

' XYZ movement
Local xmove:Int = KeyDown(KEY_D) - KeyDown(KEY_A)
Local ymove:Int = KeyDown(KEY_R) - KeyDown(KEY_F)
Local zmove:Int = KeyDown(KEY_W) - KeyDown(KEY_S)
Local turbo:Int = KeyDown(KEY_TAB)

If xmove = 0 And xadd <> 0 Then xadd = 0 Else If xmove And xadd = 0 Then xadd = 0.001
If ymove = 0 And yadd <> 0 Then yadd = 0 Else If ymove And yadd = 0 Then yadd = 0.001
If zmove = 0 And zadd <> 0 Then zadd = 0 Else If zmove And zadd = 0 Then zadd = 0.001
If roll = 0 And radd <> 0 Then radd = 0 Else If roll And radd = 0 Then radd = 0.01
If turbo = 0 And tadd <> 0 Then tadd:*0.9 Else If turbo And tadd = 0 Then tadd = 0.1

If tadd < 0.01 Then tadd = 0.0

If Abs(xmove) Then xadd:+0.01
If Abs(ymove) Then yadd:+0.01
If Abs(zmove) Then zadd:+0.01
If Abs(roll) Then radd:+0.025
If Abs(turbo) Then tadd:+0.05

xadd:*1.025
yadd:*1.025
zadd:*1.025
radd:*1.025
tadd:*1.025

If xadd > 2.0 Then xadd = 2.0
If yadd > 2.0 Then yadd = 2.0
If zadd > 2.0 Then zadd = 2.0
If radd > 1.5 Then radd = 1.5
If tadd > 25.0 Then tadd = 25.0

' calculate movespeed/rollspeed
If Abs(xmove) Then xspeed = xadd * SPEED * Sgn(xmove) * (1.0 + tadd)
If Abs(ymove) Then yspeed = yadd * SPEED * Sgn(ymove) * (1.0 + tadd)
If Abs(zmove) Then zspeed = zadd * SPEED * Sgn(zmove) * (1.0 + tadd)
If Abs(roll) Then rspeed = radd * Sgn(roll)

' perform rotation and motion
Turn(cam, pitch, yaw, rspeed)
MoveEntity cam, xspeed, yspeed, zspeed

' keep camera at home
If HOMING Then Home(cam, masterpivot, DIMENSION)

' only the master instance quads are facing to the camera
For Local q:TQuad = EachIn quadlist

q.Update(cam)

Next

' fade mesh according to its distance
If FADE Then

For Local e:TEntity = EachIn meshlist

Local d:Float = EntityDistance(cam, e)
Local a:Float = Normalize(d, DIMENSION * 1.0, DIMENSION * 2.0, 1.0, 0.0)
EntityAlpha e, a

Next

EndIf

RenderWorld

FPS.Update()

' fix for OpenB3D to have vertex colors enabled (otherwise its greyscale)
Begin2D()

DrawText("FPS [Init]..: " + FPS.FPS + " [" + MS + "ms]", 0, 0)
DrawText("Star Cluster: " + STARS, 0, 15)
DrawText("Stars Total.: " + (STARS * 5 * 5 * 5), 0, 30)

End2D()

Flip VSYNC

' decrease speed
xspeed:*BRAKE
yspeed:*BRAKE
zspeed:*BRAKE
rspeed:*BRAKE

Wend

End

' creates a single star quad
Function CreateStar(mesh:TMesh, surf:TSurface = Null, xoff:Float = 0.0:Float, yoff:Float = 0.0, zoff:Float = 0.0)

Local q:TQuad = New TQuad

q.mesh = mesh
q.surf = surf

q.x = Rnd(-DIMENSION / 2, DIMENSION / 2) + xoff
q.y = Rnd(-DIMENSION / 2, DIMENSION / 2) + yoff
q.z = Rnd(-DIMENSION / 2, DIMENSION / 2) + zoff

' randomized clustering
If Rnd(1) > 1 - DISTRIBUTION Then

Local d:Float = Rnd(0.0001, 0.05)

q.x = lx + Rnd(-DIMENSION * d, DIMENSION * d) + xoff
q.y = ly + Rnd(-DIMENSION * d, DIMENSION * d) + yoff
q.z = lz + Rnd(-DIMENSION * d, DIMENSION * d) + zoff

EndIf

q.scalex = Rnd(1, Rnd(2, Rnd(4, Rnd(8, Rnd(16, 32))))) * Scale
q.scaley = q.scalex

Local c:Float = (1.0 / q.scalex)
If Rnd(1) > 0.9 And c < 0.70 Then c = 1 - c             ' 10% Giants
If c >= 0.0 And c < 0.35 Then q.RGB = [255, 64, 0]      ' 35% Class M
If c >= 0.35 And c < 0.50 Then q.RGB = [255, 128, 32]   ' 15% Class K
If c >= 0.50 And c < 0.60 Then q.RGB = [255, 255, 64]   ' 10% Class G
If c >= 0.60 And c < 0.70 Then q.RGB = [255, 255, 128]  ' 10% Class F
If c >= 0.70 And c < 0.80 Then q.RGB = [255, 255, 255]  ' 10% Class A
If c >= 0.80 And c < 0.90 Then q.RGB = [0, 64, 255]     ' 10% Class B
If c >= 0.90 And c <= 1.00 Then q.RGB = [0, 0, 255]     ' 10% Class O

q.Add()
q.Update(cam)

ListAddLast(quadlist, q)
ListAddLast(quadsourcelist, q)

lx = q.x
ly = q.y
lz = q.z

End Function

' keeps the player in a predefined cubic area
Function Home(target:TEntity, world:TEntity, homesize:Int = 100)

' store Local player Position
Local localx:Double = EntityX(target)
Local localy:Double = EntityY(target)
Local localz:Double = EntityZ(target)

' Check X axis
While localx > homesize

globalx:+homesize
localx:-homesize
PositionEntity target, localx, localy, localz
MoveEntity world, -homesize, 0, 0

Wend

While localx < - homesize

globalx:-homesize
localx:+homesize
PositionEntity target, localx, localy, localz
MoveEntity world, homesize, 0, 0

Wend

' Check Y axis
While localy > homesize

globaly:+homesize
localy:-homesize
PositionEntity target, localx, localy, localz
MoveEntity world, 0, -homesize, 0

Wend

While localy < - homesize

globaly:-homesize
localy:+homesize
PositionEntity target, localx, localy, localz
MoveEntity world, 0, homesize, 0

Wend

' Check Z axis
While localz > homesize

globalz:+homesize
localz:-homesize
PositionEntity target, localx, localy, localz
MoveEntity world, 0, 0, -homesize

Wend

While localz < - homesize

globalz:-homesize
localz:+homesize
PositionEntity target, localx, localy, localz
MoveEntity world, 0, 0, homesize

Wend

' store simulated player Position
simx = localx + globalx
simy = localy + globaly
simz = localz + globalz

End Function

' ----------------------------------------------------------------------------
' Normalizes a value to given range
' ----------------------------------------------------------------------------
Function Normalize:Float(value:Float, vmin:Float, vmax:Float, nmin:Float, nmax:Float)

Return((value - vmin) / (vmax - vmin)) * (nmax - nmin) + nmin

End Function

' ----------------------------------------------------------------------------
' Turn Entity using Quaternions
' ----------------------------------------------------------------------------
Function Turn(Ent:TEntity, X:Float = 0.0, Y:Float = 0.0, Z:Float = 0.0, Glob:Int = False)

Local Pitch:Float = 0.0
Local Yaw:Float = 0.0
Local Roll:Float = 0.0

Local Quat:TQuaternion = EulerToQuat(0.0, 0.0, 0.0)
Local Turn_Quat:TQuaternion = EulerToQuat(0.0, 0.0, 0.0)

If Glob = False

Quat = EulerToQuat(EntityPitch(Ent, True), EntityYaw(Ent, True), EntityRoll(Ent, True))
Turn_Quat = EulerToQuat(X, Y, Z)
Quat = MultiplyQuats(Quat, Turn_Quat)
Quat = NormalizeQuat(Quat)
QuatToEuler2(Quat.x[0], Quat.y[0], Quat.z[0], Quat.w[0], pitch, yaw, roll)
RotateEntity Ent, pitch, yaw, roll

Else

RotateEntity Ent, EntityPitch(Ent) + X, EntityYaw(Ent) + Y, EntityRoll(Ent) + Z

EndIf

End Function

' ----------------------------------------------------------------------------
' Euler to Quaternion
' ----------------------------------------------------------------------------
Function EulerToQuat:TQuaternion(pitch:Float, yaw:Float, roll:Float)

Local cr:Float = Cos(-roll / 2.0)
Local cp:Float = Cos(pitch / 2.0)
Local cy:Float = Cos(yaw / 2.0)
Local sr:Float = Sin(-roll / 2.0)
Local sp:Float = Sin(pitch / 2.0)
Local sy:Float = Sin(yaw / 2.0)
Local cpcy:Float = cp * cy
Local spsy:Float = sp * sy
Local spcy:Float = sp * cy
Local cpsy:Float = cp * sy

Local q:TQuaternion = NewQuaternion()

q.w[0] = cr * cpcy + sr * spsy
q.x[0] = sr * cpcy - cr * spsy
q.y[0] = cr * spcy + sr * cpsy
q.z[0] = cr * cpsy - sr * spcy

Return q

End Function

' ----------------------------------------------------------------------------
' Quaternion to Euler
' ----------------------------------------------------------------------------
Function QuatToEuler2(x:Float, y:Float, z:Float, w:Float, pitch:Float Var, yaw:Float Var, roll:Float Var)

Local QuatToEulerAccuracy:Double = 1.0 / 2 ^ 31

Local sint:Float = (2.0 * w * y) - (2.0 * x * z)
Local cost_temp:Float = 1.0 - (sint * sint)
Local cost:Float

If Abs(cost_temp) > QuatToEulerAccuracy

cost = Sqr(cost_temp)

Else

cost = 0.0

EndIf

Local sinv:Float, cosv:Float, sinf:Float, cosf:Float

If Abs(cost) > QuatToEulerAccuracy

sinv = ((2.0 * y * z) + (2.0 * w * x)) / cost
cosv = (1.0 - (2.0 * x * x) - (2.0 * y * y)) / cost
sinf = ((2.0 * x * y) + (2.0 * w * z)) / cost
cosf = (1.0 - (2.0 * y * y) - (2.0 * z * z)) / cost

Else

sinv = (2.0 * w * x) - (2.0 * y * z)
cosv = 1.0 - (2.0 * x * x) - (2.0 * z * z)
sinf = 0.0
cosf = 1.0

EndIf

pitch = ATan2(sint, cost)
yaw = ATan2(sinf, cosf)
roll = -ATan2(sinv, cosv)

End Function

' ----------------------------------------------------------------------------
' Multiply Quaternion
' ----------------------------------------------------------------------------
Function MultiplyQuats:TQuaternion(q1:TQuaternion, q2:TQuaternion)

Local q:TQuaternion = NewQuaternion()

q.w[0] = q1.w[0] * q2.w[0] - q1.x[0] * q2.x[0] - q1.y[0] * q2.y[0] - q1.z[0] * q2.z[0]
q.x[0] = q1.w[0] * q2.x[0] + q1.x[0] * q2.w[0] + q1.y[0] * q2.z[0] - q1.z[0] * q2.y[0]
q.y[0] = q1.w[0] * q2.y[0] + q1.y[0] * q2.w[0] + q1.z[0] * q2.x[0] - q1.x[0] * q2.z[0]
q.z[0] = q1.w[0] * q2.z[0] + q1.z[0] * q2.w[0] + q1.x[0] * q2.y[0] - q1.y[0] * q2.x[0]

Return q

End Function

' ----------------------------------------------------------------------------
' Normalize Quaternion
' ----------------------------------------------------------------------------
Function NormalizeQuat:TQuaternion(q:TQuaternion)

Local uv:Float = Sqr(q.w[0] * q.w[0] + q.x[0] * q.x[0] + q.y[0] * q.y[0] + q.z[0] * q.z[0])

q.w[0] = q.w[0] / uv
q.x[0] = q.x[0] / uv
q.y[0] = q.y[0] / uv
q.z[0] = q.z[0] / uv

Return q

End Function

' ------------------------------------------------------------------------------------------------
' Quad Type
' ------------------------------------------------------------------------------------------------
Type TQuad

Field x:Float = 0.0 ' position x
Field y:Float = 0.0 ' position y
Field z:Float = 0.0 ' position z

Field row:Int = 0 ' texture row
Field col:Int = 0 ' texture column

Field scalex:Float = 1.0 ' current size X
Field scaley:Float = 1.0 ' current size Y

Field RGB:Int[] = [255, 255, 255] ' Vertex Color
Field Alpha:Float = 1.0 ' Vertex Alpha

Field v:Int = 0 ' vertex counter
Field mesh:TMesh = Null ' mesh pointer
Field surf:TSurface = Null ' surface pointer

' --------------------------------------------------------------------------------------------
' METHOD: Add new Quad
' --------------------------------------------------------------------------------------------
Method Add(col:Int = 0, row:Int = 0)

Local s:Int = CountSurfaces(mesh)
If s = 0 Then

surf = CreateSurface(mesh)

Else

surf = GetSurface(mesh, s)

EndIf

Local i:Int = CountVertices(surf)
If i + 4 > 32768 Then

surf = CreateSurface(mesh)
v = 0

EndIf

' add Vertices
Local V0:Int = AddVertex(surf, 0, 0, 0, 1, 0)
Local V1:Int = AddVertex(surf, 0, 0, 0, 1, 1)
Local V2:Int = AddVertex(surf, 0, 0, 0, 0, 1)
Local V3:Int = AddVertex(surf, 0, 0, 0, 0, 0)

' color vertices
VertexColor surf, V0, RGB[0], RGB[1], RGB[2], Alpha
VertexColor surf, V1, RGB[0], RGB[1], RGB[2], Alpha
VertexColor surf, V2, RGB[0], RGB[1], RGB[2], Alpha
VertexColor surf, V3, RGB[0], RGB[1], RGB[2], Alpha

' connect triangles
AddTriangle surf, V0, V1, V2
AddTriangle surf, V0, V2, V3

VertexTexCoords surf, V0, col + 1, row
VertexTexCoords surf, V1, col + 1, row + 1
VertexTexCoords surf, V2, col, row + 1
VertexTexCoords surf, V3, col, row

' increase vertex counter
If v >= 4 Then v = V0 + 4 Else v = V0

End Method

' --------------------------------------------------------------------------------------------
' METHOD: Update a Quad
' --------------------------------------------------------------------------------------------
Method Update(target:TEntity)

TFormVector scalex, 0, 0, target, Null
Local X1:Float = TFormedX()
Local Y1:Float = TFormedY()
Local Z1:Float = TFormedZ()

TFormVector 0, scaley, 0, target, Null
Local X2:Float = TFormedX()
Local Y2:Float = TFormedY()
Local Z2:Float = TFormedZ()

' set vertices
VertexCoords surf, v + 0, x - x1 - x2, y - y1 - y2, z - z1 - z2
VertexCoords surf, v + 1, x - x1 + x2, y - y1 + y2, z - z1 + z2
VertexCoords surf, v + 2, x + x1 + x2, y + y1 + y2, z + z1 + z2
VertexCoords surf, v + 3, x + x1 - x2, y + y1 - y2, z + z1 - z2

End Method

End Type

' ------------------------------------------------------------------------------------------------
' Exact FPS counter
' ------------------------------------------------------------------------------------------------

Type TFPS

Global renders:Int = 0

Field FPS:Int = 60 ' current FPS value
Field interval:Int = 999
Field averagefps:Int = 60 ' average FPS value
Field framedrops:Int = 0 ' dropped frames
Field oldlooptime:Int = 0
Field looptime:Int = 0
Field multi:Float ' main loop multiplicator

Field old:Int = MilliSecs()
Field totalfps:Int = 30
Field Ticks:Int

' --------------------------------------------------------------------------------------------
' METHOD: Update FPS counter
' --------------------------------------------------------------------------------------------
Method Update()

renders:+1

looptime = MilliSecs() - oldlooptime
oldlooptime = MilliSecs()

If MilliSecs() - old >= interval Then

old = MilliSecs()

FPS = renders * (1000 / interval)
renders = 0
totalfps:+FPS
Ticks:+1

averagefps = totalfps / Ticks

EndIf

End Method

End Type

' Create a stunning star texture
Function CreateSunTexture:TTexture(size:Int = 512, r:Int = 255, g:Int = 255, b:Int = 255)

Local i:Float, j:Int, col:Int, rgb:Int
Local x:Int, y:Int

Local w:Int = GraphicsWidth()

Local tempcam:TCamera, tempsun:TPivot
Local pixmap:TPixmap = CreatePixmap(size, size, PF_RGBA8888)
Local tex:TTexture = CreateTexture(size, size, 1 + 8)

For j = 0 To (size / 2) - 1

col = 255 - Normalize(j, 0, (size / 2.0) - 1, 0, 255)
If col > 255 Then col = 255
rgb = col * $1000000 + col * $10000 + col * $100 + col

For i = 0 To 360 Step 0.1

WritePixel(pixmap, (size / 2) + (Sin(i) * j), (size / 2) + (Cos(i) * j), rgb)

Next

Next

PixmapToTexture(pixmap, tex)
SavePixmapPNG(pixmap, "proceduralstar1.png", 0)

' temp camera
tempcam = CreateCamera()
CameraRange tempcam, 1, w * 2

' fix for OpenB3D to simulate MiniB3D's Cameraviewport handling
CameraViewport tempcam, 0, 0, size, size

' temp pivot
tempsun = CreatePivot()

' Create 4 body quads
CreateQuad(tempsun, size * 1.0, tex, 3, 1 + 8 + 16, r * 1.00, g * 1.00, b * 1.00, 1.00)
CreateQuad(tempsun, size * 1.5, tex, 3, 1 + 8 + 16, r * 1.00, g * 1.00, b * 1.00, 1.00)
CreateQuad(tempsun, size * 2.0, tex, 3, 1 + 8 + 16, r * 0.75, g * 0.75, b * 0.50, 0.75)
CreateQuad(tempsun, size * 4.0, tex, 3, 1 + 8 + 16, r * 0.50, g * 0.50, b * 0.50, 0.50)

' create 4 ray quads
Local ray1:TMesh = CreateQuad(tempsun, size * 4.0, tex, 3, 1 + 8 + 16, 255, 255, 255, 1)
Local ray2:TMesh = CreateQuad(tempsun, size * 4.0, tex, 3, 1 + 8 + 16, 255, 255, 255, 1)
Local ray3:TMesh = CreateQuad(tempsun, size * 4.0, tex, 3, 1 + 8 + 16, 255, 255, 255, 0.5)
Local ray4:TMesh = CreateQuad(tempsun, size * 4.0, tex, 3, 1 + 8 + 16, 255, 255, 255, 0.5)

' rescale and rotate rays
ScaleEntity ray1, size * 2, size / 32, size
ScaleEntity ray2, size / 32, size * 2, size
ScaleEntity ray3, size, size / 32, size
ScaleEntity ray4, size, size / 32, size
RotateEntity ray3, 0, 0, 45
RotateEntity ray4, 0, 0, 135

PositionEntity tempsun, 0, 0, w

' render star
RenderWorld
RenderWorld

' grab image
pixmap = GrabPixmap(0, 0, size, size)
For x = 0 To size - 1

For y = 0 To size - 1

rgb = ReadPixel(pixmap, x, y)

r = (rgb & $ff0000) / $10000
g = (rgb & $ff00) / $100
b = (rgb & $ff)

' rgb
rgb = (r + g + b) / 3 * $1000000 + r * $10000 + g * $100 + b

WritePixel(pixmap, x, y, rgb)

Next

Next

PixmapToTexture(pixmap, tex)
'SavePixmapPNG(pixmap, "proceduralstar2.png", 0)

' Delete pixmap, pivot and temp cam
pixmap = Null
FreeEntity tempsun
FreeEntity tempcam

Return tex

End Function

' custom quad creation
Function CreateQuad:Tmesh(parent:TEntity, scale:Float = 1.0, tex:TTexture = Null, blend:Int = False, fx:Int = False, r:Int = 255, g:Int = 255, b:Int = 255, a:Float = 1.0)

Local mesh:TMesh = CreateMesh()
Local surf:TSurface = CreateSurface(mesh)
Local v0:Int, v1:Int, v2:Int, v3:Int

v0 = AddVertex(surf, 1, 1, 0, 0, 0)
v1 = AddVertex(surf, -1, 1, 0, 1, 0)
v2 = AddVertex(surf, -1, -1, 0, 1, 1)
v3 = AddVertex(surf, 1, -1, 0, 0, 1)

AddTriangle surf, v0, v1, v2
AddTriangle surf, v0, v2, v3

If parent Then EntityParent Mesh, parent
If fx Then EntityFX Mesh, fx
If tex Then EntityTexture Mesh, tex
If blend Then EntityBlend Mesh, blend

EntityColor Mesh, r, g, b
EntityAlpha Mesh, a

VertexColor surf, v0, r, g, b, a
VertexColor surf, v1, r, g, b, a
VertexColor surf, v2, r, g, b, a
VertexColor surf, v3, r, g, b, a

ScaleEntity Mesh, Scale, Scale, Scale

Return Mesh

End Function

' creates a texture from a pixmap
Function PixmapToTexture(pixmap:TPixmap, tex:TTexture)

If PixmapFormat(pixmap) <> PF_RGBA8888 Then pixmap = ConvertPixmap(pixmap, PF_RGBA8888)

' OpenB3D only function to copy pixmap to texture
BufferToTex tex, PixmapPixelPtr(pixmap, 0, 0)

' MiniB3D workaround to copy pixmap to texture
'glBindTexture (GL_TEXTURE_2D, tex.gltex[0])
'gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, PixmapPixelPtr(pixmap, 0, 0))

End Function

' --------------------------------------------------------------------------------
' Fixed BeginMax2D()
' --------------------------------------------------------------------------------
Function Begin2D()

Local x:Int, y:Int, w:Int, h:Int
GetViewport(x, y, w, h)

'glPopClientAttrib()
'glPopAttrib()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_TEXTURE)
glPopMatrix()
glMatrixMode(GL_COLOR)
glPopMatrix()

glDisable(GL_LIGHTING)
glDisable(GL_DEPTH_TEST)
glDisable(GL_SCISSOR_TEST)
glDisable(GL_FOG)
glDisable(GL_CULL_FACE)

glMatrixMode GL_TEXTURE
glLoadIdentity

glMatrixMode GL_PROJECTION
glLoadIdentity
glOrtho 0, GraphicsWidth(), GraphicsHeight(), 0, -1, 1

glMatrixMode GL_MODELVIEW
glLoadIdentity

SetViewport x, y, w, h

Local MaxTex:Int
glGetIntegerv(GL_MAX_TEXTURE_UNITS, Varptr(MaxTex))

For Local Layer:Int = 0 Until MaxTex

glActiveTexture(GL_TEXTURE0+Layer)

glDisable(GL_TEXTURE_CUBE_MAP)
glDisable(GL_TEXTURE_GEN_S)
glDisable(GL_TEXTURE_GEN_T)
glDisable(GL_TEXTURE_GEN_R)

glDisable(GL_TEXTURE_2D)

Next

glActiveTexture(GL_TEXTURE0)

glViewport(0, 0, GraphicsWidth(), GraphicsHeight())
glScissor(0, 0, GraphicsWidth(), GraphicsHeight())

glEnable GL_BLEND
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_TEXTURE_2D)

End Function

' --------------------------------------------------------------------------------
' Fixed EndMax2D()
' --------------------------------------------------------------------------------
Function End2D()

' save the Max2D settings for later
'glPushAttrib(GL_ALL_ATTRIB_BITS)
'glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glMatrixMode(GL_TEXTURE)
glPushMatrix()
glMatrixMode(GL_COLOR)
glPushMatrix()

glDisable(GL_TEXTURE_CUBE_MAP)
glDisable(GL_TEXTURE_GEN_S)
glDisable(GL_TEXTURE_GEN_T)
glDisable(GL_TEXTURE_GEN_R)

glDisable(GL_TEXTURE_2D)
glDisable(GL_BLEND)

TGlobal.EnableStates()
'glDisable(GL_TEXTURE_2D)

' only needed for OpenB3D
TGlobal.alpha_enable[0] = 0 ' alpha blending was disabled by Max2d (GL_BLEND)
TGlobal.blend_mode[0] = 1 ' force alpha blending
TGlobal.fx1[0] = 0 ' full bright/surface normals was enabled by EnableStates (GL_NORMAL_ARRAY)
TGlobal.fx2[0] = 1 ' vertex colors was enabled by EnableStates (GL_COLOR_ARRAY)

glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR)
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE)

glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

glAlphaFunc(GL_GEQUAL, 0.5)

' only needed for OpenB3D
For Local cam:TCamera=EachIn TCamera.cam_list

' active camera - was if cam.hide[0]=0
If cam = TGlobal.camera_in_use

' fog with Max2d fix
cam.UpdateFog()
Exit

EndIf

Next

End Function


Kind regards
Krischan

Windows 10 Pro | i7 9700K@ 3.6GHz | RTX 2080 8GB]
Metaverse | Blitzbasic Archive | My Github projects

markcwm

QuoteWhat's not so great: LOF crashes again loading the next level (last Log entry is "Shaders deleted") :-((( Debug Error is "EXCEPTION BREAKPOINT" in the TEntity -> FreeEntity Method.

Hi Krischan,

well I thought this was due to deleting surfaces but it seems not, I uncommented the code to delete bones, now I see why it was commented. :) So a quick fix, is goto mesh.cpp line 331 in FreeEntity and comment out "delete bone". This should be in though so I'll have to have a go at fixing it properly.

Re: microstuttering, I don't really follow you, are you sure it's not just low FPS?

Krischan

#37
Uncommenting didn't help. The Feb 9, 2019 commit (Added DebugFields/Globals, TVector wrapped, Terrain vertices) and the second Feb 10, 2019 commit (Fix CopyEntity causing FreeEntity crash) work, the latest one and the first Feb 10, 2019 commit (Fixed CopyEntity not instancing, CopyMesh now full copy) crash.

And do you think that 133FPS @ 3840x1600 is too low? :o

EDIT: Anyway, we shouldn't pay too much attention to the microstutters as it could be related to my GPU/Display combination. Such a large display can have unwanted side effects unless it has 144Hz (I have "only" 75Hz)
Kind regards
Krischan

Windows 10 Pro | i7 9700K@ 3.6GHz | RTX 2080 8GB]
Metaverse | Blitzbasic Archive | My Github projects

markcwm

#38
I'm sure the latest crashes are due to me un-commenting the delete bones code in Mesh::Freeentity, as I've been able to reproduce it with LOF and fix it by removing that code, the bones are stored in the entity child_list and also in the mesh bones list, which is what I didn't realize, so yeah it was double freeing. That was a bit stupid of me, oh well I learned some new stuff.

Krischan

Your latest commit fixed it again. So what problems are left, I've lost track of things ??? I think it is only point 5) with the barely noticeable moving of the mouse pointer after centering (Line 187 ff.)

Change the lines like this and the mouse is moving:

Code (Blitzmax) Select
' Fix to really center the mouse (otherwise it "jumps" a little bit initially)
MoveMouse(GraphicsWidth() / 2, GraphicsHeight() / 2)' ; Flip
'MouseX()
'MouseY()
'MouseXSpeed()
'MouseYSpeed()
'Flip
Kind regards
Krischan

Windows 10 Pro | i7 9700K@ 3.6GHz | RTX 2080 8GB]
Metaverse | Blitzbasic Archive | My Github projects

markcwm

#40
Phew, that's great, thanks Krischan! :)

Re: MouseMove, I don't think this is a bug at all, when you use the mouse to move the camera you have to do that sort of thing to take control, there are demos in Blitz3d that do the same thing.

Edit: also I notice DrawText doesn't work with the current BeginMax2d, this is because it needs GL_TEXTURE_2D enabled, GLDrawText doesn't so I'll push that fix with the next feature, which will be Minib3d's AntiAlias code.

Krischan

Well, the code worked in miniB3D without a workaround like Flip/Reset/Flip :P The problem is when the program starts and the user takes no action there is movement where it shouldn't.
Kind regards
Krischan

Windows 10 Pro | i7 9700K@ 3.6GHz | RTX 2080 8GB]
Metaverse | Blitzbasic Archive | My Github projects

markcwm

#42
Quote5) Line 205-206: in OpenB3D the mouse pointer moves slightly after initialization, this can only be fixed by NOT subtracting -1 in GraphicsHeight() - in MiniB3D it works (and would also be mathematically correct) - is it a rounding bug?

Hmm, well I had another look at this. I can't really follow your GraphicsHeight-1 fix but I think you mean for the pitch/yaw variables. I found no difference subtracting -1 and I found no difference at all between Minib3d and Openb3d, also there's not really anything I can do about this as they are Brl.System commands, but if you place MoveMouse before the first Renderworld then you don't see the jump, although you do see the mouse pointer move.

Krischan

Hmm looks you're right - I can't reproduce it here now. I swear I had this problem on my old rig and checked it many times. Anyway, I've fixed it now in my code by checking too small numbers:

If Abs(pitch) < 0.005 Then pitch = 0
If Abs(yaw) < 0.005 Then yaw = 0

Well I think afaik all known bugs are fixed now. Time for new bugs, we're running out of bugs ;D
Kind regards
Krischan

Windows 10 Pro | i7 9700K@ 3.6GHz | RTX 2080 8GB]
Metaverse | Blitzbasic Archive | My Github projects

markcwm

I tried the pitch/yaw fix but it still moved at render init, it might have been an issue on a previous version but it's good to know it's now working like Minib3d.

I'm really happy I could fix all these bugs and thanks to you Krischan for your assistance and persistence which I'm sure was not easy. I don't really thank people enough for their help fixing these bugs some people have been amazingly helpful in the past, I think good feedback can be as valuable as the fix.

I'm glad you can now carry on with your project which I think looks great, although maybe we should look at fixing that bumpmap issue, what shader are you using, is it test.frag?

Also, Minib3d's AntiAlias is now in with the latest commit and example, it's the same speed as in Minib3d but quite slow compared to the shader fxaa example by RonTek.