Ok I have been having difficulty working out why my 3d in 2d code isnt working so I took one of the very early blitz samples I made and tried that but it's also giving me strange results, so here's the code, can anyone point out whats wrong with it, the blitz version works but this one gives a wierd display as per attached exe.
'-------------------------------------------------------------------
' The Tin Dragons
' Wireframe Test
'
' by Joncom2000 May2006
'-------------------------------------------------------------------
#define PTC_WIN
#include "ttdblitzlibv1.bi"
'-------------------------------------------------------------------
' Wireframe test
'-------------------------------------------------------------------
TTDGraphics(640,480,"TTD Test App")
'-------------------------------------------------------------------
' Setup Variables
'-------------------------------------------------------------------
dim shared numpoints as integer ' Number of points in the point table.
dim shared numconn as integer ' Number of connections in the connect table.
dim shared distance as double ' Used to calculate perspective.
dim shared rx as double ' X rotation.
dim shared ry as double ' Y rotation.
dim shared rz as double ' Z rotation.
dim shared cx as integer ' Centre offset x
dim shared cy as integer ' Centre offset y
cx=640/2
cy=480/2
distance = 512
declare Sub rotate3d()
declare Sub draw3d()
' Read data for 3d.
Read numpoints ' Read in the number of points in the object
Dim shared points(numpoints, 2) as double ' Holds the point locations of the 3d object.
Dim shared xpos(numpoints) as integer
Dim shared ypos(numpoints) as integer
For n = 1 To numpoints
Read x, y, z
points(n, 0) = x
points(n, 1) = y
points(n, 2) = z
Next
Read numconn ' Read in the numer of connections in the 3d object
Dim shared lines(numconn, 1) as integer ' Holds the connections of the 3d a to b.
For n = 1 To numconn
Read a, b
lines(n, 0) = a
lines(n, 1) = b
Next
do
TTDCls(0,0,0)
rotate3d()
draw3d()
TTDFlip()
loop until inkey$<>""
TTDEndGraphics()
end
'-------------------------------------------------------------------
' End Test
'-------------------------------------------------------------------
' --- This rotates a 3d objects points
Sub rotate3d()
dim x,y,z,tx,ty,tz,ox as double
rx =rx + 0.5
ry =ry + 0.5
rz =rz + 0.5
For n = 1 To numpoints
x = points(n, 0)
y = points(n, 1)
z = points(n, 2)
' X rotation
ty = ((y * _cos(rx)) - (z * _sin(rx)))
tz = ((y * _sin(rx)) + (z * _cos(rx)))
' Y rotation
tx = ((x * _cos(ry)) - (tz * _sin(ry)))
tz = ((x * _sin(ry)) + (tz * _cos(ry)))
' Z rotation
ox = tx
tx = ((tx * _cos(rz)) - (ty * _sin(rz)))
ty = ((ox * _sin(rz)) + (ty * _cos(rz)))
' Calculate new x and y location with perspective
xpos(n)=int(tx*(distance/(distance+tz)))+cx
ypos(n)=int(ty*(distance/(distance+tz)))+cy
Next
End sub
' ___ This draws a 3d object
Sub draw3d()
For n = 1 To numconn
TTDFastLine(xpos(lines(n, 0)), ypos(lines(n, 0)),xpos(lines(n, 1)),ypos(lines(n, 1)),255,255,255)
Next
End sub
' Define a cube
Data 8 ' Points in cube
Data -50,-50,50
Data 50,-50,50
Data 50,-50,-50
Data -50,-50,-50
Data -50,50,50
Data 50,50,50
Data 50,50,-50
Data -50,50,-50
Data 12 ' Number of connecting lines
Data 1,2
Data 2,3
Data 3,4
Data 4,1
Data 5,6
Data 6,7
Data 7,8
Data 8,5
Data 8,4
Data 7,3
Data 6,2
Data 5,1
I think it might be something to do with the maths in the rotate3d bit but not sure what.
Can't debug the code for you because there is an include missing, the matrices look fine to me, after running your exe I would guess that it's a problem with your sin and cos data.
well sin and cos and done like this
#define _sin(angle) sin(angle* 3.1415926535897932 / 180)
#define _cos(angle) cos(angle* 3.1415926535897932 / 180)
So I cant see why they would be wrong, I am converting the degrees to radians ?
The include is basicly wrapper commands for ptc open and update with other stuff to do the pixel drawing and the line command works fine when place in your test and in every 2d test I have done so I am sure the error is in this code and not the lib. This isnt the first problem I have encountered, I converted a much more complex 3d routine and had similiar problems which is why I tried this really basic wireframe code and as can be see it aint working as I expect.
Ok I removed all stuff to do with ttdlib and used the code Shockwave has posted for line drawing. Now anyone can test it.
I also discovered there is a problem with TTDFastline drawing certain angle line but TTDLine draws then perfectly all be it slower, so there's still something a miss [EDIT] I am 100% confident in TTDLine I have tested it drawing lines at every possible angle, I am sure the problem lies in the 3d rotation code and think it might be some sort of float to int conversion issue. The code worked in blitz and all I have done is convert it :(
'-------------------------------------------------------------------
' Wireframe Test Using DBF'S code
'-------------------------------------------------------------------
#define PTC_WIN
#define dbfcls redim as integer buffer (640*480)
#define _sin(angle) sin(angle* 3.1415926535897932 / 180)
#define _cos(angle) cos(angle* 3.1415926535897932 / 180)
#Include Once "tinyptc.bi"
option dynamic
'-------------------------------------------------------------------
' DBF declares and open window
'-------------------------------------------------------------------
If( ptc_open( "TTD WIRECUBE", 640, 480 ) = 0 ) Then
End -1
End If
Dim Shared As Integer Buffer( 640 * 480 )
declare sub DBFWPF(BYVAL BX AS INTEGER, BYVAL BY AS INTEGER , BYVAL CH AS INTEGER )
declare sub DBFLINE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER , BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL CR AS INTEGER, BYVAL CG AS INTEGER, BYVAL CB AS INTEGER)
'-------------------------------------------------------------------
' Setup Variables
'-------------------------------------------------------------------
dim shared numpoints as integer ' Number of points in the point table.
dim shared numconn as integer ' Number of connections in the connect table.
dim shared distance as double ' Used to calculate perspective.
dim shared rx as double ' X rotation.
dim shared ry as double ' Y rotation.
dim shared rz as double ' Z rotation.
dim shared cx as integer ' Centre offset x
dim shared cy as integer ' Centre offset y
cx=640/2
cy=480/2
distance = 512
declare Sub rotate3d()
declare Sub draw3d()
' Read data for 3d.
Read numpoints ' Read in the number of points in the object
Dim shared points(numpoints, 2) as double ' Holds the point locations of the 3d object.
Dim shared xpos(numpoints) as integer
Dim shared ypos(numpoints) as integer
For n = 1 To numpoints
Read x, y, z
points(n, 0) = x
points(n, 1) = y
points(n, 2) = z
Next
Read numconn ' Read in the numer of connections in the 3d object
Dim shared lines(numconn, 1) as integer ' Holds the connections of the 3d a to b.
For n = 1 To numconn
Read a, b
lines(n, 0) = a
lines(n, 1) = b
Next
do
rotate3d()
draw3d()
Ptc_Update @Buffer(0)
dbfcls
loop until inkey$<>""
ptc_close
end
'-------------------------------------------------------------------
' End Test
'-------------------------------------------------------------------
' --- This rotates a 3d objects points
Sub rotate3d()
dim x,y,z,tx,ty,tz,ox as double
rx =rx + 0.5
ry =ry + 0.5
rz =rz + 0.5
For n = 1 To numpoints
x = points(n, 0)
y = points(n, 1)
z = points(n, 2)
' X rotation
ty = ((y * _cos(rx)) - (z * _sin(rx)))
tz = ((y * _sin(rx)) + (z * _cos(rx)))
' Y rotation
tx = ((x * _cos(ry)) - (tz * _sin(ry)))
tz = ((x * _sin(ry)) + (tz * _cos(ry)))
' Z rotation
ox = tx
tx = ((tx * _cos(rz)) - (ty * _sin(rz)))
ty = ((ox * _sin(rz)) + (ty * _cos(rz)))
' Calculate new x and y location with perspective
xpos(n)=(tx*(distance/(distance+tz)))+cx
ypos(n)=(ty*(distance/(distance+tz)))+cy
Next
End sub
' ___ This draws a 3d object
Sub draw3d()
For n = 1 To numconn
DBFLINE(xpos(lines(n, 0)), ypos(lines(n, 0)),xpos(lines(n, 1)),ypos(lines(n, 1)),255,255,255)
Next
End sub
sub DBFLINE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER , BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL CR AS INTEGER, BYVAL CG AS INTEGER , BYVAL CB AS INTEGER)
DIM LINEXDV AS DOUBLE
DIM LINEYDV AS DOUBLE
DIM startx AS DOUBLE
DIM starty AS DOUBLE
DIM xdistance AS DOUBLE
DIM ydistance AS DOUBLE
DIM greaterx AS INTEGER
DIM lesserx AS INTEGER
DIM greatery AS INTEGER
DIM lessery AS INTEGER
DIM Lineloopsize AS INTEGER
DIM lineloop AS INTEGER
DIM TOPC AS INTEGER
TOPC = RGB(CR,CG,CB)
If x1 < x2 Then
lesserx = x1
greaterx = x2
Else
lesserx = x2
greaterx = x1
End If
If y1 < y2 Then
lessery = y1
greatery = y2
Else
Lessery = y2
greatery = y1
End If
xdistance = (greaterx-lesserx)
ydistance = (greatery-lessery)
If xdistance=0 THEN xdistance=1
If ydistance=0 THEN ydistance=1
If xdistance>=ydistance Then
lineloopsize = int(xdistance)
Else
lineloopsize = int(ydistance)
End If
LINEXDV=(greaterx-lesserx)/lineloopsize
LINEYDV=(greatery-lessery)/lineloopsize
startx=lesserx
starty=lessery
For lineloop=0 To lineloopsize
DBFWPF (startx,starty,TOPC)
startx=startx+(LINEXDV)
starty=starty+(LINEYDV)
Next
END SUB
SUB DBFWPF (BYVAL BX AS INTEGER , BYVAL BY AS INTEGER , BYVAL CH AS INTEGER)
IF (BX>0) AND (BX<640) AND (BY>0) AND (BY<480) THEN
BUFFER ((BY*640)+BX)=CH
END IF
END SUB
' Define a cube
Data 8 ' Points in cube
Data -50,-50,50
Data 50,-50,50
Data 50,-50,-50
Data -50,-50,-50
Data -50,50,50
Data 50,50,50
Data 50,50,-50
Data -50,50,-50
Data 12 ' Number of connecting lines
Data 1,2
Data 2,3
Data 3,4
Data 4,1
Data 5,6
Data 6,7
Data 7,8
Data 8,5
Data 8,4
Data 7,3
Data 6,2
Data 5,1
Does give a different result to mine but it's still wrong.
Your matrix works, I changed it to draw dots and they rotate fine.
There may be a problem with the line draw.
Hmm, as I thought! I just tested the line draw in my own 3D routine and it's broken.
Your code is fine Jon, the line draw code is fucked.
My bad.
Also looks like your lib made the same mistake too. I ported my line draw command from one I wrote in Blitz, I'll need to fix it.
I have tried 3 different line drawing functions, while I know my TTDFastline is borked the other one draws lines at any angle so I can't see why it doesnt work in this code. Strange how your line draw seems out as well, both I coded work fine in blitz as well.
Zawran to the rescue, he sent me a line draw he coded and it worked, strange thing it was the same as mine really. Still after some deleting and retyping I have a working wirecube, now I am off to bed :cheers:
Glad it's fixed.
You wont believe this but Zawran discovered that it was the order in which 2 variables were defined, switch them round and it draws wrong, change them back at it works. No idea why but it might be something like that in your line draw routine, worth a shot ;)
Ok Jon, thanks for the heads up, I'll check that.
It is really wierd because my source works perfectly in Blitz :)
Yes my source worked in blitz, we used it in the TTD vector lib for lines and alpha lines but it was not correct at all angles in FB, Zawran converted over his version of it and it worked so after some comparison he spotted the difference was 2 variables define in a different order.
Strange one, any chance you could post a bit of code that reproduces this problem and show what's done to solve it?
EDIT:
I think i see your problem shockwave, this bit:
Ã, Ã, Ã, Ã, If x1 < x2 Then
Ã, Ã, Ã, Ã, lesserx = x1
Ã, Ã, Ã, Ã, greaterx = x2
Ã, Ã, Ã, Ã, Else
Ã, Ã, Ã, Ã, lesserx = x2
Ã, Ã, Ã, Ã, greaterx = x1
Ã, Ã, Ã, Ã, End If
Ã, Ã,
Ã, Ã, Ã, Ã, If y1 < y2 Then
Ã, Ã, Ã, Ã, lessery = y1
Ã, Ã, Ã, Ã, greatery = y2
Ã, Ã, Ã, Ã, Else
Ã, Ã, Ã, Ã, Lessery = y2
Ã, Ã, Ã, Ã, greatery = y1
Ã, Ã, Ã, Ã, End If
as well as drawing from x1,y1 to x2,y2Ã, or from x2,y2 to x1,y1Ã, it can sometimes end up drawing from x2,y1 to x1,y2Ã, orÃ, from x1,y2 to x2,y1.
Well I was doing
dim xI, alpha2 as single
Zawran had
dim alpha2, xI as single
and it worked, the rest of the code in our routines was exactly the same. He has since sent me code with it done like this
dim as single xI, alpha2
Which also works if you switch the variables around. Perhaps I have been defineing them incorrectly and for multi dim's it should be like the last method ?
Quote from: Stonemonkey on May 31, 2006
Strange one, any chance you could post a bit of code that reproduces this problem and show what's done to solve it?
EDIT:
I think i see your problem shockwave, this bit:
Thanks Stonemonkey :)
I'll fix it.
If x1 < x2 Then
lesserx = x1
greaterx = x2
Else
lesserx = x2
greaterx = x1
End If
If y1 < y2 Then
lessery = y1
greatery = y2
Else
Lessery = y2
greatery = y1
End If
as well as drawing from x1,y1 to x2,y2 or from x2,y2 to x1,y1 it can sometimes end up drawing from x2,y1 to x1,y2 or from x1,y2 to x2,y1.
Yes tindragon, if you don't specify a datatype then i think it makes it integer so
dim a,b as single
will make a as integer and b as single
to make everything as single you'd do
dim as single a,b
Just so that people can run it, here's Jons source again with my line command (fixed)
'-------------------------------------------------------------------
' Wireframe Test Using DBF'S code
'-------------------------------------------------------------------
'#define PTC_WIN
#define dbfcls redim as integer buffer (640*480)
#define _sin(angle) sin(angle* 3.1415926535897932 / 180)
#define _cos(angle) cos(angle* 3.1415926535897932 / 180)
#Include Once "tinyptc.bi"
option dynamic
'-------------------------------------------------------------------
' DBF declares and open window
'-------------------------------------------------------------------
If( ptc_open( "TTD WIRECUBE", 640, 480 ) = 0 ) Then
End -1
End If
Dim Shared As Integer Buffer( 640 * 480 )
declare sub DBFWPF(BYVAL BX AS INTEGER, BYVAL BY AS INTEGER , BYVAL CH AS INTEGER )
declare sub DBFLINE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER , BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL CR AS INTEGER, BYVAL CG AS INTEGER, BYVAL CB AS INTEGER)
defint a-z
'-------------------------------------------------------------------
' Setup Variables
'-------------------------------------------------------------------
dim shared numpoints as integer ' Number of points in the point table.
dim shared numconn as integer ' Number of connections in the connect table.
dim shared distance as double ' Used to calculate perspective.
dim shared rx as double ' X rotation.
dim shared ry as double ' Y rotation.
dim shared rz as double ' Z rotation.
dim shared cx as integer ' Centre offset x
dim shared cy as integer ' Centre offset y
cx=640/2
cy=480/2
distance = 512
declare Sub rotate3d()
declare Sub draw3d()
' Read data for 3d.
Read numpoints ' Read in the number of points in the object
Dim shared points(numpoints, 2) as double ' Holds the point locations of the 3d object.
Dim shared xpos(numpoints) as double
Dim shared ypos(numpoints) as double
For n = 1 To numpoints
Read x, y, z
points(n, 0) = x
points(n, 1) = y
points(n, 2) = z
Next
Read numconn ' Read in the numer of connections in the 3d object
Dim shared lines(numconn, 1) as integer ' Holds the connections of the 3d a to b.
For n = 1 To numconn
Read a, b
lines(n, 0) = a
lines(n, 1) = b
Next
do
rotate3d()
draw3d()
Ptc_Update @Buffer(0)
dbfcls
loop until inkey$<>""
ptc_close
end
'-------------------------------------------------------------------
' End Test
'-------------------------------------------------------------------
' --- This rotates a 3d objects points
Sub rotate3d()
dim x,y,z,tx,ty,tz,ox as double
rx =rx + 0.1
ry =ry + 0.2
rz =rz + 0.3
For n = 1 To numpoints
x = points( n , 0)
y = points( n , 1)
z = points( n , 2)
' X rotation
ty = ((y * _cos(rx)) - (z * _sin(rx)))
tz = ((y * _sin(rx)) + (z * _cos(rx)))
' Y rotation
tx = ((x * _cos(ry)) - (tz * _sin(ry)))
tz = ((x * _sin(ry)) + (tz * _cos(ry)))
' Z rotation
ox = tx
tx = ((tx * _cos(rz)) - (ty * _sin(rz)))
ty = ((ox * _sin(rz)) + (ty * _cos(rz)))
' Calculate new x and y location with perspective
xpos(n)=int((tx*(distance/(distance+tz)))+cx)
ypos(n)=int((ty*(distance/(distance+tz)))+cy)
c=n*30
dbfwpf (xpos(n), ypos(n),rgb (c,100,c))
dbfwpf (xpos(n)-1,ypos(n),rgb (c,100,c))
dbfwpf (xpos(n)+1,ypos(n),rgb (c,100,c))
dbfwpf (xpos(n), ypos(n)-1,rgb(c,100,c))
dbfwpf (xpos(n), ypos(n)+1,rgb(c,100,c))
Next
End sub
' ___ This draws a 3d object
Sub draw3d()
For n = 1 To numconn
DBFLINE(xpos(lines(n, 0)), ypos(lines(n, 0)),xpos(lines(n, 1)),ypos(lines(n, 1)),255,255,255)
Next
End sub
sub DBFLINE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER , BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL CR AS INTEGER, BYVAL CG AS INTEGER , BYVAL CB AS INTEGER)
DIM LINEXDV AS DOUBLE
DIM LINEYDV AS DOUBLE
DIM startx AS DOUBLE
DIM starty AS DOUBLE
DIM xdistance AS DOUBLE
DIM ydistance AS DOUBLE
DIM greaterx AS INTEGER
DIM lesserx AS INTEGER
DIM greatery AS INTEGER
DIM lessery AS INTEGER
DIM Lineloopsize AS INTEGER
DIM lineloop AS INTEGER
DIM TOPC AS INTEGER
TOPC = RGB(CR,CG,CB)
If x1 < x2 Then
lesserx = x1
greaterx = x2
lessery = y1
greatery = y2
Else
lesserx = x2
greaterx = x1
lessery = y2
greatery = y1
End If
If y1 < y2 Then
lessery = y1
greatery = y2
lesserx = x1
greaterx = x2
Else
Lessery = y2
greatery = y1
lesserx = x2
greaterx = x1
End If
xdistance = (greaterx-lesserx)
ydistance = (greatery-lessery)
If xdistance=0 THEN xdistance=1
If ydistance=0 THEN ydistance=1
If xdistance>=ydistance Then
lineloopsize = int(xdistance)
Else
lineloopsize = int(ydistance)
End If
LINEXDV=(greaterx-lesserx)/lineloopsize
LINEYDV=(greatery-lessery)/lineloopsize
startx=lesserx
starty=lessery
For lineloop=0 To lineloopsize
DBFWPF (startx,starty,TOPC)
startx=startx+(LINEXDV)
starty=starty+(LINEYDV)
Next
END SUB
SUB DBFWPF (BYVAL BX AS INTEGER , BYVAL BY AS INTEGER , BYVAL CH AS INTEGER)
IF (BX>0) AND (BX<640) AND (BY>0) AND (BY<480) THEN
BUFFER ((BY*640)+BX)=CH
END IF
END SUB
' Define a cube
Data 8 ' Points in cube
Data -50,-50,50
Data 50,-50,50
Data 50,-50,-50
Data -50,-50,-50
Data -50,50,50
Data 50,50,50
Data 50,50,-50
Data -50,50,-50
Data 12 ' Number of connecting lines
Data 1,2
Data 2,3
Data 3,4
Data 4,1
Data 5,6
Data 6,7
Data 7,8
Data 8,5
Data 8,4
Data 7,3
Data 6,2
Data 5,1
After getting this working I was able to return to the original source I was working on and get that going as well, it was all to do with how i was defining my variables and thanks to zawran and stonemonkey I can now continue, it also fixed some other code that wasnt working as expected.
:cheers:
Looking forward to seeing some stuff from the engine when it's more finished, especially interesting will be the textures seeing as you have got perspective correct mapping sussed out now. Also you should be able to add z buffering to your engine without too much trouble as you get the Z co-ordinate for each pixel as a by product of the PC mapping.
Quoteespecially interesting will be the textures seeing as you have got perspective correct mapping sussed out now.
Not sure were you got the impression I had perspective correct texture mapping sussed from but I dont as far as I am aware :o
The last feature for drawing I added to the blitz vector lib was smooth shading thanks to help from zawran but I never used it in anything, shame really as I have a complete light entity system in it for multiple coloured light sources, which looks nice when it works but due to heavy maths tended to grind blitz to a halt on all but really fast systems ;D
As you said when you posted the voroni textured tunnel in the tunnel effects challenge it was pure 2D code compiled in BB3D, that had a lovely textured tunnel with no texture warping which would suggest to me that you have cracked the the perspective correct mapping.
If it was affine mapping you used, there would have been some warping of the textures, especially with the exagerated perspective of a tunnel. It was also a lot faster than any other texture routine I've ever seen in BB2D, I even ran that tunnel on an older computer than this (AMD Athlon 1.5 ghz) and got virtually the same frame rate from it.
In any case, it was nice texture mapping, perhaps the best I've ever seen in Blitz 2D, 4 times faster than my own code and I was looking forward to seeing it added to the TTD engine which is the only thing it's lacked so far as the engine is obviously very good.
Hehe, I aint drawing a single poly in my tunnel entry ;)
Intriguing.
Well, I'm baffled Jon. I have no idea how you did it!