Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Which face are we looking at?

This thread is locked; no one can reply to it. rss feed Print
Which face are we looking at?
ngiacomelli
Member #5,114
October 2004

I'm using a modified version of the allegro 3d example (the bouncing cubes), to spin a single cube around, dependant upon player input.

I'm running into problems when trying to figure out what face of the cube I'm currently looking at. Obviously, I need to do some kind of depth sorting, which I attempted with get_look_face(), but I'm obviously a long way off. I assumed that the sort would return the closest face first.

1QUAD faces[] =
2{
3 { points, 0, 0, 3, 2, 1 },
4 { points, 1, 4, 5, 6, 7 },
5 { points, 2, 0, 1, 5, 4 },
6 { points, 3, 2, 3, 7, 6 },
7 { points, 4, 0, 4, 7, 3 },
8 { points, 5, 1, 2, 6, 5 }
9};
10 
11void draw_shapes(BITMAP *b)
12{
13
14 int c;
15 QUAD *face = output_faces;
16 VTX *v1, *v2, *v3, *v4;
17 
18 qsort(output_faces, NUM_FACES, sizeof(QUAD), quad_cmp);
19 
20 for (c=0; c < NUM_FACES; c++) {
21 
22 v1 = face->vtxlist + face->v1;
23 v2 = face->vtxlist + face->v2;
24 v3 = face->vtxlist + face->v3;
25 v4 = face->vtxlist + face->v4;
26 
27 draw_quad(b, v1, v2, v3, v4, POLYTYPE_PTEX, face->id);
28 
29 face++;
30
31 }
32
33}
34 
35int get_look_face()
36{
37 
38 QUAD *face = output_faces;
39 
40 qsort(output_faces, NUM_FACES, sizeof(QUAD), quad_cmp);
41 
42 return face->id;
43
44}

orz
Member #565
August 2000

For normal depth sorting you want the furthest face first, not the closest face.
You don't show the code for quad_cmp.
I don't know what the point of get_look_face is... I don't see it get called by anything.

ngiacomelli
Member #5,114
October 2004

1typedef struct QUAD
2{
3 VTX *vtxlist;
4 int id;
5 int v1, v2, v3, v4;
6} QUAD;
7 
8typedef struct SHAPE
9{
10 fixed x, y, z;
11 fixed rx, ry, rz;
12 fixed dz;
13 fixed drx, dry, drz;
14} SHAPE;
15 
16VTX points[] =
17{
18 { -32 << 16, -32 << 16, -32 << 16 },
19 { -32 << 16, 32 << 16, -32 << 16 },
20 { 32 << 16, 32 << 16, -32 << 16 },
21 { 32 << 16, -32 << 16, -32 << 16 },
22 { -32 << 16, -32 << 16, 32 << 16 },
23 { -32 << 16, 32 << 16, 32 << 16 },
24 { 32 << 16, 32 << 16, 32 << 16 },
25 { 32 << 16, -32 << 16, 32 << 16 },
26};
27 
28QUAD faces[] =
29{
30 { points, 0, 0, 3, 2, 1 },
31 { points, 1, 4, 5, 6, 7 },
32 { points, 2, 0, 1, 5, 4 },
33 { points, 3, 2, 3, 7, 6 },
34 { points, 4, 0, 4, 7, 3 },
35 { points, 5, 1, 2, 6, 5 }
36};
37 
38SHAPE nav_cube;
39VTX output_points[NUM_VERTICES];
40QUAD output_faces[NUM_FACES];

1int quad_cmp(const void *e1, const void *e2)
2{
3
4 QUAD *q1 = (QUAD *)e1;
5 QUAD *q2 = (QUAD *)e2;
6 
7 fixed d1 = q1->vtxlist[q1->v1].z + q1->vtxlist[q1->v2].z +
8 q1->vtxlist[q1->v3].z + q1->vtxlist[q1->v4].z;
9 
10 fixed d2 = q2->vtxlist[q2->v1].z + q2->vtxlist[q2->v2].z +
11 q2->vtxlist[q2->v3].z + q2->vtxlist[q2->v4].z;
12 
13 return d2 - d1;
14
15}

get_look_face just returns the id of the first face returned from the qsort. id is a bitmap offset.

orz
Member #565
August 2000

Well, I think your sort puts the furthest face first. Which is good, because that's what your rendering needs to look correct. So your get_look_face() returns the face that's farthest away. Perhaps you want it to return the last face out of the sort instead of the first?

ngiacomelli
Member #5,114
October 2004

That's the method I used before posting, but I seem to have gotten my logic mixed up! D'Oh! That seems to have solved the problem! Thanks!

My next question is: what's the easiest way to ensure that all faces of the cube render their bitmaps the right way up? That may sound strange. Imagine if I have text one side of a cube, and then have text on the face behind it. If I then rotate it, allowing the text on the other side to come into view, it's upside down.

How can I sort that out?

EDIT: Here's an ugly diagram:

http://www.perforated-art.com/uglyexample.JPG

Ultio
Member #1,336
April 2001

Isn't that just a matter of texturing the faces in the proper "direction"? Clockwise/Counter clockwise? I forget. I guess it depends on how you actually construct each face. Do you create the vertices where they belong on the final result cube, or do you create six faces in the same spot and then rotate/translate them into place?

---
"It's nice knowing that someday, the software I write will just be pirated by millions of people." :-/
http://loomsoft.net | Zep's Dreamland | Allegro Newbie Tutorials

ngiacomelli
Member #5,114
October 2004

Here is the 3d code in full. As far as I can tell, the cube is created, and then the shape translated into position:

1void translate_shapes(void)
2{
3
4 int c, d;
5 MATRIX matrix;
6 VTX *outpoint = output_points;
7 QUAD *outface = output_faces;
8 
9 get_transformation_matrix(&matrix, itofix(1), nav_cube.rx, nav_cube.ry, nav_cube.rz, nav_cube.x, nav_cube.y, nav_cube.z);
10 
11 for (d = 0; d < NUM_VERTICES; d++) {
12 apply_matrix(&matrix, points[d].x, points[d].y, points[d].z,
13 &outpoint[d].x, &outpoint[d].y, &outpoint[d].z);
14 persp_project(outpoint[d].x, outpoint[d].y, outpoint[d].z,
15 &outpoint[d].x, &outpoint[d].y);
16 }
17 
18 for (d=0; d<NUM_FACES; d++) {
19 outface[d] = faces[d];
20 outface[d].vtxlist = outpoint;
21 }
22 
23 outpoint += NUM_VERTICES;
24 outface += NUM_FACES;
25 
26}
27 
28void draw_quad(BITMAP *b, VTX *v1, VTX *v2, VTX *v3, VTX *v4, int mode, int face)
29{
30
31 int col;
32 
33 /* four vertices */
34 V3D vtx1 = { 0, 0, 0, 0, 0, 0 };
35 V3D vtx2 = { 0, 0, 0, 32<<16, 0, 0 };
36 V3D vtx3 = { 0, 0, 0, 32<<16, 32<<16, 0 };
37 V3D vtx4 = { 0, 0, 0, 0, 32<<16, 0 };
38 
39 vtx1.x = v1->x; vtx1.y = v1->y; vtx1.z = v1->z;
40 vtx2.x = v2->x; vtx2.y = v2->y; vtx2.z = v2->z;
41 vtx3.x = v3->x; vtx3.y = v3->y; vtx3.z = v3->z;
42 vtx4.x = v4->x; vtx4.y = v4->y; vtx4.z = v4->z;
43 
44 vtx1.c = MID(0, 255 - fixtoi(v1->z) / 4, 255);
45 vtx2.c = MID(0, 255 - fixtoi(v2->z) / 4, 255);
46 vtx3.c = MID(0, 255 - fixtoi(v3->z) / 4, 255);
47 vtx4.c = MID(0, 255 - fixtoi(v4->z) / 4, 255);
48 
49 quad3d(b, mode, nav_texture[face], &vtx1, &vtx2, &vtx3, &vtx4);
50
51}
52 
53int quad_cmp(const void *e1, const void *e2)
54{
55
56 QUAD *q1 = (QUAD *)e1;
57 QUAD *q2 = (QUAD *)e2;
58 
59 fixed d1 = q1->vtxlist[q1->v1].z + q1->vtxlist[q1->v2].z +
60 q1->vtxlist[q1->v3].z + q1->vtxlist[q1->v4].z;
61 
62 fixed d2 = q2->vtxlist[q2->v1].z + q2->vtxlist[q2->v2].z +
63 q2->vtxlist[q2->v3].z + q2->vtxlist[q2->v4].z;
64 
65 return d2 - d1;
66
67}
68 
69void draw_shapes(BITMAP *b)
70{
71
72 int c;
73 QUAD *face = output_faces;
74 VTX *v1, *v2, *v3, *v4;
75 
76 qsort(output_faces, NUM_FACES, sizeof(QUAD), quad_cmp);
77 
78 for (c=0; c < NUM_FACES; c++) {
79 
80 v1 = face->vtxlist + face->v1;
81 v2 = face->vtxlist + face->v2;
82 v3 = face->vtxlist + face->v3;
83 v4 = face->vtxlist + face->v4;
84 
85 draw_quad(b, v1, v2, v3, v4, POLYTYPE_PTEX, face->id);
86 
87 face++;
88
89 }
90
91}

nonnus29
Member #2,606
August 2002
avatar

Sounds like you've confused depth sorting with back face culling; you're drawing all of your poly's wether they face the camera or not. Depth sorting is only good for convex models like cubes, otherwise you get 'z fighting'; I found this out in my tank game some of you may (or may not) remember. To do backface culling dot the face normal with the camera; greater than zero is faceing, less than zero is facing away.

For your texturing problem, you have to rotate and translate your texture coordinates along with the spatial coordinates. I don't see you doing that.

Allegro 3d is gross. Use opengl or write your own software renderer. If you write your own you will fully understand how un-useful allegro 3d is.

Edit; you should be using V3d for your verts, it has u,v texture coordinates, I don't see any texture coordinates in the code you posted.

One can only guess where quad3d is getting this information from...

Go to: