Hi,
I'm totally new to 3D stuff. I thought I'd see if I could draw a rectangle
in perspective. For now it's face-on to the screen and doesn't move. I'm just trying to get used to the ideas and functions.
Here's the code I've got :-
| 1 | #include <allegro.h> |
| 2 | |
| 3 | struct vertex { |
| 4 | int x, y, z; |
| 5 | }; |
| 6 | |
| 7 | typedef struct vertex VERTEX; |
| 8 | |
| 9 | struct rectangle { |
| 10 | VERTEX rect_vertices[4]; /* vertices of rectangle relative to eachother */ |
| 11 | int x, y, z; /* co-ordinates of rectangle in world */ |
| 12 | VERTEX rect_vertices_world[4]; /* vertices of rectangle in world */ |
| 13 | }; |
| 14 | |
| 15 | typedef struct rectangle RECTANGLE; |
| 16 | |
| 17 | struct cartesian_point { |
| 18 | fixed x, y; |
| 19 | }; |
| 20 | |
| 21 | typedef struct cartesian_point C_POINT; |
| 22 | |
| 23 | /* all the vertices of the rectangle */ |
| 24 | VERTEX points[] = |
| 25 | { |
| 26 | { 0, 0, 0}, |
| 27 | {100, 0, 0}, |
| 28 | {100, 100, 0}, |
| 29 | { 0, 100, 0} |
| 30 | }; |
| 31 | |
| 32 | RECTANGLE r; |
| 33 | |
| 34 | |
| 35 | void init(void) |
| 36 | { |
| 37 | allegro_init(); |
| 38 | install_keyboard(); |
| 39 | set_color_depth(32); |
| 40 | if(set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) |
| 41 | { |
| 42 | set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); |
| 43 | allegro_message("Unable to set graphics mode.\n"); |
| 44 | exit(1); |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | |
| 49 | void draw_line(BITMAP *, C_POINT, C_POINT); |
| 50 | |
| 51 | void make_rect(void); |
| 52 | |
| 53 | |
| 54 | void draw_line(BITMAP *a, C_POINT point_1, C_POINT point_2) |
| 55 | { |
| 56 | int white = makecol32(255, 255, 255); |
| 57 | line(a, fixtoi(point_1.x), fixtoi(point_1.y), fixtoi(point_2.x), fixtoi(point_2.x), white); |
| 58 | } |
| 59 | |
| 60 | |
| 61 | void make_rect(void) |
| 62 | { |
| 63 | r.rect_vertices[0] = points[0]; |
| 64 | r.rect_vertices[1] = points[1]; |
| 65 | r.rect_vertices[2] = points[2]; |
| 66 | r.rect_vertices[3] = points[3]; |
| 67 | |
| 68 | r.x = 0; |
| 69 | r.y = 0; |
| 70 | r.z = 200; |
| 71 | } |
| 72 | |
| 73 | |
| 74 | |
| 75 | int main() |
| 76 | { |
| 77 | int i; |
| 78 | |
| 79 | C_POINT rect_points_2d[4]; /* Somewhere to store the translated points of the |
| 80 | rectangle. */ |
| 81 | |
| 82 | BITMAP *buffer; |
| 83 | |
| 84 | init(); |
| 85 | |
| 86 | buffer = create_bitmap(640, 480); |
| 87 | |
| 88 | set_projection_viewport(0, 0, SCREEN_W, SCREEN_H); |
| 89 | |
| 90 | /* work out where vertices are in the world */ |
| 91 | |
| 92 | for(i = 0; i < 4; ++i) |
| 93 | { |
| 94 | r.rect_vertices_world<i>.x = r.rect_vertices<i>.x + r.x; |
| 95 | r.rect_vertices_world<i>.y = r.rect_vertices<i>.y + r.y; |
| 96 | r.rect_vertices_world<i>.z = r.rect_vertices<i>.z + r.z; |
| 97 | } |
| 98 | |
| 99 | /* translate the shapes into cartesian coordinates */ |
| 100 | |
| 101 | for(i = 0; i < 4; ++i) |
| 102 | { |
| 103 | persp_project(itofix(r.rect_vertices_world<i>.x), |
| 104 | itofix(r.rect_vertices_world<i>.y), |
| 105 | itofix(r.rect_vertices_world<i>.z), |
| 106 | &rect_points_2d<i>.x, |
| 107 | &rect_points_2d<i>.y); |
| 108 | } |
| 109 | |
| 110 | /* Draw lines between connecting points of the rectangle. */ |
| 111 | |
| 112 | draw_line(buffer, rect_points_2d[0], rect_points_2d[1]); |
| 113 | draw_line(buffer, rect_points_2d[1], rect_points_2d[2]); |
| 114 | draw_line(buffer, rect_points_2d[3], rect_points_2d[4]); |
| 115 | draw_line(buffer, rect_points_2d[4], rect_points_2d[0]); |
| 116 | |
| 117 | blit(buffer, screen, 0, 0, 0, 0, 640, 480); |
| 118 | readkey(); |
| 119 | |
| 120 | return 0; |
| 121 | } |
| 122 | END_OF_MAIN() |
All it does is draw a diagonal line across the screen.
I put plently of comments in to make it easy to understand.
Can someone help me understand what I'm doing wrong please ?
[edit]
sorry, It'd help if I'd have spent a bit more time checking for obvious mistakes
Maybe a pointless comment, but I strongly suggest using AllegroGL and OpenGL instead of Allegro 3D routines. This way you'll get 3D acceleration and programming OpenGL is a bit easier than programming 3D Allegro.
and programming OpenGL is a bit easier than programming 3D Allegro.
No, it's not. It's a lot easier. Allegro's 3d routines are the Malbolge of 3d APIs.
If you want to learn the hard way (by trial and error) how a 3d rendering pipeline works, and how one would go implementing one in software, then by all means look into allegro 3d.
For practical programming tasks, they are rather useless except for very rare situations (e.g. very simple 3d on a very low-end machine that doesn't come with 3d hw accel).
Thanks guys, you're great.