I've just been playing around with the idea of drawing lines. . .
So far I've just been drawing all edges on front facing triangles and so haven't needed to compile the list of edges etc. There does seem to be a perfomance hit, but only when you start drawing more than a few hundred lines.
It seems that the number of lines actually drawn is the main factor on performance, not the size of the mesh you perform the operation to (commenting out the Line statements proves this)
Here's the code:
There is no way that drawing lines would be quick enough.
Yup, I think after experimenting I'm inclined to agree. However, I think that some more interesting effects might be achievable with line drawing. . . for example, try modifying the code above to pass in a value of 1 or 2 to the sketchy parameter in the DrawFrontFacingLines function to see what I mean. . .
So far I'm still not sure which way is best, but I'm starting to see the pros and cons of each. Also, I still have no idea how to solve the problem of deciding whether or not to draw lines based on whether an edge is hidden behind something or not.
Thanks people. . . keep the ideas coming :O)
So far I've just been drawing all edges on front facing triangles and so haven't needed to compile the list of edges etc. There does seem to be a perfomance hit, but only when you start drawing more than a few hundred lines.
It seems that the number of lines actually drawn is the main factor on performance, not the size of the mesh you perform the operation to (commenting out the Line statements proves this)
Here's the code:
Graphics3D 800, 600 Global mshSphere% = CreateSphere(12) UpdateNormals mshSphere EntityFX mshSphere, 4 Global GlobalLight% = CreateLight() RotateEntity GlobalLight, 45, 45, 45 Global GlobalCamera% = CreateCamera() PositionEntity GlobalCamera, 4, 2, 4 PointEntity GlobalCamera, mshSphere CameraClsColor GlobalCamera, 180,180,180 Local fps% Local fpscount% Local millistop% Local millis% While Not KeyHit(1) Navigate_World_With_MouseAndKeys(0.5, 0.1) TurnEntity mshSphere, 0, 0.5, 0 SetBuffer BackBuffer() Cls RenderWorld() DrawFrontFacingLines(mshSphere, GlobalCamera, 0, 0) Color 255, 0, 0 Text 1, 1, "FPS=" + fps Text 1, 12, "TrisRendered=" + TrisRendered() Flip fpscount = fpscount + 1 millis% = MilliSecs() If millistop < millis - 1000 Then millistop = millis fps = fpscount fpscount = 0 End If Wend End Function DrawFrontFacingLines(m%, cam, thick%, sketchy#) Color 30, 30, 50 Local v3X = CreateVector(3) Local v3Y = CreateVector(3) For is% = 1 To CountSurfaces(m) s% = GetSurface(m, is) For it% = 0 To CountTriangles(s) - 1 If FrontFacing(cam, s, it, m) Then For i% = 0 To 2 vx# = VertexX(s, TriangleVertex(s, it, i)) vy# = VertexY(s, TriangleVertex(s, it, i)) vz# = VertexZ(s, TriangleVertex(s, it, i)) TFormPoint vx, vy, vz, m, 0 vx = TFormedX() vy = TFormedY() vz = TFormedZ() CameraProject(cam, vx, vy, vz) VctPut v3X, i, ProjectedX() VctPut v3Y, i, ProjectedY() Next c0 = (VctGet(v3X,0)=0) And (VctGet(v3Y,0)=0) c1 = (VctGet(v3X,1)=0) And (VctGet(v3Y,1)=0) c2 = (VctGet(v3X,2)=0) And (VctGet(v3Y,2)=0) For n% = -thick To thick r# = sketchy If Not (c0 Or c1) Then Line VctGet(v3X,0)+n+Rnd(-r, r), VctGet(v3Y,0)+Rnd(-r, r), VctGet(v3X,1)+Rnd(-r, r), VctGet(v3Y,1)+Rnd(-r, r) If Not (c1 Or c2) Then Line VctGet(v3X,1)+n+Rnd(-r, r), VctGet(v3Y,1)+Rnd(-r, r), VctGet(v3X,2)+n+Rnd(-r, r), VctGet(v3Y,2)+Rnd(-r, r) If Not (c0 Or c2) Then Line VctGet(v3X,0)+n+Rnd(-r, r), VctGet(v3Y,0)+Rnd(-r, r), VctGet(v3X,2)+n+Rnd(-r, r), VctGet(v3Y,2)+Rnd(-r, r) Next End If Next Next DeleteVector v3X DeleteVector v3Y End Function Function Navigate_World_With_MouseAndKeys(turnSpeed#=1, moveSpeed#=1) Local dY# = EntityPitch(GlobalCamera)+MouseYSpeed()/2*turnSpeed If dY > 89 Then dY = 89 If dY < -89 Then dY = -89 Local dz# = (KeyDown(200)-KeyDown(208)) * moveSpeed Local dx# = (KeyDown(205)-KeyDown(203)) * moveSpeed If dz <> 0 And dx <> 0 Then dx=dx * 0.707 dz=dz * 0.707 End If RotateEntity GlobalCamera, dY, EntityYaw(GlobalCamera)-(MouseXSpeed()/2)*turnSpeed, 0 MoveEntity GlobalCamera, dx, 0, dz MoveMouse GraphicsWidth()/2, GraphicsHeight()/2 If KeyHit(4) Then CameraZoom GlobalCamera, 4.0 End If If KeyHit(5) Then CameraZoom GlobalCamera, 1.0 End If End Function Function FrontFacing%(cam%, s%, t%, m%) Local v1 = CreateVector(3) Local v2 = CreateVector(3) Local v3 = CreateVector(3) x# = VertexX(s, TriangleVertex(s, t, 0)) y# = VertexY(s, TriangleVertex(s, t, 0)) z# = VertexZ(s, TriangleVertex(s, t, 0)) TFormPoint x, y, z, m, cam VctPut v1, 0, TFormedX() VctPut v1, 1, TFormedY() VctPut v1, 2, TFormedZ() x# = VertexX(s, TriangleVertex(s, t, 1)) y# = VertexY(s, TriangleVertex(s, t, 1)) z# = VertexZ(s, TriangleVertex(s, t, 1)) TFormPoint x, y, z, m, cam VctPut v2, 0, TFormedX() VctPut v2, 1, TFormedY() VctPut v2, 2, TFormedZ() x# = VertexX(s, TriangleVertex(s, t, 2)) y# = VertexY(s, TriangleVertex(s, t, 2)) z# = VertexZ(s, TriangleVertex(s, t, 2)) TFormPoint x, y, z, m, cam VctPut v3, 0, TFormedX() VctPut v3, 1, TFormedY() VctPut v3, 2, TFormedZ() Local vEdge1 = V3dSubtract(v3, v1) Local vEdge2 = V3dSubtract(v3, v2) Local vFNormal = V3dCross(vEdge1, vEdge2) Local bFrontFacing% = (V3dDot(v1, vFNormal) < 0) DeleteVector v1 DeleteVector v2 DeleteVector v3 DeleteVector vEdge1 DeleteVector vEdge2 DeleteVector vFNormal Return bFrontFacing End Function Function V3dAdd(v1, v2) Local v3 = CreateVector(3) VctPut v3, 0, VctGet(v1,0) + VctGet(v2,0) VctPut v3, 1, VctGet(v1,1) + VctGet(v2,1) VctPut v3, 2, VctGet(v1,2) + VctGet(v2,2) Return v3 End Function Function V3dSubtract(v1, v2) Local v3 = CreateVector(3) VctPut v3, 0, VctGet(v1,0) - VctGet(v2,0) VctPut v3, 1, VctGet(v1,1) - VctGet(v2,1) VctPut v3, 2, VctGet(v1,2) - VctGet(v2,2) Return v3 End Function Function V3dCross(v1, v2) Local v3 = CreateVector(3) VctPut v3, 0, VctGet(v1,1)*VctGet(v2,2) - VctGet(v1,2)*VctGet(v2,1) VctPut v3, 1, VctGet(v1,2)*VctGet(v2,0) - VctGet(v1,0)*VctGet(v2,2) VctPut v3, 2, VctGet(v1,0)*VctGet(v2,1) - VctGet(v1,1)*VctGet(v2,0) Return v3 End Function Function V3dDot#(v1, v2) Return VctGet(v1,0)*VctGet(v2,0) + VctGet(v1,1)*VctGet(v2,1) + VctGet(v1,2)*VctGet(v2,2) End Function Function VctGet#(v, i%) Return PeekFloat(v, i Shl 2) End Function Function VctPut(v, i%, val#) PokeFloat v, i Shl 2, val End Function Function CreateVector(nDim%) v% = CreateBank(nDim Shl 2) Return v End Function Function DeleteVector(v) FreeBank v End Function
There is no way that drawing lines would be quick enough.
Yup, I think after experimenting I'm inclined to agree. However, I think that some more interesting effects might be achievable with line drawing. . . for example, try modifying the code above to pass in a value of 1 or 2 to the sketchy parameter in the DrawFrontFacingLines function to see what I mean. . .
So far I'm still not sure which way is best, but I'm starting to see the pros and cons of each. Also, I still have no idea how to solve the problem of deciding whether or not to draw lines based on whether an edge is hidden behind something or not.
Thanks people. . . keep the ideas coming :O)