Posted By

ozkriff on 07/20/09


Tagged


Versions (?)

sdl_opengl


 / Published in: C
 

:'-(

  1. #include "SDL/SDL.h"
  2. #include "SDL/SDL_opengl.h"
  3. /* #include "SDL/SDL_image.h" */
  4. #include <math.h>
  5. #include <stdio.h>
  6.  
  7. #define SCREEN_WIDTH 640
  8. #define SCREEN_HEIGHT 480
  9. #define SCREEN_BPP 16
  10.  
  11. #define V_COUNT 5000
  12. #define VT_COUNT 5000
  13. #define F_COUNT 5000
  14.  
  15. int v_count = 0;
  16. int vt_count = 0;
  17. int f_count = 0;
  18.  
  19. typedef struct
  20. {
  21. struct { float x, y, z; } vertexes[V_COUNT];
  22. struct { float u, v; } text_coords[VT_COUNT];
  23. struct { int v1, v2, v3, vt1, vt2 , vt3; } faces[F_COUNT];
  24. } model;
  25. model mdl;
  26.  
  27. SDL_Surface *surface;
  28. int video_flags; /* Flags to pass to SDL_SetVideoMode */
  29.  
  30. int done = 0; /* Main loop variable. */
  31.  
  32. GLfloat x_rot;
  33. GLfloat y_rot;
  34. GLfloat z_rot;
  35.  
  36. GLuint texture[1]; /* Storage for one texture. */
  37.  
  38. void
  39. quit (int return_code)
  40. {
  41. SDL_Quit(); /* clean up the window */
  42. exit(return_code); /* and exit appropriately */
  43. }
  44.  
  45.  
  46. int load_gl_textures () /* load in bitmap as a GL texture */
  47. {
  48. int Status = 0; /* Status indicator */
  49.  
  50. SDL_Surface *TextureImage[1];
  51.  
  52. /* Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit */
  53. TextureImage[0] = SDL_LoadBMP("soldat.bmp");
  54. if (TextureImage[0])
  55. {
  56. Status = 1;
  57. glGenTextures ( 1, &texture[0] ); /* Create The Texture */
  58. /* Typical Texture Generation Using Data From The Bitmap */
  59. glBindTexture ( GL_TEXTURE_2D, texture[0] );
  60. /* Generate The Texture */
  61. glTexImage2D ( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w,
  62. TextureImage[0]->h, 0, GL_BGR,
  63. GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
  64. /* Linear Filtering */
  65. glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  66. GL_LINEAR );
  67. glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  68. GL_LINEAR );
  69. }
  70.  
  71. if ( TextureImage[0] )
  72. SDL_FreeSurface ( TextureImage[0] );
  73.  
  74. return Status;
  75. }
  76.  
  77.  
  78. /* reset viewport after a window resize */
  79. int resize_window ( int width, int height )
  80. {
  81. GLfloat ratio;
  82. if ( height == 0 )
  83. height = 1;
  84. ratio = (GLfloat) width / (GLfloat) height;
  85.  
  86. glViewport ( 0, 0, (GLint) width, (GLint) height );
  87.  
  88. glMatrixMode ( GL_PROJECTION ); /* Change to the projection matrix */
  89. glLoadIdentity ();
  90. gluPerspective ( 45.0f, ratio, 0.1f, 100.0f ); /* set viewing volume. */
  91.  
  92. /* Make sure we're chaning the model view and not the projection */
  93. glMatrixMode ( GL_MODELVIEW ); /* just to make sure */
  94. glLoadIdentity ();
  95.  
  96. return 1;
  97. }
  98.  
  99.  
  100. void hanlde_events ( SDL_Event event )
  101. {
  102. switch ( event.type ) {
  103. case SDL_VIDEORESIZE:
  104. surface = SDL_SetVideoMode ( event.resize.w,
  105. event.resize.h,
  106. 16, video_flags );
  107. if ( !surface ) {
  108. fprintf ( stderr, "no surface after resize: %s\n",
  109. SDL_GetError() );
  110. quit (1);
  111. }
  112. resize_window ( event.resize.w, event.resize.h );
  113. break;
  114. case SDL_KEYDOWN:
  115. switch ( event.key.keysym.sym ) {
  116. case SDLK_q:
  117. case SDLK_ESCAPE:
  118. done = 1;
  119. quit (0);
  120. break;
  121. case SDLK_F1:
  122. SDL_WM_ToggleFullScreen ( surface );
  123. break;
  124. default:
  125. break;
  126. }
  127. break;
  128. case SDL_QUIT:
  129. done = 1;
  130. break;
  131. default:
  132. puts ("unknown event!");
  133. break;
  134. }
  135. }
  136.  
  137.  
  138. int init_opengl ( GLvoid )
  139. {
  140. if (!load_gl_textures())
  141. return 0;
  142.  
  143. glEnable ( GL_TEXTURE_2D );
  144. glShadeModel ( GL_SMOOTH );
  145. glClearColor ( 0.0f, 0.0f, 0.0f, 0.5f );
  146. glClearDepth ( 1.0f );
  147. glEnable ( GL_DEPTH_TEST );
  148. glDepthFunc ( GL_LEQUAL ); /* The Type Of Depth Test To Do */
  149. /* Really Nice Perspective Calculations */
  150. glHint ( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  151.  
  152. return 1;
  153. }
  154.  
  155.  
  156. /* --- */
  157. int read_obj_file ()
  158. {
  159. float resize_coefficient;
  160. // char filename[] = "cube.obj";
  161. char filename[] = "soldat.obj";
  162. // char filename[] = "elephav.obj";
  163. char buffer[100];
  164. FILE* obj_file = NULL;
  165. obj_file = fopen ( filename, "r" );
  166.  
  167. if ( obj_file == NULL )
  168. return 1;
  169.  
  170. while ( fgets (buffer, 100, obj_file) ) {
  171. /* puts(buffer); */
  172.  
  173. /* vertex coords */
  174. if ( buffer[0] == 'v' && buffer [1] == ' ' ) {
  175. sscanf ( buffer, "v %f %f %f",
  176. &mdl.vertexes[v_count].x,
  177. &mdl.vertexes[v_count].y,
  178. &mdl.vertexes[v_count].z );
  179.  
  180. #if 1
  181. //resize_coefficient = 0.002;
  182. resize_coefficient = 0.6;
  183. mdl.vertexes[v_count].x *= resize_coefficient;
  184. mdl.vertexes[v_count].y *= resize_coefficient;
  185. mdl.vertexes[v_count].z *= resize_coefficient;
  186. #endif
  187. v_count++;
  188. }
  189.  
  190. /* vertex normals */
  191. else if ( buffer[0] == 'v' && buffer[1] == 'n' ) {
  192. /* TODO */
  193. }
  194.  
  195.  
  196. /* texture coords */
  197. else if ( buffer[0] == 'v' && buffer[1] == 't' ) {
  198. sscanf ( buffer, "vt %f %f",
  199. &mdl.text_coords[vt_count].v,
  200. &mdl.text_coords[vt_count].u );
  201. vt_count++;
  202. }
  203.  
  204. /* faces */
  205. else if ( buffer[0] == 'f' && buffer [1] == ' ' ) {
  206. // sscanf ( buffer, "f %i %i %i",
  207. sscanf ( buffer, "f %i/%i %i/%i %i/%i",
  208. // sscanf ( buffer, "f %i//%i %i//%i %i//%i",
  209. &mdl.faces[f_count].v1,
  210. &mdl.faces[f_count].vt1,
  211. &mdl.faces[f_count].v2,
  212. &mdl.faces[f_count].vt2,
  213. &mdl.faces[f_count].v3,
  214. &mdl.faces[f_count].vt3 );
  215. f_count++;
  216. }
  217. }
  218.  
  219. #if 1
  220. printf ( "vertex_count: %i\n", v_count );
  221. printf ( "text_coords_count: %i\n", vt_count );
  222. printf ( "f_count: %i\n", f_count );
  223. #endif
  224.  
  225. fclose ( obj_file );
  226. return 0;
  227. }
  228.  
  229.  
  230. int draw ( GLvoid )
  231. {
  232. int ii = 0;
  233. /* These are to calculate our fps */
  234. static GLint T0 = 0;
  235. static GLint Frames = 0;
  236.  
  237. glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  238. glLoadIdentity ();
  239. glTranslatef ( 0.0f, 0.0f, -5.0f ); /* Move Into The Screen 5 Units */
  240. glRotatef ( x_rot, 1.0f, 0.0f, 0.0f );
  241. glRotatef ( y_rot, 0.0f, 1.0f, 0.0f );
  242. glRotatef ( z_rot, 0.0f, 0.0f, 1.0f );
  243.  
  244. glBindTexture ( GL_TEXTURE_2D, texture[0] ); /* Select Texture */
  245.  
  246. /* NOTE:
  247. * The x coordinates of the glTexCoord2f function need to inverted
  248. * for SDL because of the way SDL_LoadBmp loads the data. So where
  249. * it has glTexCoord2f( 1.0f, 0.0f ); it should now read
  250. * glTexCoord2f( 0.0f, 0.0f );
  251. */
  252.  
  253. glBegin ( GL_TRIANGLES );
  254. {
  255. for ( ii = 0; ii < f_count; ii++ ) {
  256. /* TODO: remake whole structure */
  257. glTexCoord2f ( mdl.text_coords[ mdl.faces[ii].vt1 ].u,
  258. mdl.text_coords[ mdl.faces[ii].vt1 ].v );
  259. glVertex3f ( mdl.vertexes[ mdl.faces[ii].v1 ].x,
  260. mdl.vertexes[ mdl.faces[ii].v1 ].y,
  261. mdl.vertexes[ mdl.faces[ii].v1 ].z );
  262.  
  263. glTexCoord2f ( mdl.text_coords[ mdl.faces[ii].vt2 ].u,
  264. mdl.text_coords[ mdl.faces[ii].vt2 ].v );
  265. glVertex3f ( mdl.vertexes[ mdl.faces[ii].v2 ].x,
  266. mdl.vertexes[ mdl.faces[ii].v2 ].y,
  267. mdl.vertexes[ mdl.faces[ii].v2 ].z );
  268.  
  269. glTexCoord2f ( mdl.text_coords[ mdl.faces[ii].vt3 ].u,
  270. mdl.text_coords[ mdl.faces[ii].vt3 ].v );
  271. glVertex3f ( mdl.vertexes[ mdl.faces[ii].v3 ].x,
  272. mdl.vertexes[ mdl.faces[ii].v3 ].y,
  273. mdl.vertexes[ mdl.faces[ii].v3 ].z );
  274. }
  275. }
  276. glEnd ();
  277.  
  278. SDL_GL_SwapBuffers (); /* Draw it to the screen */
  279.  
  280. /* Gather FPS */
  281. Frames++;
  282. {
  283. GLint t = SDL_GetTicks ();
  284.  
  285. if ( t - T0 >= 5000 ) {
  286. GLfloat seconds = ( t - T0 ) / 1000.0;
  287. GLfloat fps = Frames / seconds;
  288. printf ( "%d frames in %g seconds = %g FPS\n",
  289. Frames, seconds, fps );
  290. T0 = t;
  291. Frames = 0;
  292. }
  293. }
  294.  
  295. x_rot += 0.03f;
  296. y_rot += 0.03f;
  297. z_rot += 0.03f;
  298.  
  299. return 1;
  300. }
  301.  
  302.  
  303. int init_sdl ()
  304. {
  305. const SDL_VideoInfo *videoInfo; /* holds info about display */
  306.  
  307. if ( SDL_Init ( SDL_INIT_VIDEO ) < 0 ) {
  308. fprintf ( stderr, "Video initialization failed: %s\n",
  309. SDL_GetError () );
  310. quit (1);
  311. }
  312.  
  313. videoInfo = SDL_GetVideoInfo (); /* Fetch the video info */
  314.  
  315. if ( !videoInfo ) {
  316. fprintf ( stderr, "Video query failed: %s\n",
  317. SDL_GetError() );
  318. quit (1);
  319. }
  320.  
  321. /* the flags to pass to SDL_SetVideoMode */
  322. video_flags = SDL_OPENGL;
  323. video_flags |= SDL_GL_DOUBLEBUFFER;
  324. video_flags |= SDL_HWPALETTE; /* Store the palette in hardware */
  325. // video_flags |= SDL_RESIZABLE; /* Enable window resizing */
  326.  
  327. if ( videoInfo->hw_available )
  328. video_flags |= SDL_HWSURFACE;
  329. else
  330. video_flags |= SDL_SWSURFACE;
  331.  
  332. if ( videoInfo->blit_hw ) /* checks if hardware blits can be done */
  333. video_flags |= SDL_HWACCEL;
  334.  
  335. /* OpenGL double buffering */
  336. SDL_GL_SetAttribute ( SDL_GL_DOUBLEBUFFER, 1 );
  337.  
  338. /* get a SDL surface */
  339. surface = SDL_SetVideoMode ( SCREEN_WIDTH, SCREEN_HEIGHT,
  340. SCREEN_BPP, video_flags );
  341.  
  342. if ( !surface ) { /* Verify there is a surface */
  343. fprintf ( stderr, "Video mode set failed: %s\n",
  344. SDL_GetError() );
  345. quit (1);
  346. }
  347.  
  348. resize_window ( SCREEN_WIDTH, SCREEN_HEIGHT );
  349.  
  350. return 1;
  351. }
  352.  
  353.  
  354. int main ( int argc, char **argv )
  355. {
  356. SDL_Event event; /* used to collect events */
  357.  
  358. init_sdl ();
  359. init_opengl ();
  360. read_obj_file ();
  361.  
  362. while ( !done ) {
  363. while ( SDL_PollEvent ( &event ) )
  364. hanlde_events ( event );
  365. draw ();
  366. }
  367.  
  368. quit (0); /* clean ourselves up and exit */
  369.  
  370. return 0;
  371. }

Report this snippet  

You need to login to post a comment.