first render
[nexus3d] / test.c
1 #include <stdio.h>
2 #include "nexus3d.h"
3
4 static int init(void);
5 static void cleanup(void);
6
7 static void display(void *cls);
8 static void reshape(int x, int y, void *cls);
9 static void keyb(int key, int pressed, void *cls);
10 static void mbutton(int bn, int pressed, int x, int y, void *cls);
11 static void mmove(int x, int y, void *cls);
12
13 #define ATTR_POS        0
14 #define ATTR_COL        1
15
16 static const float vdata[] = {
17         -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1,
18         -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1
19 };
20 static const float vcolors[] = {
21         1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0,
22         0, 1, 1, 1, 0, 1, 1, 0.5, 0, 0.5, 0.5, 0.5
23 };
24
25 static const unsigned int idata[] = {
26         0, 1, 5,        0, 5, 4,
27         1, 2, 6,        1, 6, 5,
28         2, 3, 7,        2, 7, 6,
29         3, 0, 4,        3, 4, 7,
30         4, 5, 6,        4, 6, 7,
31         1, 0, 3,        1, 3, 2
32 };
33
34
35 static int quit;
36 static nex_buffer *vbuf, *ibuf, *cbuf;
37 static nex_geometry *geom;
38 static nex_sdrprog *sdrprog;
39
40 static float cam_theta, cam_phi = 0.5, cam_dist = 8;
41 static float view_matrix[16], proj_matrix[16];
42
43 int main(void)
44 {
45         nex_gfxapi_opengl(3, 3, NEX_OPENGL_DEBUG);
46         if(nex_initgfx(1280, 800, 0) == -1) {
47                 return 1;
48         }
49
50         nex_cbdisplay(display, 0);
51         nex_cbreshape(reshape, 0);
52         nex_cbkey(keyb, 0);
53         nex_cbmousebn(mbutton, 0);
54         nex_cbmousemove(mmove, 0);
55
56         if(init() == -1) {
57                 goto end;
58         }
59
60         while(nex_evloop_wait() && !quit);
61
62 end:
63         cleanup();
64         nex_closegfx();
65         return 0;
66 }
67
68 static int init(void)
69 {
70         nex_clearcolor(0.1, 0.12, 0.2);
71
72         vbuf = nex_alloc_buffer(sizeof vdata, vdata);
73         cbuf = nex_alloc_buffer(sizeof vcolors, vcolors);
74         ibuf = nex_alloc_buffer(sizeof idata, idata);
75         geom = nex_alloc_geometry();
76         nex_geom_vbuffer(geom, 0, vbuf, 3 * sizeof(float));
77         nex_geom_vbuffer(geom, 1, cbuf, 3 * sizeof(float));
78         nex_geom_vattr(geom, ATTR_POS, NEX_VEC3, 0, 0);
79         nex_geom_vattr(geom, ATTR_COL, NEX_COL3, 1, 0);
80         nex_geom_ibuffer(geom, ibuf);
81
82         if(!(sdrprog = nex_load_sdrprog("test.v.spv", "test.p.spv"))) {
83                 return -1;
84         }
85
86         nex_enable(NEX_DEPTH_TEST);
87         nex_enable(NEX_CULL_FACE);
88         return 0;
89 }
90
91 static void cleanup(void)
92 {
93         nex_free_buffer(vbuf);
94         nex_free_buffer(cbuf);
95         nex_free_buffer(ibuf);
96         nex_free_geometry(geom);
97         nex_free_sdrprog(sdrprog);
98 }
99
100 static void display(void *cls)
101 {
102         float mvp_matrix[16];
103
104         nex_clear();
105
106         cgm_midentity(view_matrix);
107         cgm_mpretranslate(view_matrix, 0, 0, -cam_dist);
108         cgm_mprerotate(view_matrix, cam_phi, 1, 0, 0);
109         cgm_mprerotate(view_matrix, cam_theta, 0, 1, 0);
110
111         cgm_mcopy(mvp_matrix, view_matrix);
112         cgm_mmul(mvp_matrix, proj_matrix);
113         nex_uniform_mat4(sdrprog, 0, mvp_matrix);
114
115         nex_bind_sdrprog(sdrprog);
116         nex_draw_geometry(geom, NEX_TRIANGLES, 0);
117
118         nex_swap_buffers();
119 }
120
121 static void reshape(int x, int y, void *cls)
122 {
123         nex_viewport(0, 0, x, y);
124
125         cgm_mperspective(proj_matrix, cgm_deg_to_rad(50), (float)x / (float)y, 0.5, 500.0);
126 }
127
128 static void keyb(int key, int pressed, void *cls)
129 {
130         if(!pressed) return;
131
132         switch(key) {
133         case 27:
134                 quit = 1;
135                 break;
136         }
137 }
138
139 static int prev_x, prev_y;
140 static int bnstate[8];
141
142 static void mbutton(int bn, int pressed, int x, int y, void *cls)
143 {
144         if(bn < 8) bnstate[bn] = pressed;
145         prev_x = x;
146         prev_y = y;
147
148         if(pressed) {
149                 if(bn == 3) {
150                         cam_dist -= 0.5f;
151                         nex_redisplay();
152                 } else if(bn == 4) {
153                         cam_dist += 0.5f;
154                         nex_redisplay();
155                 }
156         }
157 }
158
159 static void mmove(int x, int y, void *cls)
160 {
161         int dx = x - prev_x;
162         int dy = y - prev_y;
163         prev_x = x;
164         prev_y = y;
165
166         if((dx | dy) == 0) return;
167
168         if(bnstate[0]) {
169                 cam_theta += cgm_deg_to_rad(dx * 0.5f);
170                 cam_phi += cgm_deg_to_rad(dy * 0.5f);
171
172                 if(cam_phi < -CGM_HPI) cam_phi = -CGM_HPI;
173                 if(cam_phi > CGM_HPI) cam_phi = CGM_HPI;
174
175                 nex_redisplay();
176         }
177         if(bnstate[2]) {
178                 cam_dist += dy * 0.1f;
179
180                 if(cam_dist < 0) cam_dist = 0;
181
182                 nex_redisplay();
183         }
184 }