Computer Science Canada

3D Display Engine

Author:  zero-impact [ Tue Jan 27, 2009 12:07 pm ]
Post subject:  3D Display Engine

You can change the filename in 3d.t to open any of the .raw files. Also if you want to try your ownl models just export as a .raw and make sure to convert it to tris first.
There are 3 different resolutions for the monkey head: monkSmall, monk, and monkHiRes. monkSmall should run smoothly on most computers but if you have a newer computer you can try out the other ones.

Rotate by clicking and dragging.
Zoom with 'z' and 'x'.

Any tips for optimization or anything I could improve are appreciated Smile

Author:  saltpro15 [ Tue Jan 27, 2009 3:08 pm ]
Post subject:  RE:3D Display Engine

won't work for me Sad

Author:  zero-impact [ Tue Jan 27, 2009 3:30 pm ]
Post subject:  Re: 3D Display Engine

Fixed

Author:  saltpro15 [ Tue Jan 27, 2009 3:44 pm ]
Post subject:  RE:3D Display Engine

cool, you have way too much free time to make all these Very Happy + 5 bits

Author:  Zren [ Tue Jan 27, 2009 4:42 pm ]
Post subject:  Re: 3D Display Engine

I like how it continues to rotate after you let go of the mouse.

-Lighting's next prob. Not much you could improve on a wireframe. You could put in a total polys and FPS counter I guess though. Maybe make the zoom speed faster...

Author:  saltpro15 [ Tue Jan 27, 2009 5:39 pm ]
Post subject:  RE:3D Display Engine

you definitely have to rub this in paul's face Very Happy

Author:  zero-impact [ Tue Jan 27, 2009 5:44 pm ]
Post subject:  Re: 3D Display Engine

OK update.

Thanks Zren, lighting is what I will be working on next but for this I have added solid faces. also I did increase the zoom speed Smile

Author:  andrew. [ Tue Jan 27, 2009 9:03 pm ]
Post subject:  RE:3D Display Engine

That is truly amazing. Well done zero-impact. I could never program something 3D like that in Turing.

Author:  DemonWasp [ Wed Jan 28, 2009 12:54 am ]
Post subject:  RE:3D Display Engine

Very nicely done. I'm still looking at the code, but the first thing that jumps out at me as an easy fix is this:

You're loading your data so that you have some N triangles with 3N points. That's great, and it works, but it's an awful lot of storage, since you tend to have multiple triangles sharing points. That means you're doing additional work, and storing more information!

Instead, try this:

For each model (or for the whole program, since you seem to be loading exactly one), have an array of Point objects. Load each point independent of the triangles. Then, have an array of Triangles - all these need are three integers, each an index into the Points() array.

This allows you to re-use points in your geometry and simplifies your rotate methods (which now only need to rotate points). You will probably find that you need around 1/3rd as many points.

This means:
1/3 as many point-rotate operations
1/3 as many point-draw operations
1/3 as much space required for point storage

This would require that you either update your input files (save a backup first!) or re-interpret on-the-fly after loading.

If you're not going past wireframe, it's also possible to just have an array of indices for each point indicating all the other points its connected to.

Edit 1: Fixed some grammar.

Edit 2: As a point of interest, it's generally poor style to have drawX() methods modify data. I realise it's just the x2 and y2 fields of Point, but either comment that behaviour, or comment in the Point object that x2 and y2 are just for graphics. Even so, it's probably best to move the "point.x2 := round (ZOOM * point.x) + XOFFSET" bit into drawObject(). This may happen as a result of the optimisation noted above.

Edit 3: In your revised version (note: using version numbers helps us all keep them straight; the first one can be 0.01, this is then 0.02 or whatever), you're quicksorting. This appears to be in an attempt to make sure that your model is drawn in the "correct" order, so that polygons on the back don't appear over polygons on the front. Unfortunately, the only true solution to this is a depth buffer for every pixel on the screen (impractical, methinks); your solution is alright but not fantastic (look carefully at monkey's ears).

Author:  CodeMonkey2000 [ Wed Jan 28, 2009 1:27 am ]
Post subject:  RE:3D Display Engine

You should also try back face culling (compare the normal vector to the view vector). You will be drawing roughly half as many polygons.

Author:  zero-impact [ Wed Jan 28, 2009 2:53 am ]
Post subject:  RE:3D Display Engine

Thanks DemonWasp I have thought of a few ways of optimizing it but I just wanted to get it working :p unfortunately I have to completely redesign most of it to optimize it. Also for the quicksort, I have noticed the glitches in the monkey and especially the gun. It seems to happen with very elongated polygons.. which makes sense considering how it calculates it.

Thanks for the tip CodeMonkey I will look into that.

Author:  SNIPERDUDE [ Wed Jan 28, 2009 10:03 am ]
Post subject:  RE:3D Display Engine

... Makes me want to dust off my old 3D engine and start working on that again. I never did post the thing because I kept wanting to refine it better. Anywho pretty good job Zero-impact.

Author:  saltpro15 [ Wed Jan 28, 2009 11:21 am ]
Post subject:  RE:3D Display Engine

I just had an idea for this thing, being able to zoom in on a specific area on the models would be interesting. For example, zooming in to only look at the trigger of the gun

Author:  DemonWasp [ Wed Jan 28, 2009 1:09 pm ]
Post subject:  RE:3D Display Engine

Update: I did a quick-and-dirty modification of your program to eliminate duplicate points as I'd suggested. I ran it on the monk.raw model; I had it give output:
code:

Of 2904 points, 2399 were duplicates (82.61%) and 505 (17.39%) were unique


What this means is that you could potentially use around 20% of the space and computation time as your current method uses. This modification didn't take very long, maybe about 30-60 minutes. I can post code if you want, but it'll need a cleanup first.

Author:  zero-impact [ Wed Jan 28, 2009 2:31 pm ]
Post subject:  Re: 3D Display Engine

That would be very much appreciated DemonWasp. I have been racking my brain for hours on how to eliminate duplicates.. easily.. that is. I would love to see the code for it regardless Very Happy

Codemonkey: I think I have the back face culling working pretty well as well as simple Lambertian reflectance.

Here is the updated code

Author:  saltpro15 [ Wed Jan 28, 2009 2:46 pm ]
Post subject:  RE:3D Display Engine

awesome, you have been on fire the last 2 days Razz

Author:  CodeMonkey2000 [ Wed Jan 28, 2009 2:47 pm ]
Post subject:  Re: 3D Display Engine

I made a small change. I back cull before quick sorting, thus speeding up the quick sort method slightly, and when you draw, it's not looking at every single polygon. On my computer it made a small difference.
Turing:
%Lawson Fulton%
%%%%27/01/09%%%
%Change zoom with 'x' and 'z'

setscreen ("graphics:max;max;nobuttonbar;offscreenonly")


var stream : int
open : stream, "monk.raw", get

type Point :
    record
        x : real
        y : real
        z : real
        x2 : int
        y2 : int
    end record

type Vector :
    record
        x : real
        y : real
        z : real
    end record

type Face :
    record
        v1 : Point
        v2 : Point
        v3 : Point
        normal : Vector
        view : Vector
        dotProd : real
        col : int
    end record


var chars : array char of boolean
const XOFFSET := maxx div 2
const YOFFSET := 0
const ZOFFSET := maxy div 2
const COL := black
var ZOOM := maxy div 3

var cLoc : Point  %camera location
cLoc.x := 0
cLoc.y := ZOOM
cLoc.z := 0

var object1 : flexible array 1 .. 0 of Face
var object2 : flexible array 1 .. 0 of Face

var count := 0.0
for decreasing i : 256 .. 0 %set colours
    RGB.SetColor (i, count, count, count)
    count += 1 / 256
end for

loop %Load object
    exit when eof (stream)

    new object1, upper (object1) + 1

    get : stream, object1 (upper (object1)).v1.x
    get : stream, object1 (upper (object1)).v1.y
    get : stream, object1 (upper (object1)).v1.z

    get : stream, object1 (upper (object1)).v2.x
    get : stream, object1 (upper (object1)).v2.y
    get : stream, object1 (upper (object1)).v2.z

    get : stream, object1 (upper (object1)).v3.x
    get : stream, object1 (upper (object1)).v3.y
    get : stream, object1 (upper (object1)).v3.z
end loop


proc drawPoint (var point : Point)
    point.x2 := round (ZOOM * point.x) + XOFFSET
    point.y2 := round (ZOOM * point.z) + ZOFFSET

    %drawdot (point.x2, point.y2, COL)
    %drawfilloval (point.x2, point.y2,2,2, white)
end drawPoint

proc drawEdge (v1 : Point, v2 : Point)
    drawline (v1.x2, v1.y2, v2.x2, v2.y2, COL)
end drawEdge

proc drawFace (var face : Face)
    drawPoint (face.v1)
    drawPoint (face.v2)
    drawPoint (face.v3)

    %drawEdge (face.v1, face.v2)
    %drawEdge (face.v2, face.v3)
    %drawEdge (face.v3, face.v1)

    var x, y : array 1 .. 3 of int  %temp array for draw polygoon
    x (1) := face.v1.x2
    x (2) := face.v2.x2
    x (3) := face.v3.x2

    y (1) := face.v1.y2
    y (2) := face.v2.y2
    y (3) := face.v3.y2



    drawfillpolygon (x, y, 3, abs (round (cosd (face.dotProd) * 255)))
    %drawpolygon (x, y, 3, black)
end drawFace


proc drawObject (var object : array 1 .. * of Face)
    for i : 1 .. upper (object)
        drawFace (object (i))
    end for
end drawObject

proc calcNormals (var object : array 1 .. * of Face)
    new object2, 0
    for i : 1 .. upper (object)
        var vec1 : Vector
        vec1.x := object (i).v2.x - object (i).v1.x
        vec1.y := object (i).v2.y - object (i).v1.y
        vec1.z := object (i).v2.z - object (i).v1.z
        var vec2 : Vector
        vec2.x := object (i).v3.x - object (i).v1.x
        vec2.y := object (i).v3.y - object (i).v1.y
        vec2.z := object (i).v3.z - object (i).v1.z

        object (i).normal.x := (vec1.y * vec2.z) - (vec1.z * vec2.y)
        object (i).normal.y := - ((vec1.z * vec2.x) - (vec1.x * vec2.z))
        object (i).normal.z := (vec1.x * vec2.y) - (vec1.y * vec2.x)

        var normFactor := (object (i).normal.x ** 2 + object (i).normal.y ** 2 + object (i).normal.z ** 2) ** 0.5

        object (i).normal.x := object (i).normal.x / normFactor
        object (i).normal.y := object (i).normal.y / normFactor
        object (i).normal.z := object (i).normal.z / normFactor


        object (i).view.x := cLoc.x - object (i).v1.x %view vector
        object (i).view.y := cLoc.y - object (i).v1.y
        object (i).view.z := cLoc.z - object (i).v1.z

        object (i).dotProd := (object (i).view.x * object (i).normal.x) + (object (i).view.y * object (i).normal.y) + (object (i).view.z * object (i).normal.z)
        if object (i).dotProd > 0 then
            new object2, upper (object2) + 1
            object2 (upper (object2)) := object1 (i)
        end if
    end for
end calcNormals

procedure rotatePoint (var x, y : real, theta : real)
    var x2, y2 : real
    x2 := x
    y2 := y
    x := x2 * cosd (theta) + y2 * sind (theta)
    y := y2 * cosd (theta) - x2 * sind (theta)
end rotatePoint

proc rotateObject (var object : array 1 .. * of Face, x, y, z : real)
    for i : 1 .. upper (object)
        rotatePoint (object (i).v1.x, object (i).v1.y, y) %y axis
        rotatePoint (object (i).v2.x, object (i).v2.y, y)
        rotatePoint (object (i).v3.x, object (i).v3.y, y)

        rotatePoint (object (i).v1.y, object (i).v1.z, x) %x axis
        rotatePoint (object (i).v2.y, object (i).v2.z, x)
        rotatePoint (object (i).v3.y, object (i).v3.z, x)

        rotatePoint (object (i).v1.z, object (i).v1.x, z) %z axis
        rotatePoint (object (i).v2.z, object (i).v2.x, z)
        rotatePoint (object (i).v3.z, object (i).v3.x, z)
    end for
end rotateObject


procedure swap (var list : array 1 .. * of Face, i, j : int)
    var temp : Face := list (i)
    list (i) := list (j)
    list (j) := temp
end swap
procedure quickSort (var list : array 1 .. * of Face, left, right : int)   %http://compsci.ca/v3/viewtopic.php?t=4091&highlight=quick+sort
    var pivotPlace : int
    swap (list, left, (left + right) div 2)
    var lastSmall := left
    for i : left + 1 .. right
        if list (i).v1.y + list (i).v2.y + list (i).v3.y / 3 > list (left).v1.y + list (left).v2.y + list (left).v3.y / 3 then
            lastSmall += 1
            swap (list, lastSmall, i)
        end if
    end for
    swap (list, left, lastSmall)
    pivotPlace := lastSmall
    if left < pivotPlace - 1 then
        quickSort (list, left, pivotPlace - 1)
    end if
    if pivotPlace + 1 < right then
        quickSort (list, pivotPlace + 1, right)
    end if
end quickSort


var mx, my, mx2, my2, mbutton, rx, ry : int := 0
%setObjectColours (object1)

loop
    Input.KeyDown (chars)
    if chars ('z') then
        ZOOM += 10
    elsif chars ('x') then
        ZOOM -= 10
    end if

    mx2 := mx
    my2 := my
    Mouse.Where (mx, my, mbutton)

    if mbutton = 1 then
        rx := - (my2 - my) div 2 %current rotation
        ry := (mx2 - mx) div 2
        rotateObject (object1, rx, ry, 0)
    else
        rotateObject (object1, rx, ry, 0)
    end if

    drawfillbox (0, 0, maxx, maxy, 255)
    calcNormals (object1)
    quickSort (object2, 1, upper (object2))


    drawObject (object2)
    View.Update
    Time.DelaySinceLast (10)
end loop

Author:  DemonWasp [ Wed Jan 28, 2009 3:31 pm ]
Post subject:  RE:3D Display Engine

Alright, I'm fixing up the code now. Before I post, I do have to ask to make sure: are you certain that this is NOT going to be used for a school project or any other kind of academic work?

I'm making some pretty severe changes, and if this is for academic credit, I can't contribute to your program without the express consent of your teacher, and possibly not even then.

Author:  zero-impact [ Wed Jan 28, 2009 3:31 pm ]
Post subject:  RE:3D Display Engine

Thanks codemonkey but I dont see how that speeds up the quicksort at all?

Author:  DemonWasp [ Wed Jan 28, 2009 3:34 pm ]
Post subject:  RE:3D Display Engine

It speeds up the quicksort because it only has to sort N/2 polygons on average rather than N polygons.

Edit to my previous comment: as a side note, you only need to specify "var" for any arguments in your procedure list that you intend to modify. If you don't, it's best to leave it off so the interpreter can warn you if you accidentally modify something.

Author:  zero-impact [ Wed Jan 28, 2009 3:37 pm ]
Post subject:  RE:3D Display Engine

Oh no of course not. My grade 11 comSci course ended last week. This is purely personal interest.

Oh and yes I see that now. I didn't realize you were copying the object into another smaller one. That makes more sense. Yet.. it still seems impractical to have another object array. Especially because expanding flexible arrays is so inefficient.

Author:  DemonWasp [ Wed Jan 28, 2009 4:10 pm ]
Post subject:  Re: 3D Display Engine

Alright then, I don't feel bad about contributing to personal-interest projects. Be warned before you go into this code: I have made some pretty heavy modifications to your code, including changing the global object1 flexible array to inside a class, splitting it into points() and faces(), and so on. I believe the comments in the file should make it pretty self-explanatory.

WARNING: Load times in this version are quite long. It has to do an O ( N ^ 2 ) amount of work to detect and remove duplicate points. You won't notice it for monkSmall, but for monkHiRes it can easily be 30 seconds. I have plans for how this could be improved drastically; see my comments inside the file.

There are other miscellaneous optimisations, including one to minimise the time required for flexible-array-resizing. This is commented in the file itself at the top.

Author:  zero-impact [ Wed Jan 28, 2009 5:29 pm ]
Post subject:  RE:3D Display Engine

Wow! That is an amazing improvement! +Bits

Author:  Clayton [ Wed Jan 28, 2009 6:12 pm ]
Post subject:  RE:3D Display Engine

Without actually having Turing to run this with (lab machine, emulation software not installed etc. etc) I have one question... why is the FPS limiter set to 100 fps? That's more than triple the "ideal" framerate that humans can see. Why not cut back on how often you're drawing things?

Author:  zero-impact [ Wed Jan 28, 2009 6:34 pm ]
Post subject:  RE:3D Display Engine

Because why not? :p I don't see any reason not to set it that high. it really only matters for the cubes and spheres anyways..

Author:  DemonWasp [ Wed Jan 28, 2009 6:36 pm ]
Post subject:  RE:3D Display Engine

It's limited to a maximum of 100fps. It actually ends up rendering far below that on most machines. I'm on a q9450 and monkHiRes ends up running at perhaps 15FPS (complete guesswork, as it doesn't output rate).

Probably the next step for me on this is to add a BST to improve the loading times (around 15 seconds for monkHiRes on my uber-powered desktop machine...that's about the same as the time required to load a COD4 map).

Author:  saltpro15 [ Wed Jan 28, 2009 6:38 pm ]
Post subject:  RE:3D Display Engine

DemonWasp, do you know if it's possible to output FPS in a game? that would be really handy for my raycaster...

Author:  zero-impact [ Wed Jan 28, 2009 7:15 pm ]
Post subject:  RE:3D Display Engine

I'm just wondering.. does anybody know if I'm on the right track with this Lambertian Reflectance?

Author:  DemonWasp [ Wed Jan 28, 2009 7:47 pm ]
Post subject:  RE:3D Display Engine

@zero-impact: Lambertian Reflectance appears to be used largely for simplistic lighting effects. It's a good next step for the program, and should make it look even nicer. I think it's about time to get started on making the code more object-oriented, so I think I'll get a start on that; we can merge in the changes you're making to the changes I'm making soon.

@saltpro15: There are a few easy ways. Simplest is probably to time each loop (tick) and then divide one second by that, to get the number of frames per second (frames / second = 1 / seconds per frame). That number changes every frame though, so it can change wildly.

Better would be to time some number of frames (10 or so) and update the FPS counter every N frames. This cuts down on the problem of the inaccuracy of Turing's timing system and gives you a more "stable" number that still appears just as animated.

Author:  saltpro15 [ Wed Jan 28, 2009 7:52 pm ]
Post subject:  RE:3D Display Engine

alright, if i were to guess I have mine running at around 10 fps, we shall see how close my guess was Very Happy

Author:  zero-impact [ Wed Jan 28, 2009 10:57 pm ]
Post subject:  RE:3D Display Engine

DemonWasp: I looked at your code and redid the quicksort to draw the faces semi correctly (havn't done the back face culling yet) and it seems that the quick sort really is the biggest bottle neck. On monkHiRes it only gives an improvement of about 3-5 fps.. Does anyone know of any other practical ways of determining the order of the polygons? back face culling by itself is not enough as there is still some glitches with overlapping polys.

Author:  DemonWasp [ Thu Jan 29, 2009 2:30 pm ]
Post subject:  Re: 3D Display Engine

I've done some more code updates:
- Returned the quickSort, but refactored to improve its efficiency slightly. Draw order is now determined by an array of indices to faces, with back-culled faces removed beforehand. There's probably something that can be done to improve this, but I'm not seeing it offhand. Maybe when I've had some sleep.
- Added a display for the number of points, faces, duplicated points and FPS
- Added a logger stream (WARNING: logging severely reduces performance and generates a lot of data (if you uncomment the logger-writing lines) )
- Added the Vector3f class in Vector3f.t ; the API is largely the same as the jME Vector3f class. This class can replace Point soon.

You will need to put Vector3f.t in the same folder as the main turing file and all the raw objects.

Comments / recommendations / suggestions are all welcome.

Author:  CodeMonkey2000 [ Thu Jan 29, 2009 3:32 pm ]
Post subject:  RE:3D Display Engine

Too bad turing doesn't support operator overloading.

Author:  DemonWasp [ Thu Jan 29, 2009 5:06 pm ]
Post subject:  RE:3D Display Engine

Yeah, operator overloading could have made this a little easier. It'd also have helped if they hadn't grabbed "length" and "set" as reserved keywords.

Most of what jME has are sorta useless though; their code for some of the multiply methods calls another multiply method. This works out fine in the JVM, which can short-circuit that, but Turing won't, so I cut it out: methods do what they're supposed to and return the result immediately.

Author:  zero-impact [ Thu Jan 29, 2009 11:11 pm ]
Post subject:  Re: 3D Display Engine

Here is a small update with the lighting (still using my original procedural version) using Lambertian Reflectance.

Author:  DemonWasp [ Fri Jan 30, 2009 4:34 pm ]
Post subject:  Re: 3D Display Engine

Updates:
- Integrated zero-impact's Lambertian Reflectance.
- Removed the Point type entirely. Use the Vector3f class instead. For projected pixel coordinates (formerly x2, y2), use pointProjectX, pointProjectY.
- Added pervasive keyword so that certain classes / methods / variables do not need to be imported into classes.

Performance:
On this 2.4Ghz P4, I get about 5-9 FPS with monk.raw, depending on model angle. This represents a slight improvement over the version posted by zero-impact, which ran at about 4FPS on the same machine with the same file, regardless of model orientation.

Author:  zero-impact [ Sun Feb 01, 2009 4:35 pm ]
Post subject:  Re: 3D Display Engine

Interesting.. I ran monkHiRes.raw on your newest update and walked away for about 5 minutes. When I got back Turing had crashed due to a "fatal error". Any ideas?

Author:  DemonWasp [ Sun Feb 01, 2009 8:03 pm ]
Post subject:  RE:3D Display Engine

Sorry, no ideas. I can't reproduce the issue on my home PC. It spends about 10 seconds loading, then draws at about 3-4 fps.

I should mention: the machine in question is incredibly powerful (q9450, 6GB ram, high-end hard disks). Is your machine perhaps short on RAM or CPU? If so, try a smaller model; monk or monkSmall or gun or whatever really, so long as it's not the high-res model.

Load time is still an issue; I'm considering implementing some of the Java Collections framework so I can use a hashtable or similar to cut down loading from O ( numPoints^2 ) to O ( numPoints )

Author:  zylum [ Mon Feb 02, 2009 6:01 am ]
Post subject:  RE:3D Display Engine

Try using transformation/rotation matrices.. They should speed up your program a bit. My old engine used them but I'm not sure I posted a version with matrices.. Also look into the .ply file format -- it's a bit more efficient than .raw as it doesn't store multiple instances of the same point. Also, if you are aiming for speed, you'll want to minimize function calls and the number of classes you have. This is really bad practice but it helps a lot.

Author:  DemonWasp [ Mon Feb 02, 2009 9:50 am ]
Post subject:  RE:3D Display Engine

@zylum: I inlined the swap() method used by qSort() and that resulted in a 0.5 FPS average increase (averages about 5.25FPS on this machine now). Inlining rotatePoint() wasn't quite as effective, but did provide a slight boost. Inlining drawFace improved by another 0.25 FPS or so.

At this point I think we're rapidly approaching Turing's limits on speed. No matter how much we destroy real design for speed, it's never going to exceed 7-8 FPS on this machine. Turing is just too slow. For reference, the only testing I've ever done seems to indicate that Turing is about 1% the speed of compiled C / C++ or Java.

Author:  zylum [ Mon Feb 02, 2009 2:51 pm ]
Post subject:  RE:3D Display Engine

Hmm... I remember my engine being quite a bit faster and I remember having ideas on how to improve the speed. Your implementation looks very similar to mine though... Do you cull the faces before sorting?? Check out my engine for more ideas..

Author:  DemonWasp [ Mon Feb 02, 2009 3:43 pm ]
Post subject:  RE:3D Display Engine

Faces are "culled" before sorting, in that the indices of drawable faces are input into an array which is then sorted. Perhaps some speed can be gained by allocating that array differently...nope. Even allocating the array so that it's not new'd at each frame-draw doesn't produce any meaningful performance boost.

Remember, speed varies substantially from one version of Turing to another, and from one machine to another. I'm on a dreadfully slow and overburdened machine (Firefox + WinAmp + a server + Lotus Notes + remote-desktop software, with only 2.4Ghz CPU and 2GB RAM).

Author:  zylum [ Mon Feb 02, 2009 5:28 pm ]
Post subject:  RE:3D Display Engine

I just tested my old engine and it can run two monkey models at 10-16 fps depending on the rotation. And like I said, there's tons of room for improvement... You must have some sort of bottle neck somewhere. Try timing each major section of code to see where the biggest slow down is. Check the rotation function, sorting and drawing..

Here's my engine btw http://compsci.ca/v3/viewtopic.php?t=9639&highlight=zylum+engine

Author:  zero-impact [ Mon Feb 02, 2009 8:57 pm ]
Post subject:  RE:3D Display Engine

DemonWasp: no power issues here. I'm running a q660 with 2Gb of RAM. I get about 12 - 20 fps on monk.raw

Zylum: That is amazing Very Happy


: