3d Fantasy Land Battle Scene Thingy

Started by Matty, December 12, 2023, 08:39:21

Previous topic - Next topic

chalky

Really enjoying these videos. Some impressive stuff going on here... :D

Matty

Thanks Chalky, I'm trying to keep the scope small enough to play to my strengths while hopefully making something that is still interesting and fun to play - and looks good enough for a modern user.

Matty

;;;;;;;;;;;;;;;;;;;;;;;;;;
;A simple program for generating
;a skybox environment, then rendering
;it to bitmaps, and then demonstrating
;using it to display a fake background
;based on a pre-rendered mesh
;
;
Graphics3D 1920,1080,0,2 ;set our 3d display
showbox = 0 ;flag - change this to 1 when you want to see the skybox in action

.start
pcamera = CreateCamera() ;camera
CameraRange pcamera,2,2000
CameraZoom pcamera,1
CameraClsColor pcamera,165,193,211 ;sky color
CameraFogMode pcamera,1 ;turn on fog
CameraFogRange pcamera,100,800
CameraFogColor pcamera,165,193,211 ;match sky color with fog

terraintype$ = "grass"

If showbox = 1 Then ;yeah a goto I know - this is just 'cause it's easy to do this way right now
Goto envbox
EndIf

;set up our lighting scheme - 4 lights, an a low ambient light, directional lights
;pointing across in a few different ways
Dim lights(4)
AmbientLight 10,10,20
pivot = CreatePivot()
light = CreateLight(1)
lights(0) = light
PositionEntity light,300,150,-200
PointEntity light,pivot
LightColor light,185,160,120
light = CreateLight(1)
lights(1) = light
PositionEntity light,-300,150,-200
PointEntity light,pivot
LightColor light,185,160,120
light = CreateLight(1)
lights(2) = light
PositionEntity light,300,150,200
PointEntity light,pivot
LightColor light,185,160,120
light = CreateLight(1)
lights(3) = light
PositionEntity light,-300,150,200
PointEntity light,pivot
LightColor light,185,160,120

mountains = LoadMesh("mountains.b3d") ;load our 3d mountain range.
;This mountain range is really just a height map of a jagged donut saved as a mesh and texture loosely.

gtex = LoadTexture("grass.png",1)
ScaleTexture gtex,0.125,0.25
EntityTexture mountains,gtex


;load our tree/foliage mesh. You could do an awful lot more than what I've done here
TextureFilter("leaves_DF.tga",1+2)
treemesh = LoadMesh("elm.b3d")
HideEntity treemesh

;load some more foliage...
rivergrass = LoadMesh("rivergrass.b3d")
HideEntity rivergrass
camera = pcamera


;put our camera in the middle of the yard and raise it up a little.
MoveEntity camera,0,20,0
rtime = MilliSecs()


For angle = 1 To 4 ;we're going to take 4 snapshots - with a zoom of 1.0 it means the fov is 90 degrees, so...makes sense
If image<>0 Then FreeImage image:image = 0
image = CreateImage(1920,1080) ;this image is merely to allow us to watch it render...while it renders...

TurnEntity camera,0,90,0 ;turn the camera
SetBuffer BackBuffer()
CameraClsMode camera,True,True ;render the mountain range..and put it in the zbuffer/colour buffer
ShowEntity mountains
RenderWorld
HideEntity mountains ;hide the moutnains
CameraClsMode camera,False,False ;change the camera to not clear the zbuffer or colour buffer...we'll simply keep rendering stuff into it until we've got a nice picture.
ShowEntity treemesh
ShowEntity rivergrass
;you could do this step a million and one different ways, this is how I've chosen to do it.
;for example you could simply line pick a million times to get the height of the mountains
;all over the place....we're planting trees here...millions of them....
For s = 1 To CountSurfaces(mountains)
surf = GetSurface(mountains,s)
For v = 0 To CountVertices(surf) - 1
x# = VertexX(surf,v)
z# = VertexZ(surf,v)
y# = VertexY(surf,v)
TFormPoint x,y,z,0,pcamera ;just checking if the tree will be inside the camera view
If TFormedZ()<0 Or Abs(TFormedX())*0.95>TFormedZ() Then Goto skipit
If KeyHit(1) Then End
If MilliSecs()>stime Then ;this is just to let us see the render updating as we go...gives us something to look at while it works in the background
stime = MilliSecs()+1000
CopyRect 0,0,1920,1080,0,0,BackBuffer(),ImageBuffer(image)
SetBuffer FrontBuffer()
DrawBlock image,0,0
Delay 2
SetBuffer BackBuffer()
EndIf
fog=fog+1
If fog Mod 12 = 0 Then
;this gives us our weirdly nice volumetric cloudy effect
;we're changing the fog range slightly every few renders....
;that gives the effect of misty clouds that actually look like fog
CameraFogRange camera,Rnd(80,120),Rnd(700,900)
EndIf
If Abs(TFormedX())>TFormedZ()*0.8 Then CameraFogRange camera,100,800
If y > 2 Then
For i = 1 To 50
;plant a shit-ton of trees for each vertex in the mountain range above a yheight
PositionEntity treemesh,x+Rnd(-20,20),y+Rnd(-25,5),z+Rnd(-20,20)
RotateEntity treemesh,Rnd(-20,20),Rnd(360),0
sc# = Rnd(0.2,0.6)+Rnd(0.2,0.6)+Rnd(0.2,0.6)
ScaleEntity treemesh,sc,sc,sc
RenderWorld ;render the tree, hide it, reposition it, show it, render again...I think you get it.
HideEntity treemesh
ShowEntity rivergrass
For j = 1 To 10 ;plant a shit ton of grass around each tree
PositionEntity rivergrass,EntityX(treemesh)+Rnd(-10,10),EntityY(treemesh)+Rnd(-2,2),EntityZ(treemesh)+Rnd(-10,10)
RotateEntity rivergrass,Rnd(-20,20),Rnd(360),0
sc = 2.0+Rnd(-0.5,1.5)
ScaleEntity rivergrass,sc,sc,sc
RenderWorld
Next
HideEntity rivergrass
ShowEntity treemesh
Next
Else
;we're on the flat...put a bunch of grass down
ShowEntity rivergrass
HideEntity treemesh
For j = 1 To 50
PositionEntity rivergrass,x+Rnd(-20.0,20.0),y+Rnd(-2.0,2.0),z+Rnd(-20.0,20.0)
RotateEntity rivergrass,Rnd(-20.0,20.0),Rnd(360),0
sc = 2.0+Rnd(-0.5,1.5)
ScaleEntity rivergrass,sc,sc,sc
RenderWorld
Next
HideEntity rivergrass
If Rand(0,100)<5 And (TFormedZ()*TFormedZ()+TFormedX()*TFormedX())>300*300 Then
ShowEntity treemesh
PositionEntity treemesh,x+Rnd(-20,20),y+Rnd(-2,2),z+Rnd(-20,20)
RotateEntity treemesh,Rnd(-20,20),Rnd(360),0
sc# = Rnd(0.2,0.6)+Rnd(0.2,0.6)+Rnd(0.2,0.6)
ScaleEntity treemesh,sc,sc,sc
RenderWorld

HideEntity treemesh
EndIf
EndIf
.skipit
Next
Next
HideEntity treemesh
HideEntity rivergrass
SaveBuffer BackBuffer(),terraintype$+"_background_"+angle+".bmp" ;save the skybox images.....
Next
rtime = (MilliSecs() - rtime)/1000
Color 255,255,255
Text 0,0,"Render Time:"+rtime+" seconds."
Flip
Delay 4000
ClearWorld()
showbox = 1
Goto start
End



.envbox

If boxtex1<>0 Then FreeTexture boxtex1
If boxtex2<>0 Then FreeTexture boxtex2
If boxtex3<>0 Then FreeTexture boxtex3
If boxtex4<>0 Then FreeTexture boxtex4
If boxsprite1<>0 Then FreeEntity boxsprite1
If boxsprite2<>0 Then FreeEntity boxsprite2
If boxsprite3<>0 Then FreeEntity boxsprite3
If boxsprite4<>0 Then FreeEntity boxsprite4


boxtex1 = LoadTexture(terraintype+"_background_1.bmp",1+16+32)
boxtex2 = LoadTexture(terraintype+"_background_2.bmp",1+16+32)
boxtex3 = LoadTexture(terraintype+"_background_3.bmp",1+16+32)
boxtex4 = LoadTexture(terraintype+"_background_4.bmp",1+16+32)
boxsprite1 = CreateSprite()
boxsprite2 = CreateSprite()
boxsprite3 = CreateSprite()
boxsprite4 = CreateSprite()
EntityTexture boxsprite1,boxtex1
EntityTexture boxsprite2,boxtex2
EntityTexture boxsprite3,boxtex3
EntityTexture boxsprite4,boxtex4
ScaleSprite boxsprite1,1920/10,1080/10
ScaleSprite boxsprite2,1920/10,1080/10
ScaleSprite boxsprite3,1920/10,1080/10
ScaleSprite boxsprite4,1920/10,1080/10
SpriteViewMode boxsprite1,2
SpriteViewMode boxsprite2,2
SpriteViewMode boxsprite3,2
SpriteViewMode boxsprite4,2
PositionEntity boxsprite1,0,0,192
PositionEntity boxsprite2,-192,0,0
PositionEntity boxsprite3,0,0,-192
PositionEntity boxsprite4,192,0,0
pivot = CreatePivot()
PointEntity boxsprite1,pivot
PointEntity boxsprite2,pivot
PointEntity boxsprite3,pivot
PointEntity boxsprite4,pivot
FreeEntity pivot
EntityFX boxsprite1,25
EntityFX boxsprite2,25
EntityFX boxsprite3,25
EntityFX boxsprite4,25
TurnEntity boxsprite1,0,180,0
TurnEntity boxsprite2,0,180,0
TurnEntity boxsprite3,0,180,0
TurnEntity boxsprite4,0,180,0
EntityOrder boxsprite1,10
EntityOrder boxsprite2,10
EntityOrder boxsprite3,10
EntityOrder boxsprite4,10
Repeat
TurnEntity pcamera,0,.1,0
RenderWorld
Color 15,15,15
Rect 0,900,1920,180,1
Color 190,190,190
If font = 0 Then font = LoadFont("Arial",30)
If font<>0 Then SetFont font
Text 10,1000,"This SkyBox Was Generated By First Rendering Millions of Foliage elements to bitmap in blitz, then setting the renders as textures for four simple sprite elements"
Text 10,1040,"Technically this could be done with anything, not just trees and foliage. You could render a scene of billions of polygons as a skybox, as long as you happy to wait."
Flip
Delay 15
Until KeyHit(1)

End

Matty

#34
Excuse the low resolution video quality - unfortunately I'm using a 10 year old PC to make this, which was not the fastest PC to start with and so capturing video is difficult if the machine is already working pretty hard to render frames for a game.....but I think you should be able to see what's going on.



Matty


Matty

#36


The method/algorithm is very simple:

You have your update loop as per normal.

Then in your 'rendering' section of the code you do this:

;set the camera for the very first render to clear the zbuffer and colour buffer
cameraclsmode camera,true,true
;hide all the entities in the game except for the main level/background entity.
renderworld
;set the camera mode for all subsequent renderworlds to not clear the zbuffer or colour buffer
cameraclsmode camera,false,false
;then for example - you have a single 'knight' entity that was loaded, but you want 10,000 of them
;on the map....
showentity knightmesh
for i = 1 to 10000
  positionentity knightmesh,knightx,knighty,knightz
rotateentity knightmesh...etc..etc
setanimtime knightmesh,whatever frame it should be on
renderworld
next
hideentity knightmesh
;and then repeat for all the other 'things' in the game.....
;by not clearing the zbuffer or colour buffer blitz will simply render that single model, as long as it
is the only one not hidden, into its right position, depth sorted and lit etc, correctly.
You can do thousands of models this way...and by using setanimtime you can have each of them
in a different pose.
The key thing is to only have a single entity unhidden for every renderworld.

Matty

Here are some smaller skirmishes where it's a bit easier to see what's going on in the combat....



This uses one of the hidden modes in my game that lets me get the computer to play battles against itself with various sized forces, in this case small skirmishes.

Matty

I kind of have to stop further development on this for the following basic reasons:

1. I lack the skills to polish the current elements of the game without adding mess to the game in the same way as a window cleaner who has only dirty rags can't clean the windows further no matter how much effort they apply.

2. Certain features that the game would benefit from such as a strategy map mode I can't add because I lack the skill to keep the quality consistent with the battle mode if I did.

I've only got the skills to produce what I've already produced. Additional features or attempts to polish will only make a mess of what's already there. I simply lack the skills to enhance things without making a mess of it. So I have to leave it as it is currently and declare it 'finished'. Any further work by me will only make it worse not better. Like a cleaner whose cleaning cloths are all dirty, and there's no fresh water to replace them with.

Matty

Some minor graphical enhancements....

skybox, grass changes, fog changes...







Matty

Isn't it just the way coding goes:

I optimise huge sections of the program so that it runs well on my machine and the - once I've got it running at a decent speed, I start adding sufficient extra content to slow it down again.

It's like when management wants you to clear away the garbage from an area - merely so they can use it to store new garbage that's just come in.

Matty

And why is it that my best products/games have my worst, ugliest, poorly designed code that breaks every rule while any product I create that is coded in a 'beautiful manner' following all sorts of proper conventions are usually totally uninteresting products in the end.

Matty

Game Link

A few more little magical effects:

The blue overlay and other such effects, including the shadows, are now done by rendering the models with coloured fog that is limited to their entity only.


Matty

Game Link

Latest work on my video:

Things completed include:
Optimisations and performance enhancements and automatic adjustments in game.
Magic effects for some of the cards.
Trees and vegetation outside the main playing area.
Shadows that look better than they did before and with less performance hit.