WIP 3D Engine [v0.06] (v0.07 preview screenie)
-
- Posts: 8641
- Joined: May 28, 2005 3:28
- Contact:
For an infinity ground you need a good and fast FILTER
here one example without a FILTER.
Joshy
here one example without a FILTER.
Joshy
Code: Select all
const ScreenWidth = 640
const ScreenHeight= 480
type VECTOR3D
as single x,y,z
as single w
end type
type PLANE_t
as VECTOR3D Position
as VECTOR3D Normale
as VECTOR3D A
as VECTOR3D B
as single MaxWidth,NP,DN
as single al,be,ga
end type
dim shared Plane as PLANE_t
dim shared Texture as integer ptr
' 2x2 pixel in this case
sub CreateTexture()
if Texture<>0 then return
Texture=callocate(2*2*4)
Texture[0]=&HFFFFFF
Texture[2]=&HFFFFFF
end sub
sub VecRotate( _
byref RetVec as VECTOR3D, _
SrcVec as VECTOR3D, _
a as single, _
b as single, _
g as single)
a*=atn(1)/45
b*=atn(1)/45
g*=atn(1)/45
dim as single cox = Cos(a), coy = Cos(b), coz = Cos(g)
dim as single six = Sin(a), siy = Sin(b), siz = Sin(g)
dim as single Y = SrcVec.Y * cox - SrcVec.Z * six
dim as single Z = SrcVec.Y * six + SrcVec.Z * cox
dim as single X = SrcVec.X * coy + Z * siy
RetVec.Z =-SrcVec.X * siy + Z * coy
RetVec.X = X * coz - Y * siz
RetVec.Y = X * siz + Y * coz
end sub
const MiddleWidth = ScreenWidth *0.5
const MiddleHeight= ScreenHeight*0.5
const ScaleInv = 1/ScreenWidth
Function ShowPoint(X as integer, _
Y as integer) as integer
dim as VECTOR3D ODES=any,HitP=any
dim as single L=any ' length of ray if hits
dim as integer u=any,v=any ' texture coords
' shot a ray thrue every pixel
With ODES
.X = (X-MiddleWidth ) * ScaleInv
.Y = (MiddleHeight-Y) * ScaleInv
.Z = 1
End With
With Plane
' dot = ray * plane normale
.DN=ODes.x*.Normale.x _
+ODes.y*.Normale.y _
+ .Normale.z ' rey.destination.z is = 1
if .DN=0 then return &H5555CC
L= .NP/.DN ' parallel or far away
if (L<1) or (L>.MaxWidth) then return &H5555CC
' get ray hitpont
HitP.x=ODes.x*L-.Position.x
HitP.y=ODes.y*L-.Position.y
HitP.z= L-.Position.z
' rotate it back in camera space
VecRotate HitP,HitP,-.al,-.be,-.ga
' optional get texture coords
u=abs(HitP.x/.MaxWidth)*128
v=abs(Hitp.z/.MaxWidth)*128
' texture is in this case 2x2
u and=1:v and=1':u shl=1
end with
return texture[u+v]
End Function
sub Render
dim as integer ptr lpScreen
lpScreen=screenptr
For y as integer=0 to ScreenHeight-1
For X as integer=0 to ScreenWidth-1
*lpScreen=ShowPoint(x,y)
lpScreen+=1
next
next
end sub
'
' main
'
dim as single w
dim as double t1,t2
dim as integer frames,fps
ScreenRes ScreenWidth,ScreenHeight,24,,1
CreateTexture
Plane.MaxWidth=ScreenWidth*4
t1=timer
while inkey<>chr(27)
With Plane
.Normale.x=0:.Normale.y=1:.Normale.z=0
.A.x =0:.A.y =0:.A.z =1
.B.x =1:.B.y =0:.B.z =0
VecRotate .Normale,.Normale,.al,.be,.ga
VecRotate .A ,.A ,.al,.be,.ga
VecRotate .B ,.B ,.al,.be,.ga
.NP=.Normale.x*.Position.x _
+.Normale.y*.Position.y _
+.Normale.z*.Position.z
screenlock:cls
Render
locate 1,1:print fps
screenunlock
' camera
.Position.y=sin(w*3)*300-350
.al=sin(w*2.0)*1
.be=cos(w )*360
.ga=sin(w*0.5)*5
w+=0.005:if w>(atn(1)*8) then w=0
end with
frames+=1
if frames=100 then
t2=timer
fps=frames/(t2-t1)
t1=t2:frames=0
end if
wend
end
MESSAGE FOR MODERATORS :
thanks for the change :)
D.J. Peter > Thanks for the code :) Since Mip-mapping and filtering are on my todo list, your code will be really useful :) thanks, I'll "analyze" it.
Engine News :
Before starting optimizations, I wanted to modularize and reorganize a bit my code to help comprehension. So here are the news :
- Modularization : code broken into smaller header files (Engine.bi, DataTypes.bi, Materials.bi)
- Texture BMP loader
- Backface Culling
- /!\ New material Type to handle .. well, materials :p
+ Effective way (I hope) to create/edit materials in code
- Texture tiling routine
- Changed textures of the example for realistic ones
An example of material editing :
Code:

thanks for the change :)
D.J. Peter > Thanks for the code :) Since Mip-mapping and filtering are on my todo list, your code will be really useful :) thanks, I'll "analyze" it.
Engine News :
Before starting optimizations, I wanted to modularize and reorganize a bit my code to help comprehension. So here are the news :
- Modularization : code broken into smaller header files (Engine.bi, DataTypes.bi, Materials.bi)
- Texture BMP loader
- Backface Culling
- /!\ New material Type to handle .. well, materials :p
+ Effective way (I hope) to create/edit materials in code
- Texture tiling routine
- Changed textures of the example for realistic ones
An example of material editing :
Code:
Code: Select all
Dim as ObjectT MyObject
MyObject.GenerateCube(x0,y0,z0,SideSize)
Dim as TextureT CubeTex
CubeTex.LoadBMP "Texture_Cube.bmp"
Dim as MaterialT CubeMaterial
CubeMaterial.Edit
Mat_Shader GOURAUD_SHADER
Mat_Texture CubeTex,tileX,tileY
Mat_Diffuse r,g,b
Mat_ambient r,g,b
CubeMaterial.End_Edit
MyObject.Assign_Material CubeMaterial

Big update :)
I'm now on the v0.4 and a lot of things changed since the previous version :)
A screenshot :

I don't really know which version I lastly posted here but here are the last changes :
You can move in the world with the keyboard arrows (left/right control the camera angle)
Download :
Engine v0.04
Could you please tell me how many FPS you got ?
thanks :D
I'm now on the v0.4 and a lot of things changed since the previous version :)
A screenshot :

I don't really know which version I lastly posted here but here are the last changes :
v0.04 Changes List
MAJOR :
- Big Optimization with the Shaders calculations.
> Shaders are now calculated only on visible triangles
- Big Optimization while computing mipMap level
> MipMap level is now calculated only once per scanline
- Camera Rotation handling.
> Camera can now rotate according to Y axis and X axis
- Added Init_Engine Sub.
> User can now choose desired resolution
- Added GenerateTore Sub.
> object.GenerateTore(x0,y0,z0,r1,r2,nbfaces)
- material Ambient is modified when Diffuse is modified.
> Can still modify the ambiant after the diffuse modification.
Minor :
- Camera can now translate in world space or in View space
> Move_Camera X,Y,Z, SPACE (IN_VIEWPOS or IN_WORLD)
- Fixed a bug with the Z-Buffer handling
- Fixed a bug in the untextured rendering
You can move in the world with the keyboard arrows (left/right control the camera angle)
Download :
Engine v0.04
Could you please tell me how many FPS you got ?
thanks :D
12fps 800-830 triangles
Ati x1400 w/256mb
T7200 Dual Core
1gb system ram.
Looks good, but even at like 10 triangles, I only got 30fps.
Have you tried to pregen your Sin and Cos tables?
Oh and lol. I love the loops in the Generate Floor function.
Ati x1400 w/256mb
T7200 Dual Core
1gb system ram.
Looks good, but even at like 10 triangles, I only got 30fps.
Have you tried to pregen your Sin and Cos tables?
Oh and lol. I love the loops in the Generate Floor function.
Code: Select all
for i as integer = -1 to 1
if i=0 then i=1
for j as integer = -1 to 1
if j=0 then j=1
Flo.Triangle(Flo.nb_triangles).Vertex(0).pos3d.x = i*lSize+lSize
Flo.Triangle(Flo.nb_triangles).Vertex(0).pos3d.y = 0
Flo.Triangle(Flo.nb_triangles).Vertex(0).pos3d.z = j*lSize+lSize
Flo.Triangle(Flo.nb_triangles).Vertex(0).U = 1
Flo.Triangle(Flo.nb_triangles).Vertex(0).V = 0
Flo.Triangle(Flo.nb_triangles).Vertex(1).pos3d.x = i*lSize-lSize
Flo.Triangle(Flo.nb_triangles).Vertex(1).pos3d.y = 0
Flo.Triangle(Flo.nb_triangles).Vertex(1).pos3d.z = j*lSize+lSize
Flo.Triangle(Flo.nb_triangles).Vertex(1).U = 0
Flo.Triangle(Flo.nb_triangles).Vertex(1).V = 0
Flo.Triangle(Flo.nb_triangles).Vertex(2).pos3d.x = i*lSize-lSize
Flo.Triangle(Flo.nb_triangles).Vertex(2).pos3d.y = 0
Flo.Triangle(Flo.nb_triangles).Vertex(2).pos3d.z = j*lSize-lSize
Flo.Triangle(Flo.nb_triangles).Vertex(2).U = 0
Flo.Triangle(Flo.nb_triangles).Vertex(2).V = 1
Flo.Triangle(Flo.nb_triangles+1).Vertex(0).pos3d.x = i*lSize+lSize
Flo.Triangle(Flo.nb_triangles+1).Vertex(0).pos3d.y = 0
Flo.Triangle(Flo.nb_triangles+1).Vertex(0).pos3d.z = j*lSize+lSize
Flo.Triangle(Flo.nb_triangles+1).Vertex(0).U = 1
Flo.Triangle(Flo.nb_triangles+1).Vertex(0).V = 0
Flo.Triangle(Flo.nb_triangles+1).Vertex(1).pos3d.x = i*lSize-lSize
Flo.Triangle(Flo.nb_triangles+1).Vertex(1).pos3d.y = 0
Flo.Triangle(Flo.nb_triangles+1).Vertex(1).pos3d.z = j*lSize-lSize
Flo.Triangle(Flo.nb_triangles+1).Vertex(1).U = 0
Flo.Triangle(Flo.nb_triangles+1).Vertex(1).V = 1
Flo.Triangle(Flo.nb_triangles+1).Vertex(2).pos3d.x = i*lSize+lSize
Flo.Triangle(Flo.nb_triangles+1).Vertex(2).pos3d.y = 0
Flo.Triangle(Flo.nb_triangles+1).Vertex(2).pos3d.z = j*lSize-lSize
Flo.Triangle(Flo.nb_triangles+1).Vertex(2).U = 1
Flo.Triangle(Flo.nb_triangles+1).Vertex(2).V = 1
Flo.nb_triangles +=2
next
next
Can you do these tasks in parallel? If one task needs the output of another task as its input, then they cannot be run in parallel, and threads would not help.Hezad wrote:Hey :)
I just wondered something ... Couldn't I win some FPS by running subs in different threads ?
eg : the different filling procedures in a thread A, Shaders processing in a thread B, and filtering in a thread C ?
I imagine your code (I have not inspected it) is something like a pipeline, where each task's input is the output of the previous task; in this case, it is not easy to run two tasks in parallel. However, perhaps you can find some tasks where this is not the case; this would be the place to try threads first. If not, you could try splitting a task into smaller units of work that could be done in parallel (render half the screen in one thread and the other half in another, for example), but this will not be nearly as easy.
-
- Posts: 2338
- Joined: May 31, 2005 9:59
- Location: Croatia
- Contact:
thanks for the replies :)
@Alterac
Nope. I should but I hadn't done it yet :P
? lol what's the problem ? I use i and j to add an offset on each quarter of the floor(the floor is composed of 4 quads / 8 triangles).
@DrV
Thanks :) All my procedures use the previously computed procedure indeed. hm.. so threads seem unusable in my case. I'll think about splitting task into smaller units usable in parallel.
@Lachie
Thanks for feedback :)
I see the engine runs between 12 and 20 FPS .. I still have optimizations to do ><
@Alterac
Code: Select all
Have you tried to pregen your Sin and Cos tables?
Code: Select all
Oh and lol. I love the loops in the Generate Floor function.
@DrV
Thanks :) All my procedures use the previously computed procedure indeed. hm.. so threads seem unusable in my case. I'll think about splitting task into smaller units usable in parallel.
@Lachie
Thanks for feedback :)
I see the engine runs between 12 and 20 FPS .. I still have optimizations to do ><
No problem with the loops, It just made me smile :D
and on your threads idea, you could probally spawn your rotateobj as a thread.
As long as it all completes before you draw the object.
oh, and oddly enough if I dont Project_object floor I get a 8fps boost.
Of all the objects, removing the floor is the one that makes a nice difference.
I have been tinkering with it quite a bit, and noticed its not your rotate functions that are slowing things down.
Its the projection function.
I can rotate all 21 of the little squares and only lose 1fps, but if I start removing objects it speeds it up greatly.
It also doesnt seem to matter if its texture mapped, or gourad shaded.
and on your threads idea, you could probally spawn your rotateobj as a thread.
As long as it all completes before you draw the object.
oh, and oddly enough if I dont Project_object floor I get a 8fps boost.
Of all the objects, removing the floor is the one that makes a nice difference.
I have been tinkering with it quite a bit, and noticed its not your rotate functions that are slowing things down.
Its the projection function.
I can rotate all 21 of the little squares and only lose 1fps, but if I start removing objects it speeds it up greatly.
It also doesnt seem to matter if its texture mapped, or gourad shaded.
Thanks for feedback and for all your tests Alterac :)
in order :
- Camera Space transformation
- First Clipping (suppress objects lying totally outside the frustum)
- BackFace Culling
- Shading
- Clipping (chopping triangles lying ON the frustum, this one is very laggy)
- Projection
- Rendering
I should change the name of this sub since it's not only the projection anymore :P But since almost everything is calculated in the project_object sub, it's normal all the FPS loss come from it.
Thanks again for your tests :)
okay ^^ Sorry then, I thought you noticed something wrong in it :)No problem with the loops, It just made me smile :D
Well I'll try this but as you said, the rotations are not the procedures which really make the program to slow down.and on your threads idea, you could probally spawn your rotateobj as a thread. As long as it all completes before you draw the object.
Yep And I think it's because of my clipping function since the floor is the only object which is almost always clipped. I must work on it but I don't really know what to change in it for now.oh, and oddly enough if I dont Project_object floor I get a 8fps boost.
Of all the objects, removing the floor is the one that makes a nice difference.
Normal, the project_object sub is in fact the procedure calling all the rendering pipeline for each object :Its the projection function.
I can rotate all 21 of the little squares and only lose 1fps, but if I start removing objects it speeds it up greatly.
in order :
- Camera Space transformation
- First Clipping (suppress objects lying totally outside the frustum)
- BackFace Culling
- Shading
- Clipping (chopping triangles lying ON the frustum, this one is very laggy)
- Projection
- Rendering
I should change the name of this sub since it's not only the projection anymore :P But since almost everything is calculated in the project_object sub, it's normal all the FPS loss come from it.
Thanks again for your tests :)