![]() |
|
First person camera using transformations |
DontKnow3D
Member #16,883
July 2018
|
i have tried to implement a first person camera, but as you might guess: It don't work. everything works fine in the whole 3d department of my code, except for the camera. if you look forwards everything works, but if you look 90 degrees to the side instead of the camera looking up and down when you move the mouse it spins in a circle and if you look 180 degrees behind yourself the camera is inverted. how do i fix this? i have tried many different formulas but none of them work. mouse processing: 1switch (ev.type) {
2 case ALLEGRO_EVENT_MOUSE_AXES:
3 p.m.x += ev.mouse.dx;
4 p.m.y += ev.mouse.dy;
5 p.m.ax = p.m.x / MOUSE_SPEED;//angle x: 1 rotation = 2*PI
6 p.m.ay = p.m.y / -MOUSE_SPEED;//angle y: goes from -PI/2 to PI/2
7 al_set_mouse_xy(display, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
8 if (p.m.ay > PI / 2) {
9 p.m.ay = PI / 2;
10 p.m.y = ((PI / 2)*-MOUSE_SPEED);
11 }
12 if (p.m.ay < -PI / 2) {
13 p.m.ay = -PI / 2;
14 p.m.y = ((-PI / 2)*-MOUSE_SPEED);
15 }
16//------------------------------------------------
17//----------calculate camera rotation-------------
18//------------------------------------------------
19//-------------how do i do this?------------------
20//------------------------------------------------
21 p.m.cax = p.m.ay;
22 p.m.cay = p.m.ax;
23 p.m.caz = 0;
24
25 /*p.m.cax = cos(p.m.ax) * cos(p.m.ay)*PI;
26 p.m.cay = sin(p.m.ay)*PI;
27 p.m.caz = sin(p.m.ax) * cos(p.m.ay)*PI;*/
28 break;
camera transformation code: 1 al_identity_transform(&tra);
2 al_translate_transform_3d(&tra, p.x, p.y, p.z);
3 al_rotate_transform_3d(&tra, 1, 0, 0, p.m.cax);
4 al_rotate_transform_3d(&tra, 0, 1, 0, p.m.cay);
5 al_rotate_transform_3d(&tra, 0, 0, 1, p.m.caz);
6 al_perspective_transform(&tra, -SCREEN_WIDTH / 2, -SCREEN_HEIGHT / 2, 1000, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 100000);
7 al_use_projection_transform(&tra);
8
9 al_flip_display();
whole code: 1#include<allegro5\allegro.h>
2#include<allegro5\allegro_font.h>
3#include<allegro5\allegro_ttf.h>
4#include<allegro5\allegro_color.h>
5#include<allegro5\allegro_primitives.h>
6#include<allegro5\allegro_image.h>
7#include<cmath>
8
9
10#define LOOP(var,max) for(var=0;var<max;++var)
11#define KD(keycode) al_key_down(&key,ALLEGRO_KEY_##keycode)
12
13#define SCREEN_WIDTH (100 * 16)
14#define SCREEN_HEIGHT (100 * 9)
15#define PI 3.141592653589793238462643
16
17#define MOVE_SPEED 30
18#define MOUSE_SPEED 500. //higher = lower speed
19
20typedef struct {
21 int x, y;//xy location of mouse
22 float ax, ay;//xy angle of mouse
23 float cax, cay, caz;//camera angle
24}mouse_t;
25
26class player_t {
27public:
28 mouse_t m = { 0 };
29 float x = 0, y = 0, z = 0;
30};
31
32void process_keyboard(player_t& p) {
33 ALLEGRO_KEYBOARD_STATE key;
34 al_get_keyboard_state(&key);
35
36 //move the player
37 if (KD(A)) {
38 p.x += MOVE_SPEED * cos(p.m.ax);
39 p.z += MOVE_SPEED * sin(p.m.ax);
40 }
41 if (KD(D)) {
42 p.x -= MOVE_SPEED * cos(p.m.ax);
43 p.z -= MOVE_SPEED * sin(p.m.ax);
44 }
45 if (KD(W)) {
46 p.z += MOVE_SPEED * cos(-p.m.ax);
47 p.x += MOVE_SPEED * sin(-p.m.ax);
48 }
49 if (KD(S)) {
50 p.z -= MOVE_SPEED * cos(-p.m.ax);
51 p.x -= MOVE_SPEED * sin(-p.m.ax);
52 }
53 if (KD(SPACE))
54 p.y += MOVE_SPEED;
55 if (KD(CAPSLOCK) || KD(LSHIFT))
56 p.y -= MOVE_SPEED;
57 if (KD(ESCAPE))
58 exit(0);
59}
60
61void init() {
62 al_init();
63 al_init_image_addon();
64 al_init_primitives_addon();
65 al_init_ttf_addon();
66 al_init_font_addon();
67 al_install_keyboard();
68 al_install_mouse();
69 al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST);
70}
71
72int main() {
73 init();
74 int i, j;
75 auto display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT);
76 auto q = al_create_event_queue();
77 auto fps = al_create_timer(1 / 60.);
78 ALLEGRO_EVENT ev;
79 ALLEGRO_TRANSFORM tra;
80 player_t p;
81 auto font = al_load_ttf_font("fonts/DeansgateCondensed-Bold.ttf", 64, 0);//just a generic font for testing
82 al_register_event_source(q, al_get_timer_event_source(fps));
83 al_register_event_source(q, al_get_mouse_event_source());
84 al_register_event_source(q, al_get_display_event_source(display));
85 al_start_timer(fps);
86 al_set_render_state(ALLEGRO_DEPTH_TEST, 1);
87 auto image = al_load_bitmap("images/ground.jpeg");//random picture of some ground
88 /*p.m.x = SCREEN_WIDTH / 2;
89 p.m.y = SCREEN_HEIGHT / 2;*/
90 al_set_mouse_xy(display, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
91 ALLEGRO_VERTEX cube[] = {
92 {-1000,-1000,-1000, 0,0,al_map_rgb_f(1,1,1)},
93 {-1000,-1000, 1000, 0,0,al_map_rgb_f(1,1,1)},
94 {-1000, 1000, 1000, 0,0,al_map_rgb_f(1,1,1)},
95
96 {1000, 1000,-1000, 0,0,al_map_rgb_f(0,1,1)},
97 {-1000,-1000,-1000, 0,0,al_map_rgb_f(0,1,1)},
98 {-1000, 1000,-1000, 0,0,al_map_rgb_f(0,1,1)},
99
100 {1000,-1000, 1000, 0,0,al_map_rgb_f(1,0,1)},
101 {-1000,-1000,-1000, 0,0,al_map_rgb_f(1,0,1)},
102 {1000,-1000,-1000, 0,0,al_map_rgb_f(1,0,1)},
103
104 {1000, 1000,-1000, 0,0,al_map_rgb_f(1,1,0)},
105 {1000,-1000,-1000, 0,0,al_map_rgb_f(1,1,0)},
106 {-1000,-1000,-1000, 0,0,al_map_rgb_f(1,1,0)},
107
108 {-1000,-1000,-1000, 0,0,al_map_rgb_f(0,0,1)},
109 {-1000, 1000, 1000, 0,0,al_map_rgb_f(0,0,1)},
110 {-1000, 1000,-1000, 0,0,al_map_rgb_f(0,0,1)},
111
112 {1000,-1000, 1000, 0,0,al_map_rgb_f(0,1,0)},
113 {-1000,-1000, 1000, 0,0,al_map_rgb_f(0,1,0)},
114 {-1000,-1000,-1000, 0,0,al_map_rgb_f(0,1,0)},
115
116 {-1000, 1000, 1000, 0,0,al_map_rgb_f(1,0,0)},
117 {-1000,-1000, 1000, 0,0,al_map_rgb_f(1,0,0)},
118 {1000,-1000, 1000, 0,0,al_map_rgb_f(1,0,0)},
119
120 {1000, 1000, 1000, 0,0,al_map_rgb_f(0,0,0)},
121 {1000,-1000,-1000, 0,0,al_map_rgb_f(0,0,0)},
122 {1000, 1000,-1000, 0,0,al_map_rgb_f(0,0,0)},
123
124 {1000,-1000,-1000, 0,0,al_map_rgb_f(1,1,1)},
125 {1000, 1000, 1000, 0,0,al_map_rgb_f(1,1,1)},
126 {1000,-1000, 1000, 0,0,al_map_rgb_f(1,1,1)},
127
128 {1000, 1000, 1000, 0,0,al_map_rgb_f(0,1,1)},
129 {1000, 1000,-1000, 0,0,al_map_rgb_f(0,1,1)},
130 {-1000, 1000,-1000, 0,0,al_map_rgb_f(0,1,1)},
131
132 {1000, 1000, 1000, 0,0,al_map_rgb_f(1,0,1)},
133 {-1000, 1000,-1000, 0,0,al_map_rgb_f(1,0,1)},
134 {-1000, 1000, 1000, 0,0,al_map_rgb_f(1,0,1)},
135
136 {1000, 1000, 1000, 0,0,al_map_rgb_f(1,1,0)},
137 {-1000, 1000, 1000, 0,0,al_map_rgb_f(1,1,0)},
138 {1000,-1000, 1000, 0,0,al_map_rgb_f(1,1,0)},
139 };
140 ALLEGRO_VERTEX ground[] = {
141 { 1000,0,1000,al_get_bitmap_width(image),al_get_bitmap_height(image),al_map_rgb_f(1,1,1) },
142 { -1000,0,1000,0,al_get_bitmap_height(image),al_map_rgb_f(1,1,1) },
143 { -1000,0,-1000,0,0,al_map_rgb_f(1,1,1) },
144
145 { 1000,0,1000,al_get_bitmap_width(image),al_get_bitmap_height(image),al_map_rgb_f(1,1,1) },
146 { 1000,0,-1000,al_get_bitmap_width(image),0,al_map_rgb_f(1,1,1) },
147 { -1000,0,-1000,0,0,al_map_rgb_f(1,1,1) },
148 };
149 while (1) {
150 al_wait_for_event(q, &ev);
151 switch (ev.type) {
152 case ALLEGRO_EVENT_MOUSE_AXES:
153 p.m.x += ev.mouse.dx;
154 p.m.y += ev.mouse.dy;
155 p.m.ax = p.m.x / MOUSE_SPEED;//angle x: 1 rotation = 2*PI
156 p.m.ay = p.m.y / -MOUSE_SPEED;//angle y: goes from -PI/2 to PI/2
157 al_set_mouse_xy(display, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
158 if (p.m.ay > PI / 2) {
159 p.m.ay = PI / 2;
160 p.m.y = ((PI / 2)*-MOUSE_SPEED);
161 }
162 if (p.m.ay < -PI / 2) {
163 p.m.ay = -PI / 2;
164 p.m.y = ((-PI / 2)*-MOUSE_SPEED);
165 }
166//------------------------------------------------
167//----------calculate camera rotation-------------
168//------------------------------------------------
169//-------------how do i do this?------------------
170//------------------------------------------------
171 p.m.cax = p.m.ay;
172 p.m.cay = p.m.ax;
173 p.m.caz = 0; //ev.mouse.z / 100.;
174
175 /*p.m.cax = cos(p.m.ax) * cos(p.m.ay)*PI;
176 p.m.cay = sin(p.m.ay)*PI;
177 p.m.caz = sin(p.m.ax) * cos(p.m.ay)*PI;*/
178
179 break;
180 case ALLEGRO_EVENT_TIMER:
181 //key input
182 process_keyboard(p);
183
184 //clear display
185 al_clear_to_color(al_map_rgb_f(0.5, 0.5, 0.5));
186 al_clear_depth_buffer(10000);
187
188 //draw the normalized angles (floating text around you) (2*PI = 1)
189 al_identity_transform(&tra);
190 al_translate_transform_3d(&tra, -p.x, -p.y, -p.z - 2000);
191 al_use_transform(&tra);
192 LOOP(j, 12) {
193 al_rotate_transform_3d(&tra, 0, 1, 0, PI / 6);
194 LOOP(i, 12) {
195 al_rotate_transform_3d(&tra, 1, 0, 0, PI / 6);
196 al_use_transform(&tra);
197 al_draw_multiline_textf(font, al_map_rgb_f(0, 1, 0.5), 50, 50, 0, 0, 0, "ax_%.4f ay_%.4f cax_%.4f cay_%.4f caz_%.4f", p.m.ax / PI / 2, p.m.ay / PI / 2, p.m.cax / PI / 2, p.m.cay / PI / 2, p.m.caz / PI / 2);
198 }
199 }
200 //draw the ground
201 al_identity_transform(&tra);
202 al_scale_transform_3d(&tra, 10, 0, 10);
203 al_translate_transform_3d(&tra, 0, 6000, 0);
204 al_use_transform(&tra);
205 al_draw_prim(ground, NULL, image, 0, 6, ALLEGRO_PRIM_TRIANGLE_LIST);
206
207 //draw the 5 floating cubes
208 al_identity_transform(&tra);
209 al_translate_transform_3d(&tra, 0, 0, -4000);
210 al_use_transform(&tra);
211 al_draw_prim(cube, NULL, NULL, 0, sizeof(cube) / sizeof(cube[0]), ALLEGRO_PRIM_TRIANGLE_LIST);
212 al_translate_transform_3d(&tra, 0, 5000, 0);
213 al_use_transform(&tra);
214 al_draw_prim(cube, NULL, NULL, 0, sizeof(cube) / sizeof(cube[0]), ALLEGRO_PRIM_TRIANGLE_LIST);
215 al_translate_transform_3d(&tra, 5000, -5000, 5000);
216 al_use_transform(&tra);
217 al_draw_prim(cube, NULL, NULL, 0, sizeof(cube) / sizeof(cube[0]), ALLEGRO_PRIM_TRIANGLE_LIST);
218 al_translate_transform_3d(&tra, -5000, -5000, 5000);
219 al_use_transform(&tra);
220 al_draw_prim(cube, NULL, NULL, 0, sizeof(cube) / sizeof(cube[0]), ALLEGRO_PRIM_TRIANGLE_LIST);
221 al_translate_transform_3d(&tra, -5000, 5000, 5000);
222 al_use_transform(&tra);
223 al_draw_prim(cube, NULL, NULL, 0, sizeof(cube) / sizeof(cube[0]), ALLEGRO_PRIM_TRIANGLE_LIST);
224
225 //do the camera transforms
226 al_identity_transform(&tra);
227 al_translate_transform_3d(&tra, p.x, p.y, p.z);
228 al_rotate_transform_3d(&tra, 1, 0, 0, p.m.cax);
229 al_rotate_transform_3d(&tra, 0, 1, 0, p.m.cay);
230 al_rotate_transform_3d(&tra, 0, 0, 1, p.m.caz);
231 al_perspective_transform(&tra, -SCREEN_WIDTH / 2, -SCREEN_HEIGHT / 2, 1000, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 100000);
232 al_use_projection_transform(&tra);
233
234 al_flip_display();
235 break;
236 }
237 }
238}
(and i also cant manage to figure out how to draw a 'hud' or just simple things right on the display after the transformations) |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
You have to understand there are two matrices involved. The projection matrix, and the view matrix. You're mixing the two, and you still aren't even trying to do what I showed you in the other thread. https://www.allegro.cc/forums/thread/617512/1038669#target Also, you are mixing 2D and 3D drawing without resetting your projection matrices properly. You should read over the manual entry for transformations. https://liballeg.org/a5docs/trunk/transformations.html Specifically, look at the docs for al_build_camera_transform , al_orthographic_transform, and al_perspective_transform. For 2D you use the orthographic transform for the projection matrix. For 3D you use the perspective transform for the projection matrix. For 2D view matrix, all you need is the identity. For 3D, you need to apply a camera transform to the view matrix. First, see https://liballeg.org/a5docs/trunk/transformations.html#al_use_projection_transform for the difference between 2D and 3D projection matrices. Second, see https://liballeg.org/a5docs/trunk/transformations.html#al_build_camera_transform for how to set up your camera. As I told you before, you need to use a forward, right, and up vector to define the orientation of the camera. You also need a position for the camera. Then the lookAt parameter becomes camera.position + forward_vector. EDIT The compass heading becomes the rotation around the y-axis on the xz plane. +Y -Z | / | / | / -X_____|/____ +X /| / | / | +Z -Y And then the pitch become the rotation around the right vector. I think that's right but I'm tired. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
DontKnow3D
Member #16,883
July 2018
|
OK so; I have majorly rewritten how everything about my perspective/transformation/drawing works. I now first generate 1 mesh, where everything 3d is stored and then draw all of that at once to the screen. 2d operations work now too and i think i have gotten a much better grasp on how the perspective transformations work. i now also use the camera transformation. the only thing that doesent work now is: the camera. I think I'm using the camera correctly, but apparently I'm not. and if you see anything I'm doing wrong now with the transformations, pleas tell me. 1#include<allegro5\allegro.h>
2#include<allegro5\allegro_font.h>
3#include<allegro5\allegro_ttf.h>
4#include<allegro5\allegro_color.h>
5#include<allegro5\allegro_primitives.h>
6#include<allegro5\allegro_image.h>
7#include<cmath>
8#include<cstdlib>
9#include<iostream>
10
11#define FOV (PI/2) //90 degrees (vertical not horizontal)
12
13#define KD(keycode) al_key_down(&key,ALLEGRO_KEY_##keycode)
14#define LOOP(var,max) for(var=0;var<max;++var)
15
16#define PI 3.141592653589793238462643
17#define SCREEN_WIDTH (100 * 16)
18#define SCREEN_HEIGHT (100 * 9)
19
20#define MOVE_SPEED .03
21#define MOUSE_SPEED 500. //higher = lower speed
22
23typedef struct {
24 int x, y;//xy location of mouse
25 float ax, ay;//xy angle of mouse
26 float cax, cay, caz;//camera "location"
27}mouse_t;
28
29class player_t {
30public:
31 mouse_t m = { 0 };
32 float x = 0, y = 0, z = 3;
33};
34
35class mesh_t {
36public:
37 size_t size_of_mesh = 0;
38 ALLEGRO_VERTEX * mesh = NULL;
39 void add_to_mesh_transform(ALLEGRO_VERTEX*add, size_t amount_of_vertices, ALLEGRO_TRANSFORM*transform) {
40 ALLEGRO_VERTEX*v = (ALLEGRO_VERTEX*)malloc(sizeof(ALLEGRO_VERTEX)*amount_of_vertices);
41 if (v == NULL) {
42 std::cout << "EVERYTHING HAS FAILED! ABORT NOW OR COMPUTER WILL EXPLODE!" << std::endl;
43 al_rest(5);
44 exit(1);
45 }
46 memcpy(v, add, amount_of_vertices * sizeof(ALLEGRO_VERTEX));
47 int i;
48 LOOP(i, amount_of_vertices) {
49 al_transform_coordinates_3d(transform, &v[i].x, &v[i].y, &v[i].z);
50 }
51 mesh = (ALLEGRO_VERTEX*)realloc(mesh, sizeof(ALLEGRO_VERTEX)*(amount_of_vertices + size_of_mesh));
52 memcpy(&(mesh[size_of_mesh]), v, amount_of_vertices * sizeof(ALLEGRO_VERTEX));
53 size_of_mesh += amount_of_vertices;
54 free(v);
55 }
56 void reset_mesh() {
57 free(mesh);
58 mesh = NULL;
59 size_of_mesh = 0;
60 }
61 //size_t size() {
62 // return size_of_mesh;
63 //}
64};
65
66void process_keyboard(player_t& p) {
67 ALLEGRO_KEYBOARD_STATE key;
68 al_get_keyboard_state(&key);
69
70 //move the player
71 if (KD(A)) {
72 p.x += MOVE_SPEED * cos(p.m.ax);
73 p.z += MOVE_SPEED * sin(p.m.ax);
74 }
75 if (KD(D)) {
76 p.x -= MOVE_SPEED * cos(p.m.ax);
77 p.z -= MOVE_SPEED * sin(p.m.ax);
78 }
79 if (KD(W)) {
80 p.z += MOVE_SPEED * cos(-p.m.ax);
81 p.x += MOVE_SPEED * sin(-p.m.ax);
82 }
83 if (KD(S)) {
84 p.z -= MOVE_SPEED * cos(-p.m.ax);
85 p.x -= MOVE_SPEED * sin(-p.m.ax);
86 }
87 if (KD(SPACE))
88 p.y += MOVE_SPEED;
89 if (KD(CAPSLOCK) || KD(LSHIFT))
90 p.y -= MOVE_SPEED;
91 if (KD(ESCAPE))
92 exit(0);
93}
94
95void init() {
96 al_init();
97 al_init_image_addon();
98 al_init_primitives_addon();
99 al_init_ttf_addon();
100 al_init_font_addon();
101 al_install_keyboard();
102 al_install_mouse();
103 al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST);
104}
105
106void setup_3d_projection() {
107 ALLEGRO_TRANSFORM projection;
108 al_identity_transform(&projection);
109 al_translate_transform_3d(&projection, 0, 0, 0);
110 double fov = tan(FOV / 2);
111 al_perspective_transform(&projection, -1 * SCREEN_WIDTH / SCREEN_HEIGHT * fov, fov, 1, fov*SCREEN_WIDTH / SCREEN_HEIGHT, -fov, 1000);
112 al_use_projection_transform(&projection);
113}
114
115int main() {
116 init();
117 int i, j;
118 auto display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT);
119 auto q = al_create_event_queue();
120 auto fps = al_create_timer(1 / 60.);
121 mesh_t mesh;
122 ALLEGRO_EVENT ev;
123 ALLEGRO_TRANSFORM tra, cam, curprotra;
124 player_t p;
125 auto font = al_load_ttf_font("fonts/DeansgateCondensed-Bold.ttf", 16, 0);//just a generic font for testing
126 al_register_event_source(q, al_get_timer_event_source(fps));
127 al_register_event_source(q, al_get_mouse_event_source());
128 al_register_event_source(q, al_get_display_event_source(display));
129 al_start_timer(fps);
130 auto image = al_load_bitmap("images/ground.jpeg");//random picture of some ground
131 al_set_mouse_xy(display, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
132 ALLEGRO_VERTEX cube[] = {
133 {-1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(1,1,1)},
134 {-1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(1,1,1)},
135 {-1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(1,1,1)},
136
137 {1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(0,1,1)},
138 {-1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(0,1,1)},
139 {-1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(0,1,1)},
140
141 {1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(1,0,1)},
142 {-1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(1,0,1)},
143 {1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(1,0,1)},
144
145 {1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(1,1,0)},
146 {1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(1,1,0)},
147 {-1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(1,1,0)},
148
149 {-1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(0,0,1)},
150 {-1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(0,0,1)},
151 {-1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(0,0,1)},
152
153 {1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(0,1,0)},
154 {-1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(0,1,0)},
155 {-1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(0,1,0)},
156
157 {-1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(1,0,0)},
158 {-1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(1,0,0)},
159 {1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(1,0,0)},
160
161 {1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(0,0,0)},
162 {1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(0,0,0)},
163 {1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(0,0,0)},
164
165 {1.0f,-1.0f,-1.0f, 0,0,al_map_rgb_f(1,1,1)},
166 {1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(1,1,1)},
167 {1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(1,1,1)},
168
169 {1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(0,1,1)},
170 {1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(0,1,1)},
171 {-1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(0,1,1)},
172
173 {1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(1,0,1)},
174 {-1.0f, 1.0f,-1.0f, 0,0,al_map_rgb_f(1,0,1)},
175 {-1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(1,0,1)},
176
177 {1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(1,1,0)},
178 {-1.0f, 1.0f, 1.0f, 0,0,al_map_rgb_f(1,1,0)},
179 {1.0f,-1.0f, 1.0f, 0,0,al_map_rgb_f(1,1,0)},
180 };
181 ALLEGRO_VERTEX ground[] = {
182 { 1.0f,0,1.0f,al_get_bitmap_width(image),al_get_bitmap_height(image),al_map_rgb_f(0,1,1) },
183 { -1.0f,0,1.0f,0,al_get_bitmap_height(image),al_map_rgb_f(1,0,1) },
184 { -1.0f,0,-1.0f,0,0,al_map_rgb_f(1,1,0) },
185
186 { 1.0f,0,1.0f,al_get_bitmap_width(image),al_get_bitmap_height(image),al_map_rgb_f(0,0,1) },
187 { 1.0f,0,-1.0f,al_get_bitmap_width(image),0,al_map_rgb_f(1,0,0) },
188 { -1.0f,0,-1.0f,0,0,al_map_rgb_f(0,1,0) },
189 };
190
191 //initialize the mesh
192 al_identity_transform(&tra);
193 mesh.add_to_mesh_transform(cube, std::size(cube), &tra);
194 al_translate_transform_3d(&tra, 3, 0, 0);
195 mesh.add_to_mesh_transform(cube, std::size(cube), &tra);
196 al_identity_transform(&tra);
197 al_scale_transform_3d(&tra, 10, 1, 10);
198 al_translate_transform_3d(&tra, 0, 6, 0);
199 mesh.add_to_mesh_transform(ground, std::size(ground), &tra);
200
201 while (1) {
202 al_wait_for_event(q, &ev);
203 switch (ev.type) {
204 case ALLEGRO_EVENT_MOUSE_AXES:
205 p.m.x += ev.mouse.dx;
206 p.m.y += ev.mouse.dy;
207 p.m.ax = p.m.x / MOUSE_SPEED;//angle x: 1 rotation = 2*PI
208 p.m.ay = p.m.y / -MOUSE_SPEED;//angle y: goes from -PI/2 to PI/2
209 al_set_mouse_xy(display, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
210 /*if (p.m.ay > PI / 2) {
211 p.m.ay = PI / 2;
212 p.m.y = ((PI / 2)*-MOUSE_SPEED);
213 }
214 if (p.m.ay < -PI / 2) {
215 p.m.ay = -PI / 2;
216 p.m.y = ((-PI / 2)*-MOUSE_SPEED);
217 }*/
218
219//--------------camera calculations----------------
220 p.m.cax = cos(p.m.ay)*sin(p.m.ax);
221 p.m.cay = cos(p.m.ay)*cos(p.m.ax);
222 p.m.caz = sin(p.m.ay);
223
224 std::cout << "cax=" << p.m.cax << '\t' << "cay=" << p.m.cay << '\t' << "caz=" << p.m.caz << '\t' << std::endl;
225 break;
226 case ALLEGRO_EVENT_TIMER:
227 //key input
228 process_keyboard(p);
229
230 curprotra = *al_get_current_projection_transform();
231 setup_3d_projection();
232
233 al_clear_to_color(al_map_rgb_f(0.5, 0.5, 0.5));
234 al_set_render_state(ALLEGRO_DEPTH_TEST, 1);
235 al_clear_depth_buffer(1);
236
237// ----------------camera transform---------------
238 al_build_camera_transform(&cam, p.x, p.y, p.z,
239 p.x + p.m.cax, p.y + p.m.cay, p.z + p.m.caz,
240 0, 1, 0);
241 al_use_transform(&cam);
242 //draw 3d things
243 al_draw_prim(mesh.mesh, NULL, NULL, 0, mesh.size_of_mesh, ALLEGRO_PRIM_TRIANGLE_LIST);
244
245 //restore projection
246 al_identity_transform(&tra);
247 al_use_transform(&tra);
248 al_use_projection_transform(&curprotra);
249 al_set_render_state(ALLEGRO_DEPTH_TEST, 0);
250
251 //draw 2d things
252 al_draw_multiline_textf(font, al_map_rgb_f(0.8, 0.1, 0.2), 50, 50, 0, 0, 0, "normalized(2PI=1) ax_%.4f ay_%.4f not_normalized cax_%.4f cay_%.4f caz_%.4f", p.m.ax / PI / 2, p.m.ay / PI / 2, p.m.cax, p.m.cay, p.m.caz);
253 al_flip_display();
254 break;
255 }
256 }
257}
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
I think your formula is just a bit off. You have z and y reversed. It should be :
{"name":"611674","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/4\/94b598fff0562e56a5c7bf072c62b984.png","w":800,"h":600,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/4\/94b598fff0562e56a5c7bf072c62b984"} Or you can build your forward vector using transforms : 1 void RebuildTransform() {
2 fw = Vec(0,0,-1);
3 rt = Vec(1,0,0);
4 up = Vec(0,1,0);
5 /// Apply yaw
6 ALLEGRO_TRANSFORM t1;
7 al_identity_transform(&t1);
8 al_rotate_transform(&t1 , up.x , up.y , up.z , yaw);
9 al_transform_coordinates(&t1 , &rt.x , &rt.y , &rt.z);
10 al_transform_coordinates(&t1 , &fw.x , &fw.y , &fw.z);
11
12 /// Apply pitch
13 al_identity_transform(&t1);
14 al_rotate_transform(&t1 , rt.x , rt.y , rt.z , yaw);
15 al_transform_coordinates(&t1 , &up.x , &up.y , &up.z);
16 al_transform_coordinates(&t1 , &fw.x , &fw.y , &fw.z);
17
18 /// Apply roll
19 //...
20 Vec look = pos + fw;
21 al_build_camera_transform(&t , pos.x , pos.y , pos.z , look.x , look.y , look.z , up.x , up.y , up.z);
22 }
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
DontKnow3D
Member #16,883
July 2018
|
ok thank you! you've been a great help in all of this. there is just 1 more thing id like to figure out. in my code right after i use the camera transformation, i draw the whole map mesh. now i would like to also draw other things and use transformations on them. but if i trie to do that, it doesent really work. the things i draw after the new transformations move with the camera rotation. how would i fix that? 1// ----------------camera transform---------------
2 al_build_camera_transform(&cam, p.x, p.y, p.z,
3 p.x + p.m.cax, p.y + p.m.cay, p.z + p.m.caz,
4 0, 1, 0);
5 al_use_transform(&cam);
6
7 //draw 3d things
8 al_draw_prim(mesh.mesh, NULL, NULL, 0, mesh.size_of_mesh, ALLEGRO_PRIM_TRIANGLE_LIST);//drawing the mesh as before
9
10//now draw an extra cube 3 units below 0,0,0
11 ALLEGRO_TRANSFORM copy_of_cam, transform;
12 al_identity_transform(&transform);
13 al_copy_transform(©_of_cam, &cam);
14
15 al_translate_transform_3d(&transform,0, -3, 0);
16 al_compose_transform(©_of_cam, &transform);
17 al_use_transform(©_of_cam);
18
19 al_draw_prim(cube, NULL, NULL, 0, std::size(cube), ALLEGRO_PRIM_TRIANGLE_LIST);
20
21 //restore projection
22 //...
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
You need to transform your objects first, before applying the camera transform. Do the same thing, but swap the order. ALLEGRO_TRANSFORM t; al_identity_transform(&t); al_translate_transform(&t , 0 , -3 , 0); al_compose_transform(&t , &cam); al_use_transform(&t);
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
DontKnow3D
Member #16,883
July 2018
|
thank you! you've been a great help! |
|