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