1848b8605Smrg/* Display a cleared blue window.  This demo has no dependencies on
2848b8605Smrg * any utility code, just the graw interface and gallium.
3848b8605Smrg */
4848b8605Smrg
5848b8605Smrg#include "state_tracker/graw.h"
6848b8605Smrg#include "pipe/p_screen.h"
7848b8605Smrg#include "pipe/p_context.h"
8848b8605Smrg#include "pipe/p_shader_tokens.h"
9848b8605Smrg#include "pipe/p_state.h"
10848b8605Smrg#include "pipe/p_defines.h"
11848b8605Smrg
12848b8605Smrg#include <stdio.h>              /* for fread(), etc */
13848b8605Smrg
14848b8605Smrg#include "util/u_inlines.h"
15848b8605Smrg#include "util/u_memory.h"      /* Offset() */
16848b8605Smrg#include "util/u_draw_quad.h"
17848b8605Smrg#include "util/u_box.h"
18848b8605Smrg
19848b8605Smrgstatic const char *filename = NULL;
20848b8605Smrgunsigned show_fps = 0;
21848b8605Smrg
22848b8605Smrg
23848b8605Smrgstatic void usage(char *name)
24848b8605Smrg{
25848b8605Smrg   fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
26848b8605Smrg#ifndef _WIN32
27848b8605Smrg   fprintf(stderr, "\n" );
28848b8605Smrg   fprintf(stderr, "options:\n");
29848b8605Smrg   fprintf(stderr, "    -fps  show frames per second\n");
30848b8605Smrg#endif
31848b8605Smrg}
32848b8605Smrg
33848b8605Smrg
34848b8605Smrgenum pipe_format formats[] = {
35848b8605Smrg   PIPE_FORMAT_RGBA8888_UNORM,
36848b8605Smrg   PIPE_FORMAT_BGRA8888_UNORM,
37848b8605Smrg   PIPE_FORMAT_NONE
38848b8605Smrg};
39848b8605Smrg
40848b8605Smrgstatic const int WIDTH = 250;
41848b8605Smrgstatic const int HEIGHT = 250;
42848b8605Smrg
43848b8605Smrgstatic struct pipe_screen *screen = NULL;
44848b8605Smrgstatic struct pipe_context *ctx = NULL;
45848b8605Smrgstatic struct pipe_resource *rttex = NULL;
46848b8605Smrgstatic struct pipe_resource *constbuf = NULL;
47848b8605Smrgstatic struct pipe_surface *surf = NULL;
48848b8605Smrgstatic struct pipe_sampler_view *sv = NULL;
49848b8605Smrgstatic void *sampler = NULL;
50848b8605Smrgstatic void *window = NULL;
51848b8605Smrgstatic struct pipe_resource *samptex = NULL;
52848b8605Smrg
53848b8605Smrgstruct vertex {
54848b8605Smrg   float position[4];
55848b8605Smrg   float color[3];
56848b8605Smrg};
57848b8605Smrg
58848b8605Smrg/* Draw a regular mesh
59848b8605Smrg */
60848b8605Smrg#define MESH_SZ 16
61848b8605Smrgstatic struct vertex vertices[MESH_SZ * MESH_SZ];
62848b8605Smrg
63848b8605Smrgstatic float constants[] =
64848b8605Smrg{  0.4, 0, 0,  1,
65848b8605Smrg   1,   1, 1,  1,
66848b8605Smrg   2,   2, 2,  2,
67848b8605Smrg   4,   8, 16, 32,
68848b8605Smrg
69848b8605Smrg   3,  0, 0, 0,
70848b8605Smrg   0, .5, 0, 0,
71848b8605Smrg   0,  0, 1, 0,
72848b8605Smrg   0,  0, 0, 1,
73848b8605Smrg
74848b8605Smrg   1, 0, 0, 0.5,
75848b8605Smrg   0, 1, 0, 0.5,
76848b8605Smrg   0, 0, 1, 0,
77848b8605Smrg   0, 0, 0, 1,
78848b8605Smrg};
79848b8605Smrg
80848b8605Smrgstatic void init_fs_constbuf( void )
81848b8605Smrg{
82848b8605Smrg   struct pipe_resource templat;
83848b8605Smrg   struct pipe_box box;
84848b8605Smrg
85b8e80941Smrg   memset(&templat, 0, sizeof(templat));
86848b8605Smrg   templat.target = PIPE_BUFFER;
87848b8605Smrg   templat.format = PIPE_FORMAT_R8_UNORM;
88848b8605Smrg   templat.width0 = sizeof(constants);
89848b8605Smrg   templat.height0 = 1;
90848b8605Smrg   templat.depth0 = 1;
91848b8605Smrg   templat.array_size = 1;
92848b8605Smrg   templat.last_level = 0;
93848b8605Smrg   templat.bind = PIPE_BIND_CONSTANT_BUFFER;
94848b8605Smrg
95848b8605Smrg   constbuf = screen->resource_create(screen,
96848b8605Smrg                                      &templat);
97848b8605Smrg   if (constbuf == NULL)
98848b8605Smrg      exit(4);
99848b8605Smrg
100848b8605Smrg
101848b8605Smrg   u_box_2d(0,0,sizeof(constants),1, &box);
102848b8605Smrg
103b8e80941Smrg   ctx->buffer_subdata(ctx, constbuf,
104b8e80941Smrg                       PIPE_TRANSFER_WRITE,
105b8e80941Smrg                       0, sizeof(constants), constants);
106848b8605Smrg
107848b8605Smrg   pipe_set_constant_buffer(ctx,
108848b8605Smrg                            PIPE_SHADER_VERTEX, 0,
109848b8605Smrg                            constbuf);
110848b8605Smrg}
111848b8605Smrg
112848b8605Smrg
113848b8605Smrgstatic void set_viewport( float x, float y,
114848b8605Smrg                          float width, float height,
115b8e80941Smrg                          float zNear, float zFar)
116848b8605Smrg{
117b8e80941Smrg   float z = zFar;
118848b8605Smrg   float half_width = (float)width / 2.0f;
119848b8605Smrg   float half_height = (float)height / 2.0f;
120b8e80941Smrg   float half_depth = ((float)zFar - (float)zNear) / 2.0f;
121848b8605Smrg   struct pipe_viewport_state vp;
122848b8605Smrg
123848b8605Smrg   vp.scale[0] = half_width;
124848b8605Smrg   vp.scale[1] = half_height;
125848b8605Smrg   vp.scale[2] = half_depth;
126848b8605Smrg
127848b8605Smrg   vp.translate[0] = half_width + x;
128848b8605Smrg   vp.translate[1] = half_height + y;
129848b8605Smrg   vp.translate[2] = half_depth + z;
130848b8605Smrg
131848b8605Smrg   ctx->set_viewport_states( ctx, 0, 1, &vp );
132848b8605Smrg}
133848b8605Smrg
134848b8605Smrgstatic void set_vertices( void )
135848b8605Smrg{
136848b8605Smrg   struct pipe_vertex_element ve[2];
137848b8605Smrg   struct pipe_vertex_buffer vbuf;
138848b8605Smrg   void *handle;
139848b8605Smrg   int x,y;
140848b8605Smrg
141848b8605Smrg   memset(ve, 0, sizeof ve);
142848b8605Smrg
143848b8605Smrg   ve[0].src_offset = Offset(struct vertex, position);
144848b8605Smrg   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
145848b8605Smrg   ve[1].src_offset = Offset(struct vertex, color);
146848b8605Smrg   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
147848b8605Smrg
148848b8605Smrg   handle = ctx->create_vertex_elements_state(ctx, 2, ve);
149848b8605Smrg   ctx->bind_vertex_elements_state(ctx, handle);
150848b8605Smrg
151848b8605Smrg   for (x = 0; x < MESH_SZ; x++) {
152848b8605Smrg      for (y = 0; y < MESH_SZ; y++) {
153848b8605Smrg         int i = y * MESH_SZ + x;
154848b8605Smrg         vertices[i].position[0] = ((float)x)/MESH_SZ * 2.0 - 1.0;
155848b8605Smrg         vertices[i].position[1] = ((float)y)/MESH_SZ * 2.0 - 1.0;
156848b8605Smrg         vertices[i].position[2] = 0;
157848b8605Smrg         vertices[i].position[3] = 1.0;
158848b8605Smrg
159848b8605Smrg         vertices[i].color[0] = .5;
160848b8605Smrg         vertices[i].color[1] = (float)x / (float)MESH_SZ;
161848b8605Smrg         vertices[i].color[2] = (float)y / (float)MESH_SZ;
162848b8605Smrg      }
163848b8605Smrg   }
164848b8605Smrg
165848b8605Smrg   memset(&vbuf, 0, sizeof vbuf);
166848b8605Smrg
167848b8605Smrg   vbuf.stride = sizeof( struct vertex );
168848b8605Smrg   vbuf.buffer_offset = 0;
169b8e80941Smrg   vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
170848b8605Smrg                                              PIPE_BIND_VERTEX_BUFFER,
171848b8605Smrg                                              PIPE_USAGE_DEFAULT,
172848b8605Smrg                                              sizeof(vertices),
173848b8605Smrg                                              vertices);
174848b8605Smrg
175848b8605Smrg   ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
176848b8605Smrg}
177848b8605Smrg
178848b8605Smrgstatic void set_vertex_shader( void )
179848b8605Smrg{
180848b8605Smrg   FILE *f;
181848b8605Smrg   char buf[50000];
182848b8605Smrg   void *handle;
183848b8605Smrg   int sz;
184848b8605Smrg
185848b8605Smrg   if ((f = fopen(filename, "r")) == NULL) {
186848b8605Smrg      fprintf(stderr, "Couldn't open %s\n", filename);
187848b8605Smrg      exit(1);
188848b8605Smrg   }
189848b8605Smrg
190848b8605Smrg   sz = fread(buf, 1, sizeof(buf), f);
191848b8605Smrg   if (!feof(f)) {
192848b8605Smrg      printf("file too long\n");
193848b8605Smrg      exit(1);
194848b8605Smrg   }
195848b8605Smrg   printf("%.*s\n", sz, buf);
196848b8605Smrg   buf[sz] = 0;
197848b8605Smrg
198848b8605Smrg   handle = graw_parse_vertex_shader(ctx, buf);
199848b8605Smrg   ctx->bind_vs_state(ctx, handle);
200848b8605Smrg   fclose(f);
201848b8605Smrg}
202848b8605Smrg
203848b8605Smrgstatic void set_fragment_shader( void )
204848b8605Smrg{
205848b8605Smrg   void *handle;
206848b8605Smrg   const char *text =
207848b8605Smrg      "FRAG\n"
208848b8605Smrg      "DCL IN[0], COLOR, LINEAR\n"
209848b8605Smrg      "DCL OUT[0], COLOR\n"
210848b8605Smrg      "  0: MOV OUT[0], IN[0]\n"
211848b8605Smrg      "  1: END\n";
212848b8605Smrg
213848b8605Smrg   handle = graw_parse_fragment_shader(ctx, text);
214848b8605Smrg   ctx->bind_fs_state(ctx, handle);
215848b8605Smrg}
216848b8605Smrg
217848b8605Smrg
218848b8605Smrg
219848b8605Smrgstatic void draw( void )
220848b8605Smrg{
221848b8605Smrg   union pipe_color_union clear_color = { {.1,.3,.5,0} };
222848b8605Smrg
223848b8605Smrg   ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
224b8e80941Smrg   util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, ARRAY_SIZE(vertices));
225848b8605Smrg   ctx->flush(ctx, NULL, 0);
226848b8605Smrg
227848b8605Smrg   graw_save_surface_to_file(ctx, surf, NULL);
228848b8605Smrg
229848b8605Smrg   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
230848b8605Smrg}
231848b8605Smrg
232848b8605Smrg#define SIZE 16
233848b8605Smrg
234848b8605Smrgstatic void init_tex( void )
235848b8605Smrg{
236848b8605Smrg   struct pipe_sampler_view sv_template;
237848b8605Smrg   struct pipe_sampler_state sampler_desc;
238848b8605Smrg   struct pipe_resource templat;
239848b8605Smrg   struct pipe_box box;
240848b8605Smrg   ubyte tex2d[SIZE][SIZE][4];
241848b8605Smrg   int s, t;
242848b8605Smrg
243848b8605Smrg#if (SIZE != 2)
244848b8605Smrg   for (s = 0; s < SIZE; s++) {
245848b8605Smrg      for (t = 0; t < SIZE; t++) {
246848b8605Smrg         if (0) {
247848b8605Smrg            int x = (s ^ t) & 1;
248848b8605Smrg	    tex2d[t][s][0] = (x) ? 0 : 63;
249848b8605Smrg	    tex2d[t][s][1] = (x) ? 0 : 128;
250848b8605Smrg	    tex2d[t][s][2] = 0;
251848b8605Smrg	    tex2d[t][s][3] = 0xff;
252848b8605Smrg         }
253848b8605Smrg         else {
254848b8605Smrg            int x = ((s ^ t) >> 2) & 1;
255848b8605Smrg	    tex2d[t][s][0] = s*255/(SIZE-1);
256848b8605Smrg	    tex2d[t][s][1] = t*255/(SIZE-1);
257848b8605Smrg	    tex2d[t][s][2] = (x) ? 0 : 128;
258848b8605Smrg	    tex2d[t][s][3] = 0xff;
259848b8605Smrg         }
260848b8605Smrg      }
261848b8605Smrg   }
262848b8605Smrg#else
263848b8605Smrg   tex2d[0][0][0] = 0;
264848b8605Smrg   tex2d[0][0][1] = 255;
265848b8605Smrg   tex2d[0][0][2] = 255;
266848b8605Smrg   tex2d[0][0][3] = 0;
267848b8605Smrg
268848b8605Smrg   tex2d[0][1][0] = 0;
269848b8605Smrg   tex2d[0][1][1] = 0;
270848b8605Smrg   tex2d[0][1][2] = 255;
271848b8605Smrg   tex2d[0][1][3] = 255;
272848b8605Smrg
273848b8605Smrg   tex2d[1][0][0] = 255;
274848b8605Smrg   tex2d[1][0][1] = 255;
275848b8605Smrg   tex2d[1][0][2] = 0;
276848b8605Smrg   tex2d[1][0][3] = 255;
277848b8605Smrg
278848b8605Smrg   tex2d[1][1][0] = 255;
279848b8605Smrg   tex2d[1][1][1] = 0;
280848b8605Smrg   tex2d[1][1][2] = 0;
281848b8605Smrg   tex2d[1][1][3] = 255;
282848b8605Smrg#endif
283848b8605Smrg
284b8e80941Smrg   memset(&templat, 0, sizeof(templat));
285848b8605Smrg   templat.target = PIPE_TEXTURE_2D;
286848b8605Smrg   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
287848b8605Smrg   templat.width0 = SIZE;
288848b8605Smrg   templat.height0 = SIZE;
289848b8605Smrg   templat.depth0 = 1;
290848b8605Smrg   templat.array_size = 1;
291848b8605Smrg   templat.last_level = 0;
292848b8605Smrg   templat.bind = PIPE_BIND_SAMPLER_VIEW;
293848b8605Smrg
294848b8605Smrg
295848b8605Smrg   samptex = screen->resource_create(screen,
296848b8605Smrg                                 &templat);
297848b8605Smrg   if (samptex == NULL)
298848b8605Smrg      exit(4);
299848b8605Smrg
300848b8605Smrg   u_box_2d(0,0,SIZE,SIZE, &box);
301848b8605Smrg
302b8e80941Smrg   ctx->texture_subdata(ctx,
303b8e80941Smrg                        samptex,
304b8e80941Smrg                        0,
305b8e80941Smrg                        PIPE_TRANSFER_WRITE,
306b8e80941Smrg                        &box,
307b8e80941Smrg                        tex2d,
308b8e80941Smrg                        sizeof tex2d[0],
309b8e80941Smrg                        sizeof tex2d);
310848b8605Smrg
311848b8605Smrg   /* Possibly read back & compare against original data:
312848b8605Smrg    */
313848b8605Smrg   if (0)
314848b8605Smrg   {
315848b8605Smrg      struct pipe_transfer *t;
316848b8605Smrg      uint32_t *ptr;
317848b8605Smrg      ptr = pipe_transfer_map(ctx, samptex,
318848b8605Smrg                              0, 0, /* level, layer */
319848b8605Smrg                              PIPE_TRANSFER_READ,
320848b8605Smrg                              0, 0, SIZE, SIZE, &t); /* x, y, width, height */
321848b8605Smrg
322848b8605Smrg      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
323848b8605Smrg         assert(0);
324848b8605Smrg         exit(9);
325848b8605Smrg      }
326848b8605Smrg
327848b8605Smrg      ctx->transfer_unmap(ctx, t);
328848b8605Smrg   }
329848b8605Smrg
330848b8605Smrg   memset(&sv_template, 0, sizeof sv_template);
331848b8605Smrg   sv_template.format = samptex->format;
332848b8605Smrg   sv_template.texture = samptex;
333848b8605Smrg   sv_template.swizzle_r = 0;
334848b8605Smrg   sv_template.swizzle_g = 1;
335848b8605Smrg   sv_template.swizzle_b = 2;
336848b8605Smrg   sv_template.swizzle_a = 3;
337848b8605Smrg   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
338848b8605Smrg   if (sv == NULL)
339848b8605Smrg      exit(5);
340848b8605Smrg
341848b8605Smrg   ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sv);
342848b8605Smrg
343848b8605Smrg
344848b8605Smrg   memset(&sampler_desc, 0, sizeof sampler_desc);
345848b8605Smrg   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
346848b8605Smrg   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
347848b8605Smrg   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
348848b8605Smrg   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
349848b8605Smrg   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
350848b8605Smrg   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
351848b8605Smrg   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
352848b8605Smrg   sampler_desc.compare_func = 0;
353848b8605Smrg   sampler_desc.normalized_coords = 1;
354848b8605Smrg   sampler_desc.max_anisotropy = 0;
355848b8605Smrg
356848b8605Smrg   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
357848b8605Smrg   if (sampler == NULL)
358848b8605Smrg      exit(6);
359848b8605Smrg
360848b8605Smrg   ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
361848b8605Smrg
362848b8605Smrg}
363848b8605Smrg
364848b8605Smrgstatic void init( void )
365848b8605Smrg{
366848b8605Smrg   struct pipe_framebuffer_state fb;
367848b8605Smrg   struct pipe_resource templat;
368848b8605Smrg   struct pipe_surface surf_tmpl;
369848b8605Smrg   int i;
370848b8605Smrg
371848b8605Smrg   /* It's hard to say whether window or screen should be created
372848b8605Smrg    * first.  Different environments would prefer one or the other.
373848b8605Smrg    *
374848b8605Smrg    * Also, no easy way of querying supported formats if the screen
375848b8605Smrg    * cannot be created first.
376848b8605Smrg    */
377848b8605Smrg   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
378848b8605Smrg      screen = graw_create_window_and_screen(0, 0, 300, 300,
379848b8605Smrg                                             formats[i],
380848b8605Smrg                                             &window);
381848b8605Smrg      if (window && screen)
382848b8605Smrg         break;
383848b8605Smrg   }
384848b8605Smrg   if (!screen || !window) {
385848b8605Smrg      fprintf(stderr, "Unable to create window\n");
386848b8605Smrg      exit(1);
387848b8605Smrg   }
388848b8605Smrg
389b8e80941Smrg   ctx = screen->context_create(screen, NULL, 0);
390848b8605Smrg   if (ctx == NULL)
391848b8605Smrg      exit(3);
392848b8605Smrg
393b8e80941Smrg   memset(&templat, 0, sizeof(templat));
394848b8605Smrg   templat.target = PIPE_TEXTURE_2D;
395848b8605Smrg   templat.format = formats[i];
396848b8605Smrg   templat.width0 = WIDTH;
397848b8605Smrg   templat.height0 = HEIGHT;
398848b8605Smrg   templat.depth0 = 1;
399848b8605Smrg   templat.array_size = 1;
400848b8605Smrg   templat.last_level = 0;
401848b8605Smrg   templat.bind = (PIPE_BIND_RENDER_TARGET |
402848b8605Smrg                   PIPE_BIND_DISPLAY_TARGET);
403848b8605Smrg
404848b8605Smrg   rttex = screen->resource_create(screen,
405848b8605Smrg                                 &templat);
406848b8605Smrg   if (rttex == NULL)
407848b8605Smrg      exit(4);
408848b8605Smrg
409848b8605Smrg   surf_tmpl.format = templat.format;
410848b8605Smrg   surf_tmpl.u.tex.level = 0;
411848b8605Smrg   surf_tmpl.u.tex.first_layer = 0;
412848b8605Smrg   surf_tmpl.u.tex.last_layer = 0;
413848b8605Smrg   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
414848b8605Smrg   if (surf == NULL)
415848b8605Smrg      exit(5);
416848b8605Smrg
417848b8605Smrg   memset(&fb, 0, sizeof fb);
418848b8605Smrg   fb.nr_cbufs = 1;
419848b8605Smrg   fb.width = WIDTH;
420848b8605Smrg   fb.height = HEIGHT;
421848b8605Smrg   fb.cbufs[0] = surf;
422848b8605Smrg
423848b8605Smrg   ctx->set_framebuffer_state(ctx, &fb);
424848b8605Smrg
425848b8605Smrg   {
426848b8605Smrg      struct pipe_blend_state blend;
427848b8605Smrg      void *handle;
428848b8605Smrg      memset(&blend, 0, sizeof blend);
429848b8605Smrg      blend.rt[0].colormask = PIPE_MASK_RGBA;
430848b8605Smrg      handle = ctx->create_blend_state(ctx, &blend);
431848b8605Smrg      ctx->bind_blend_state(ctx, handle);
432848b8605Smrg   }
433848b8605Smrg
434848b8605Smrg   {
435848b8605Smrg      struct pipe_depth_stencil_alpha_state depthstencil;
436848b8605Smrg      void *handle;
437848b8605Smrg      memset(&depthstencil, 0, sizeof depthstencil);
438848b8605Smrg      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
439848b8605Smrg      ctx->bind_depth_stencil_alpha_state(ctx, handle);
440848b8605Smrg   }
441848b8605Smrg
442848b8605Smrg   {
443848b8605Smrg      struct pipe_rasterizer_state rasterizer;
444848b8605Smrg      void *handle;
445848b8605Smrg      memset(&rasterizer, 0, sizeof rasterizer);
446848b8605Smrg      rasterizer.cull_face = PIPE_FACE_NONE;
447848b8605Smrg      rasterizer.point_size = 8.0;
448848b8605Smrg      rasterizer.half_pixel_center = 1;
449848b8605Smrg      rasterizer.bottom_edge_rule = 1;
450b8e80941Smrg      rasterizer.depth_clip_near = 1;
451b8e80941Smrg      rasterizer.depth_clip_far = 1;
452848b8605Smrg      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
453848b8605Smrg      ctx->bind_rasterizer_state(ctx, handle);
454848b8605Smrg   }
455848b8605Smrg
456848b8605Smrg   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
457848b8605Smrg
458848b8605Smrg   init_tex();
459848b8605Smrg   init_fs_constbuf();
460848b8605Smrg
461848b8605Smrg   set_vertices();
462848b8605Smrg   set_vertex_shader();
463848b8605Smrg   set_fragment_shader();
464848b8605Smrg}
465848b8605Smrg
466848b8605Smrgstatic void args(int argc, char *argv[])
467848b8605Smrg{
468848b8605Smrg   int i;
469848b8605Smrg
470848b8605Smrg   for (i = 1; i < argc;) {
471848b8605Smrg      if (graw_parse_args(&i, argc, argv)) {
472848b8605Smrg         continue;
473848b8605Smrg      }
474848b8605Smrg      if (strcmp(argv[i], "-fps") == 0) {
475848b8605Smrg         show_fps = 1;
476848b8605Smrg         i++;
477848b8605Smrg      }
478848b8605Smrg      else if (i == argc - 1) {
479848b8605Smrg         filename = argv[i];
480848b8605Smrg         i++;
481848b8605Smrg      }
482848b8605Smrg      else {
483848b8605Smrg         usage(argv[0]);
484848b8605Smrg         exit(1);
485848b8605Smrg      }
486848b8605Smrg   }
487848b8605Smrg
488848b8605Smrg   if (!filename) {
489848b8605Smrg      usage(argv[0]);
490848b8605Smrg      exit(1);
491848b8605Smrg   }
492848b8605Smrg}
493848b8605Smrg
494848b8605Smrgint main( int argc, char *argv[] )
495848b8605Smrg{
496848b8605Smrg   args(argc,argv);
497848b8605Smrg   init();
498848b8605Smrg
499848b8605Smrg   graw_set_display_func( draw );
500848b8605Smrg   graw_main_loop();
501848b8605Smrg   return 0;
502848b8605Smrg}
503