Drawing 3D "manually"...

Started by
17 comments, last by ph33r 19 years, 5 months ago
Hi all I'm currently working on a project (along with a few others) to draw some 3D stuff, which will hopefully turn into a rendering engine eventually. I searched for a bit on these forums, and google with no luck. What i would like to do is draw 3D points on the 2D screen, with a depth buffer. I understand that the camera is a 4x4 matrix, along with the point, and i know all rotation matricies ant stuff like that. What is getting me is, given the projection (is it a matrix? in OGL it's gluPerspective(50,1,1,100) ) then how to I get the 2D point on the screen and how far away it is for Depth?? I've worked with OpenGL for a while now, with a little DirectX, and i think that will help me.. Thanks for anything (sorry if this topic has been brought up before) ~zix~ [Edited by - zix99 on November 22, 2004 3:05:15 PM]
---------------------------------------------------Game Programming Resources, Tutorials, and Multimedia | Free Skyboxes
Advertisement
Yes, projection is a matrix. The DX SDK help files detail how the projection matrix is created.

What then occurs is: vertexposition (with an assumed w of 1...[x,y,z,1]) * world * view * projection.

The resulting vector is the divided by W. Now you're in clip space. In DX thats -1<x<1, -1<y<1, and 0<z<1. I think I've seen somewhere that in OpenGL z goes from -1 to 1 too... it's a full cube.

From here, you discard and/or clip the triangles to fit within those boundaries. You can also do this before dividing by W, where -w<x<w, -w<y<w, etc..

Then you apply viewport scaling. Basically scale and offset the x and y into pixel coordinates. For a 640x480 screen that would be x*320+320 and y*240+240. Then, rasterize your result.
Any good tutorials that might show exaclty how to do this (I'll look into the DirectX SDK)?
Including drawing triangles/texturing triangles...

Thanks again
~zix~
---------------------------------------------------Game Programming Resources, Tutorials, and Multimedia | Free Skyboxes
Yeah, look up the D3DXMatrixPerspectiveLH function in the DirectX SDK help file, it shows you exactly what the perspective matrix looks like.

It's this:

w       0       0               00       h       0               00       0       zf/(zf-zn)      10       0       -zn*zf/(zf-zn)  0where:h is the view space height. It is calculated from h = cot(fovY/2);w is the view space width. It is calculated from w = h * aspect   (where aspect = screenWidth/screenHeight)zf = farthest visible distance, zn = nearest visible distance


So, this works with homogenous coordinates. for a vertex:

  [x, y, z, 1]


you get the following: output vertex

  [x*w, y*h, (z-zn)*zf / (zf-zn), z]


which becomes (After the homogenous divide by w)

  [x*w/z, y*h/z, (1-zn/z)*zf / (zf-zn), 1]


In the case of D3D's matrices, you end up with x and y in the range [-1, 1] and z in the range [0, 1], 1 being farthest from the camera (the z-far plane) and 0 being nearest (z-near plane).

Hope that helps :)
Drillan, thank you very much for that response, quite helpful. Now, sense I have one subject down, all that's left is drawing filled triangles (dont forget i'm using depth so if it is translated to 2D then drawn, i still need depth). Also texturing, but this can be covered later if needed.

One question for namethatnobodyelsetook
Quote:What then occurs is: vertexposition (with an assumed w of 1...[x,y,z,1]) * world * view * projection.


So, if I am correct it would look something like (if camera was at 0,0,0 and point was at 5,5,0):
1  0  0  5                 1  0  0  0    w  0  0  00  1  0  5   *  WORLD?  *  0  1  0  0  * 0  h  0  00  0  1  0                 0  0  1  0    0  0  zf/(zf-zn)  10  0  0  1                 0  0  0  1    0  0  -zn*zf/(zf-zn)  0

I figure rotating the camera is simply just multiplying the viewport coordinates by the rotation matrix?

Thanks again
~zix~

PS: I rated u guys up.. but it's not doing anything.. is the rating system broken??
---------------------------------------------------Game Programming Resources, Tutorials, and Multimedia | Free Skyboxes
To draw a triangle, start by drawing the lines of the triangle. Look into Bresenham's line algorithm for details. When you draw the lines to the screen you only need to keep track of the smallest x value, and the greatest x value of the line.

So you could keep two array's of min x and max x.

MIN X MAX X
[0] [0]
[1] [1]
. .
. .
[480] [480]

The array would be the height of the screen, then just iterate through the array and connect the lines horizontally. In array position [0] you could have a value of 10, and array 2 position [0] you could have a value of 100, that means that left most outer edge of the traingle 0 pixels down on the screen is at 10, and the right most edge of the triangle 0 pixels down is at 100. A simple for loop from 10 to 100, filling in each pixel with an interpolated color or a sampled UV coord will give you a colored/textured triangle.

- Hope thats clear.
Quote:Original post by zix99
So, if I am correct it would look something like (if camera was at 0,0,0 and point was at 5,5,0):
1  0  0  5                 1  0  0  0    w  0  0  00  1  0  5   *  WORLD?  *  0  1  0  0  * 0  h  0  00  0  1  0                 0  0  1  0    0  0  zf/(zf-zn)  10  0  0  1                 0  0  0  1    0  0  -zn*zf/(zf-zn)  0

I figure rotating the camera is simply just multiplying the viewport coordinates by the rotation matrix?


The correct order of operations is world*view*proj.

I don't understand what you mean by point was at 5,5,0 do you mean the look at point for the camera? I'm not sure what you mean but, for camera, every thing is inverted, because the world is transformed to move the camera back to 0,0,0. So if the camera was translated 5,5,0 forward the matrix would have -5,-5,0 in the translation portions.
Maybe this is clearer?
(5,5,0)                    (0,0,0)Vertex Pos      World      Camera        Projection1  0  0  5                 1  0  0  0    w  0  0  00  1  0  5   *  WORLD?  *  0  1  0  0  * 0  h  0  00  0  1  0                 0  0  1  0    0  0  zf/(zf-zn)  10  0  0  1                 0  0  0  1    0  0  -zn*zf/(zf-zn)  0



According to namethatnooneelsetook it is
Quote:vertexposition (with an assumed w of 1...[x,y,z,1]) * world * view * projection.

And i'm a little confused on what the world matrix vs view matrix is. I'm guessing the view matrix is the same as the camera (inverted); in that case what is the world?

Thanks
~Zix

PS: Thanks for the triangle algo, once you have the 3 positions of the triangle, then you simple interpoliate the UV coordinates and draw accordingly (relativly simple).. correct? I'll have to do some thinking on this (along with the aspect of depth buffer), but i think i may have it.
---------------------------------------------------Game Programming Resources, Tutorials, and Multimedia | Free Skyboxes
OpenGL doesn't necessarily have a world, you have a modelview matrix which is both world and view together (I could be wrong, I've never used OpenGL).

In DirectX the World matrix is the matrix that transforms a vertex to world space. ie: It positions and rotates a mesh.

The view matrix is the inverse of the camera's world matrix. If your camera was at 1,2,3, the inverse of that would be a translation matrix of -1,-2,-3. Instead of actually moving a camera through the world, the world is dragged (and rotated) to the camera.

So, lets say we have a vertex at the origin. Lets say our mesh is at 0,0,10. Lets say the camera is at 0,0,2.

vertex pos = 0,0,0
*worldmatrix = 0,0,10
*viewmatrix = 0,0,8
*projection = ...

Thanks everyone.. I'll test all these ideas out and let you know how it goes.

I'll also rate you guys up as soon as it lets me.
EDIT: It just wont let me rate Drillan... is it because he's a GDNet member? o well, i guess i'll report to bugs

~zix~
---------------------------------------------------Game Programming Resources, Tutorials, and Multimedia | Free Skyboxes

This topic is closed to new replies.

Advertisement