C Board  

Go Back   C Board > General Programming Boards > FAQ Board

 
 
LinkBack Thread Tools Display Modes
Old 09-22-2004, 11:29 AM   #1
Registered User
 
crepincdotcom's Avatar
 
Join Date: Oct 2003
Posts: 94
Cool FAQ: Graphics Math

Hey guys,

this is more of a meth question and less of c, but after searching google for a long time I wasn't getting aynwhere.

Basically, I would like to render a 3d wireframe on the screen, WITHOUT LIBRARIES. I want to hack a few functions to draw lines, then use those, along with math, to make, for instance, a grid-plane that I can 'rotate' around, and have the lines stay in perspective.

so really there are two questions here:

1) (main) How can I use "transformation matrices" to move around this grid and keep the lines correct?

2) (insignificant) How can I stick a single pixel on the screen?

I'm not really looking for straight answers, but perhaps some article people might have seen over the years.

Thanks again,
__________________
-Jack C
jack {at} crepinc.com
http://www.crepinc.com
crepincdotcom is offline  
Old 09-22-2004, 12:00 PM   #2
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
Well this is a nice long read
http://thorkildsen.no/faqsys/
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline  
Old 09-22-2004, 12:25 PM   #3
Registered User
 
Join Date: Apr 2002
Posts: 1,571
Start here, it's a 4 part series...

http://www.devmaster.net/articles/so...ring/part1.php
__________________
"...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers
MrWizard is offline  
Old 09-22-2004, 05:40 PM   #4
Registered User
 
crepincdotcom's Avatar
 
Join Date: Oct 2003
Posts: 94
Quote:
Originally Posted by Salem
Well this is a nice long read
http://thorkildsen.no/faqsys/
Seems to be the opening page... didn't have a lot of time now, but tomorrow whould I read the whole site? Or is there just a good long peice....

Thanks guys...

And a func to turn on a pixel in c?
__________________
-Jack C
jack {at} crepinc.com
http://www.crepinc.com
crepincdotcom is offline  
Old 09-22-2004, 05:54 PM   #5
Registered User
 
crepincdotcom's Avatar
 
Join Date: Oct 2003
Posts: 94
After reading the devmaster article..... I understand the math but fail to see how to take an x,y,z point and, using perspective, make it on the screen. (other than by dropping z, and having the camera dead-center)

I will read it again though, perhaps I missed something.....
__________________
-Jack C
jack {at} crepinc.com
http://www.crepinc.com
crepincdotcom is offline  
Old 09-22-2004, 10:57 PM   #6
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,472
You divide by Z - or in the case of modern graphics you divide by W. This is the perspective projection.

Before matrices were widely used this was the formula used for dividing by Z.

Screen.x=(View.x*Dist_To_Plane)/(View.z+CenterScreen.x);
Screen.y=(View.y*Dist_To_Plane)/(View.z+CenterScreen.y);

But with matrices this can be done quite easily and it can also then be added into the graphics pipeline that already uses matrices quite heavily. The advantage is you don't have to change your projection function significantly to perspective project your vertices into screen space.

You really need to buy a book on the mathematics of 3D graphics in order to understand how it all works.

Translation is really just this:

x+=distance_x;
y+=distance_y;
z+=distance_z;

But because of the way we multiply or concatenate matrices a 4x4 homogneous matrix works very well for this:

[1,0,0,0]
[0,1,0,0]
[0,0,1,0]
[distance_x,distance_y,distance_z,1]

A simple concatenation function (and not by any means the fastest) for a 4x4 matrix. Matrix is assumed to be a 4x4 array - again not the best way.


Code:
void MatMultiply(float mat1[4][4],float mat2[4][4],float result[4][4])
{
  for (int i=0;i<4;i++)
  {
	for (int j=0;j<4;j++)
	{
	  result[i][j]=0.0f;
	  for (int k=0;k<4;k++)
	  {
		result[i][j]+=mat1[i][k]*mat2[k][j];
	  }
	}
  }
}

And a simple world transform function.

Code:
void WorldTransform(vertex *vtxs,int numvtxs,float wm[4][4])
{
  for (int i=0;i<numvtxs;i++)
  {
	float lx=vtxs[i].model.x;
	float ly=vtxs[i].model.y;
	float lz=vtsx[i].model.z;
 
	float wx,wy,wz=0.0f;
 
	wx=lx*wm[0][0]+ly*wm[1][0]+lz*wm[2][0]+wm[3][0];
	wy=ly*wm[0][1]+ly*wm[1][1]+lz*wm[2][1]+wm[3][1];
	wz=lz*wm[0][2]+ly*wm[1][2]+lz*wm[2][2]+wm[3][2];
	vtxs[i].world.x=wx;
	vtxs[i].world.y=wy;
	vtxs[i].world.z=wz;
   }
}
But thankfully in DirectX you don't need to worry about all of this because it is done for you. No more tracking of model, world, view, and screen vertexes/coordinates. But the above code is from a software 3D engine I wrote quite some time ago.
Bubba is offline  
Old 09-23-2004, 01:22 AM   #7
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> Seems to be the opening page
Yeah, click the mathematics link for actual tutorials
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline  
Old 09-24-2004, 09:11 AM   #8
Registered User
 
crepincdotcom's Avatar
 
Join Date: Oct 2003
Posts: 94
Salem, that site will keep me busy for the next 11 hours....

OK bubba, I did your example. I finally saw that it works, and how, however it was in the article you previously sent me as x=D*X'/z... and D was a constant they showed how to get: 1/tan(theta). I figured theta was the angle to look at... but actually, as you posted, it's the distance from the plane.

That's cool.... but I was hoping to figure out how to make an x,y,z point become and x,y, but showing the peices behind the front at an angle, for instance up and to the right maybe, not just expanding sideways in the back. Do I do this with the rotation peice you showed me? Or am I paddling up the wrong creek?

Thanks guys,
__________________
-Jack C
jack {at} crepinc.com
http://www.crepinc.com
crepincdotcom is offline  
Old 09-24-2004, 09:17 AM   #9
Crazy Fool
 
Perspective's Avatar
 
Join Date: Jan 2003
Location: Canada
Posts: 2,588
You need to first perform all the rotations and translations in 3D, then project the resulting vertices on to the projection plane.
Perspective is offline  
Old 09-24-2004, 09:19 AM   #10
Registered User
 
crepincdotcom's Avatar
 
Join Date: Oct 2003
Posts: 94
so... say I have 8 points that make a box. I rotate the box sideways, then when I use the formula from about to get the 2-D points, it works?

I'l hack that up real quick and see if i can get it to work.

Thanks
__________________
-Jack C
jack {at} crepinc.com
http://www.crepinc.com
crepincdotcom is offline  
Old 09-29-2004, 10:51 AM   #11
Registered User
 
crepincdotcom's Avatar
 
Join Date: Oct 2003
Posts: 94
Ok, i'm having a hard time conceptualtizing this. I'mm trying to just make a wireframe box rotate. So I can draw one box... but getting the next point by a 2-degree rotation is hard.

So, I was wondering, does anyone know of any tutorials with example code that show how to do this? If I could just see someone else's code, I could figure it out. I've just never seen how these things are done in the "real world" (ie, not some little dude like me trying to do a big math thing.)

Thanks again you guys,
__________________
-Jack C
jack {at} crepinc.com
http://www.crepinc.com
crepincdotcom is offline  
Old 09-29-2004, 11:45 PM   #12
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,472
You are confused as to what is happening.

First all graphics in 3D are centered around 0,0,0. Every object is centered around 0,0,0 in model space or at least should be or weird things begin to happen. Since you want to always see your 2D wireframe box set the z coordinates to something greater than or equal to 1.0f, but greater than 1.0f is your best bet.

So imagine a universe. A universe is made of planets. The sun is just another very bright planet. All planets have their center at 0,0,0 in their model space. But you want to transform them to world space. So if you want your model to rotate in model space you must rotate first and then translate. If you translate first and then rotate your rotation will be in world space or will make the planet orbit the sun.

All models start in model space. They are then transformed to world space. Then to camera/view space, then to clip space, then to screen space.

It truly is impossible for me to explain 3D mathematics, matrix concatenation, and matrix transformation in one post. I would suggest purchasing a book about 3D to start you on your way. I could write a huge post here with all kinds of code, but it would only confuse the heck out of you. Get a book.

Last edited by Bubba; 09-29-2004 at 11:48 PM.
Bubba is offline  
Old 09-30-2004, 06:53 AM   #13
Registered User
 
crepincdotcom's Avatar
 
Join Date: Oct 2003
Posts: 94
OK, I will get a book. But, about centering 0,0,0: I first tryed that a while ago, and what came out was sorts of strange. But probably my fault. So, can you have negative values in the 3d-2d conversion? Ie, is 5,5,5 the same as 5,5,-5? It shouldn't be, I had trouble with that. So, basically, if I just make a box like 5,5,5 5,-5,5 -5,-5,5, etc for all 8 points, that should work?

Thanks agian,
__________________
-Jack C
jack {at} crepinc.com
http://www.crepinc.com
crepincdotcom is offline  
Old 10-04-2004, 11:19 AM   #14
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,472
This depends on your coordinate system. For all of my systems thus far I use this:

-X is left.
+X is right.
-Y is up.
+Y is down.
-Z is toward the camera.
+Z is away from the camera.

So a 2D 20x20 unit box that lies 1.0 z unit from the camera has the following vertexes wound in counterclockwise rotation. I say unit because these values must be appropriate for the system of measurement you are using. For now let's say that all units are pixels.

Vertex 0.......-20,-20,1
Vertex 1........20,-20,1
Vertex 2........-20,20,1
Vertex 3........20,20,1

Okay that is the front face. Now a 3D cube is just a front and a back face connected by 4 lines - which then create 4 more faces. So create the backface. Let's say it is 21 units away from the camera, thus giving our cube a width of 20, height of 20, and depth of 20.

Vertex 4.....-20,-20,21
Vertex 5.....20,-20,21
Vertex 6.....-20,20,21
Vertex 7.....20,20,21

Okay you now have all the vertexes needed for a 6 sided 3D cube. The only thing left to do is create the indices or indexes for the cube. Indexes allow you to specify vertex numbers that make up triangles. So each triangle will have 3 indexes. For instance let's triangulate the front face in a counter-clockwise fashion.

Triangle 1
Vertex 0
Vertex 1
Vertex 2

So the indices for triangle 1 are 0,1,2

Triangle 2

Vertex 1
Vertex 3
Vertex 2

Indices: 1,3,2

So your first 2 sets of indexes for the front face are:

0,1,2
1,3,2

Notice that you can specify these vertexes in any order as long as they proceed counterclockwise around the triangle when viewed from the front if your culling mode is counter-clockwise culling else you must specify vertices in clockwise order.

As you will notice indexing into the vertex data is much more efficient. In this picture alone you can see that these triangles share vertices 1 and 2 but we only declare them once. This means that you index array will be larger than your vertex array, but indices are integers and vertexes are normally floats - 3 of them to be exact. Indexing saves a lot of memory.

Also not that when you specify a triangle you need not specify the closing leg. For instance specifying 0,1,2 to Direct3D will cause a line to be drawn from 0 to 1, 1 to 2, and 2 to 0. You need not specify 2,0 in your index array. Most APIs automatically close the triangle for you so you only need to specify 3 indexes per triangle. Specifying 0,1,2 is much more effienct than doing this:

0,1
1,2
2,0

So instead of specifying six indexes per triangle you can specify three.

Last edited by Bubba; 10-04-2004 at 11:25 AM.
Bubba is offline  
Old 10-04-2004, 11:30 AM   #15
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,472
I omitted the texture coords from my first picture. Here is another picture with the texture coords.

They are specified in (u,v) format where u is the horizontal and v is the vertical.

They are specified in range 0.0f to 1.0f - which means that your texture coords are independent of texture size. If you specify .50f,.50f on a 100x100 texture it will be 50,50. If you specify .50f,.50f on a 1000x1000 texture it will be 500x500. Notice both correspond to the center of the texture regardless of size. These are called normalized texture coordinates since they always fall in the range 0.0f to 1.0f.
Bubba is offline  
 

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Wiki FAQ dwks General Discussions 192 04-29-2008 01:17 PM
an easy, portable, python accessible graphics math library ichijoji Game Programming 2 12-07-2006 12:10 AM
Beginning Game Programming Type Books bumfluff Game Programming 36 09-13-2006 04:15 PM
how to use operator+() in this code? barlas C++ Programming 10 07-09-2005 07:22 PM
Min Math level req for 3d graphics? EvBladeRunnervE Game Programming 12 02-24-2003 10:32 PM


All times are GMT -6. The time now is 09:08 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22