Lab 6 Intro to 3D Graphics

advertisement
Lab 6
Intro to 3D Graphics
This tutorial is taken from Ray Diaz
http://www.blitzbasic.com/Community/posts.php?topic=27913
And also samples code from Grant McGregor's StarWars3D program (on CSIS 196.1
website)
Battle001
CREATING A SIMPLE GAME IN 3D
Chapter I: The Scenery
Overview: In order to create a game we need to provide several items that will give a
backbone to the project:
 The environment for our characters
 The characters
 The Plot
These three basic aspects can be defined as follows:



The environment for our characters: The world they live in, and a way to see
what they do.
The characters: Good guys, bad guys, fill-in guys
The plot : The rules of the game, as well as the story.
The environment consists of
 The graphic setting
 The Lights
 Pivots
 Our Eyes: The camera
 The Sky
 The Floor (or terrain)
 Props
The Graphic Setting
{graphics3d width,height,depth,mode}1
{Setbuffer buffer}
CODE
;graphics
Remarks
We have chosen 800 x 600, leaving the
1
The curly braces are quotations from the help manual. If you are not familiar with the command, refer
to the help manual when the command is first mentioned to gain a better insight of the operation being
carried out. Checking the help manual and trying out the examples will give you more confidence with
the system
1
Graphics3D 800,600
SetBuffer BackBuffer()
depth and mode to Blitz.
We have chosen the back buffer as our
drawing buffer
The Light
{createlight([type][,parent]}
(RotateEntity entity,pitch#,yaw#,roll#[,global]
CODE
REMARKS
;light
We have created a directional light by
Global light = CreateLight()
default, with no parents, and rotated it 90
RotateEntity light, 90,0,0
degrees to obtain light from above
If you do not rotate the light it gives a dark hue. And if you rotate it 45 degrees it
gives a sort of twilight.
A pivot : the camera pivot
{createpivot(parent}
{entityRadius,entity,x#_radius[,y#_radius]}
{entityType,entity,collision_type)
We will create a pivot essentially to control the camera and other entities, such as the
sky, so that when the pivot moves it will move the camera and the sky.
The “entity radius” feature will be used to calculate collisions later.
The “entity type” determines a category of entity used for collision checking.
CODE
Remarks
;CAMERA PIVOT
Create the pivot, give it a radius
camera_pivot= CreatePivot()
(basically how fat and tall it will be), and
EntityRadius camera_pivot,1.4
a type of PLAYER, which is defined in
EntityType camera_pivot,PLAYER
the global declarations as a number 2
Global PLAYER = 2
Collision Groups
Collision groups will become important later; for now, we will just build a “Collisions
Group” list below the Graphics entries.
Code
Remarks
;Collision Groups
Global PLAYER = 2
Our eyes, the camera
{CreateCamera (parent)}
{cameraRange camera,near,far}
{CamerafogMode,entity,mode}
{CameraFogRange,entity,near,far}
CODE
;CAMERA
Global camera = CreateCamera(camera_pivot)
CameraRange camera,1,1000
CameraFogMode camera,1
CameraFogRange camera,60,200
REMARKS
Create a camera that will move
when the camera pivot moves.
In addition, set the parameters
for range and fog.
2
We could look into our program if we wanted to, but we would see nothing yet. Once
we have the ground and the sky, we will be able to look on a new world.
The Sky
{createSphere(segments)[,parent]
{FlipMesh mesh}
{ScaleEntity entity,x#_scale,y#_scale,z#_scale)[,global]}
{PositionEntity entity,x#,y#,z# [,global]}
{LoadTexture(File$[,flags])}
{EntityTexture entity,texture}
The technique used to create a credible sky is FlipMesh, a
command that flips the triangles of a mesh so you can see the
inside. We need any suitable sky picture for a texture. The one
we used here was in the samples provided with Blitz3d, a 256 x
256 file in bmp format called “sky.bmp”
CODE
;SKY
Global sky = CreateSphere(16,camera_pivot)
FlipMesh sky
ScaleEntity sky,100,100,100
PositionEntity sky, 0,50,0
sky_tex = LoadTexture("sky.bmp")
EntityTexture sky,sky_tex
REMARKS
We create a reasonable sphere with 16
segments, and specify the camera pivot as
the parent, so that when the camera
moves, the sky will move with it.
Otherwise we might run out of sky very
soon.
Then we flip the mesh sky, scale it up to
100 times its original size, and position it
50 units high.
Next, we create a texture from the bit
map “sky”, with no special flags, and
apply the texture to the mesh.
The Terrain
{loadterrain(file$[,parent])}
{terraindetail(detail_level[,vertex_morph])}
Height2.jpg
Code
;TERRAIN
Global terrain = LoadTerrain("height2.jpg")
TerrainDetail terrain,2500,True
ScaleEntity terrain, 3,15,3
Mossyground.bmp
Remarks
We load a “height map” as a terrain.
This is a black and white bmp file where
white is high, black is low, and shades of
gray are differences in height.
The terrain detail was set at 2500, with
vertex morphing.
Due to the nature of terrains, we make the
3
PositionEntity terrain,-1000,0,-530
ter_tex = LoadTexture("mossyground.bmp")
EntityTexture terrain,ter_tex
EntityRadius terrain,0.2
EntityType terrain,SCENERY
Amend the Collisions groups as follows
Code
;collision groups
Global SCENERY = 1
Global PLAYER = 2
y dimension 15 times bigger, while
making the x and z dimensions only 3
times bigger
Next, we position the terrain under us so
that we are well within it, not at the edge.
We chose the famous “mossy ground”
texture from the help file, media folder.
Apply it, and finally establish a radius for
the terrain of 0.2 so that we can check
collisions Finally, make a type
SCENERY, defined in globals as = 1
Remarks
We have two groups for the moment.
We will position the camera a bit above ground to see the scenery:
CODE
REMARKS
PositionEntity Camera_pivot 0,10,120
This places the camera 10 units above
ground level
The Game Loop
Now we need a game loop to see our creation so far:
{MoveEntity entity,x#,y#,z#}
{TurnEntity entity x#,y#,z#}
{updateWorld}
{renderWorld}
CODE
;main loop
While Not KeyHit(1)
If KeyDown(200) MoveEntity camera_pivot,0,0,0.05
If KeyDown(208)MoveEntity camera_pivot,0,0,-0.05
If KeyDown(203) TurnEntity camera_pivot,0,2,0
If KeyDown(205)TurnEntity camera_pivot,0,-2,0
REMARKS
The side cursor keys
will turn the camera,
and the forward and
backward cursor keys
will let you fly over
the terrain.
UpdateWorld
RenderWorld
Flip
Wend
End
Run the program.
This is a new, empty green world, which we will develop further in the next chapters.
4
Summary Of Resources:
Sky.bmp
Height2.jpg
Mossyground.bmp
Battle001.bb
256 x 256 BMP file
256 x 256 JPG file
256 x 256 BMP file
Blitz 3d source file
Radius65
Sept ‘03
Run the demo program ModifiedBattle001.bb. (Initially the same as Battle001.bb)
Move around using arrow keys. Then try the following Modifications:
1.
Under Light…change the rotation:
2.
Read help entry on RotateEntity
3.
Open RotateCone.bb, play with pitch, roll, yaw
4. Add these lines to
RotateEntity light, 90,0,0
ModifiedBattle001.bb under ;Position the camera
;Position the camera
PositionEntity camera_pivot,0,10,120
; Create and position cone
ADD
cone=CreateCone( 32 )
ADD
PositionEntity cone,0,10,140 ADD
5. Add more manueverability to
Play with cone
position and size
ModifiedBattle001.bb
;main loop
While Not KeyHit(1)
If KeyDown(200) MoveEntity camera_pivot,0,0,0.05
If KeyDown(208)
MoveEntity camera_pivot,0,0,-0.05
If KeyDown(203) TurnEntity camera_pivot,0,2,0
If KeyDown(205) TurnEntity camera_pivot,0,-2,0
If KeyDown(31) TurnEntity camera_pivot,2,0,0
ADD
If KeyDown(32) TurnEntity camera_pivot,-2,0,0
ADD
If KeyDown(44) MoveEntity camera_pivot,0,0.05,0 ADD
If KeyDown(45) MoveEntity camera_pivot,0,-0.05,0 ADD
up arrow forward
down arrow backward
left arrow turn left
right arrow turn right
letter s pitch back (up)
letter d pitch fwd (dn)
letter z move up
letter x move down
NOTES
A) change the steps sizes is for larger jumps. Can you reach the edge of the world?
B) How does the terrain map change the landscape?
C) Magnify the vertical scale of the terrain map. Find this line:
ScaleEntity terrain, 3,15,3
(change 15 to 50…what happens?)
D) Set the scale back to 15 before doing next steps
5
Battle002
CREATING A SIMPLE GAME IN 3D
CHAPTER II
Keeping Your Feet On The Ground


Overview: We are exploring the elements that will give a backbone to our project:
The environment, the characters, and the plot. So far, we have seen the environment
and created the graphic setting, the lights, a pivot, the camera, the sky, and the
floor (or terrain).
In this chapter we will begin by arming our hero, then we will take care of
gravity in our world, discuss how to get our bearings, and we will plant down
some floors to mark our first four settlements.
Give the man a weapon
Thanks to Psionic3d Design Resources (www.psionic3D.co.uk) we can use
a 3D model of a gun, so that our hero does not go out defenseless. These
are the commands you should look up in the help files:
{Loadmesh(filename$[,parent])}
{entityOrder, entity,var}
Glocmap.jpg
Add the following lines after Terrain and before Position the camera:
CODE`
REMARKS
;WEAPON psionic3d
The commands used are falling
into a repetitive sequence:
Global weapon2 = LoadMesh("gloc.3ds",camera_pivot)
 Load mesh,
weapon_tex2 = LoadTexture("glocmap.jpg")
 Load texture,
EntityTexture weapon2,weapon_tex2
 Assign it to the gun,
RotateEntity weapon2,12,170,14
 Rotate the entity until you are
satisfied with the way the
gun looks
ScaleEntity weapon2,0.01,0.01,0.01
 Scale the gun so that it looks
reasonable
PositionEntity weapon2,1,-1,1.5
 Position the entity where you
can see it (in this case a bit
behind the camera, so that
you only see part of it).
EntityOrder weapon2, -1
The “entityOrder” command allows
the weapon to be drawn last. The
reason for this is to prevent the
gun from “sinking” into other
props.
Because we are too high over the ground we should reposition ourselves a bit lower, to walk
the earth:
Change the position entity camera pivot command to
PositionEntity camera_pivot,0,5.6,120
This will put us 5.6 units above ground.
Go walking around
6
As we run the program we see an impressive mossy ground topped by a blue sky, and
we see ourselves with a powerful gun in our hands. Full of self-confidence we start to
move… and we go right through the moss. Our character is not responsive to the up
and downs of the world. To solve this we need to reposition our camera pivot each
time we move. This is the method given in the B3D help files, using the terrainY
figure, which controls the terrain height.
Let us say you are looking at a map on your desk. To your left is West, to your right is
East, North is upwards, and South is downward. The distance from your eyes to the
printed page is the Height (UP). In 3D coordinates these cardinal points are defined as
follows:
West = -X (negative
values of X)
East = +X (positive
values of X)
North = +Z (positive
values of Z)
South = -Z (negative
values of Z)
Height +Y (positive
values of Y)
If you went under the
table and looked up, that would be a negative value of Y. And that is what is
happening to our man: He is sinking under the ground.
To correct this, we need to add some lines of code:
Declare some globals right under graphics:
;GLOBALS
Global x#,y#,z#,terra_y#
Add the following code inside the main loop:
{EntityX(entity[,global])}
{EntityY(entity[,global])}
(EntityZ(entity[,global])}
{TerrainY(terrain,x#,y#,z#)}
Code
x#=EntityX(camera_pivot)
y#=EntityY(camera_pivot)
z#=EntityZ(camera_pivot)
Remarks
The current x value of the camera pivot
The current Y value of the camera pivot
The current Z value of the camera pivot
Terra y# will take the resulting value of
the composite TerrainY, which is an
aggregate of the terrain values of x, y,
and z, plus 1.6. Now, terrainY is equal to
the terrain height at that particular point.
Adding 1.6 on top ensures that the
camera pivot will be ABOVE it by that
much every cycle.
terra_y#=TerrainY(terrain,x#,y#,z#)+1.6
7
PositionEntity camera_pivot,x#,terra_y#,z#
Add these lines after Update World
After we add those lines to our main loop our hero will never sink under the ground
for long. If the ground is quite wild you may have to adjust the 1.6 value a bit. Try it.
NOTES
A) When you are ready, scale the terrain back to 50 or even 100 pr 200 and see what
happens. Can you still rise up and down (z and x keys) can you look up or down (s
and d keys)
Populating the world. Lets make a moving object
Grant has done some terrific work creating star wars models in his 3D star wars game (see
online). This code creates a tie fighter from spheres and cylinders linked together:
Code
Remarks
; create and position tie fighter
ball = CreateSphere ()
ScaleEntity ball, 0.5, 0.5, 0.5
RotateEntity ball, 90, 0, 90
PositionEntity ball, 10, 10, 170
sphere at core of fighter
pole = CreateCylinder (18, True, ball)
ScaleEntity pole, 0.25, 2.5, 0.25
the central pole in fighter
twing = CreateCylinder (6, True, pole)
ScaleEntity twing, 15, 0.1, 15
RotateEntity twing, 0, 30, 0
PositionEntity twing, 0, -1, 0
the hexagonal side panel
twing2 = CopyEntity (twing, pole)
PositionEntity twing2, 0, 1, 0
the other hex panel
Copy and paste it into the program after where you created and positioned the cone.
In order to make it move, add the following line at the bottom of the main game loop, before
UpdateWorld:
TranslateEntity ball, 0, 0, -0.2
Now run the game and watch the tie fighter fly by. You can play with modifying the camera
movement routines to be able to chase the tie fighter.
THAT'S IT!!!
Hope you enjoyed the class! If you liked this, and want to explore
programming further, check out in the spring:
CSIS 10A Beginning C++ programming
Tue/Thur 11:30 to 2 Starts 1/31/06
8
Download