Advertisement
Guest User

Untitled

a guest
Nov 27th, 2015
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.37 KB | None | 0 0
  1. //compile with this command on my Ubuntu 12.04 machine:
  2. //gcc sdl2-opengl-sample.c -o sdl2-opengl-sample -Wall -std=c99 -I/usr/local/include/SDL2 -lSDL2 -I/usr/include/GL -lGL -lGLEW -Wall
  3.  
  4. #define GLEW_STATIC
  5. #include <GL/glew.h>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <cstdarg>
  9. #include <cstring>
  10. #include <cassert>
  11. #include <cmath>
  12.  
  13. #include <SDL.h>
  14. #include <SDL_image.h>
  15.  
  16. GLuint BuildShaderProgram(const char *vsPath, const char *fsPath);
  17. GLuint CreateShader(GLenum eShaderType, const char *strShaderFile);
  18.  
  19. enum VertexBuffer : int
  20. {
  21. VERT_POSITION = 0,
  22. VERT_COLOR = 1
  23. };
  24.  
  25. void Init();
  26. void Printf( const char *format... );
  27. void InitHint();
  28.  
  29. struct Vertex
  30. {
  31. float xyz[4];
  32. //float st[2];
  33. GLfloat c[4];
  34. };
  35. void GLCheckError()
  36. {
  37. GLenum err;
  38. char str[64];
  39.  
  40. for( int i = 0; i < 15; i++ )
  41. {
  42. if( ( err = glGetError() ) != GL_NO_ERROR )
  43. {
  44. switch( err )
  45. {
  46. case GL_INVALID_ENUM:
  47. strcpy( str, "GL_INVALID_ENUM" );
  48. break;
  49. case GL_INVALID_VALUE:
  50. strcpy( str, "GL_INVALID_VALUE" );
  51. break;
  52. case GL_INVALID_OPERATION:
  53. strcpy( str, "GL_INVALID_OPERATION" );
  54. break;
  55. case GL_STACK_OVERFLOW:
  56. strcpy( str, "GL_STACK_OVERFLOW" );
  57. break;
  58. case GL_STACK_UNDERFLOW:
  59. strcpy( str, "GL_STACK_UNDERFLOW" );
  60. break;
  61. case GL_OUT_OF_MEMORY:
  62. strcpy( str, "GL_OUT_OF_MEMORY" );
  63. break;
  64. case GL_INVALID_FRAMEBUFFER_OPERATION:
  65. strcpy( str, "GL_INVALID_FRAMEBUFFER_OPERATION" );
  66. break;
  67. default: break;
  68. }
  69. printf( "GL error %s %#x\n", str, err );
  70. }
  71. }
  72. }
  73.  
  74. #define MAX_VERTS 3
  75.  
  76. Vertex immediate[ MAX_VERTS ];
  77.  
  78. #undef main
  79. int main()
  80. {
  81. Init();
  82. if( SDL_Init(SDL_INIT_VIDEO) < 0 )
  83. {
  84. printf( "Error SDL init\n" );
  85. return 1;
  86. }
  87.  
  88. SDL_Window *window = SDL_CreateWindow("My Game Window",
  89. SDL_WINDOWPOS_UNDEFINED,
  90. SDL_WINDOWPOS_UNDEFINED,
  91. 800, 600,
  92. SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL );
  93.  
  94. if( !window )
  95. {
  96. printf( "Window error init\n");
  97. return 1;
  98. }
  99.  
  100. SDL_GLContext glContext = SDL_GL_CreateContext(window);
  101. if( !glContext )
  102. {
  103. printf("There was an error creating the OpenGL context!\n");
  104. return 1;
  105. }
  106.  
  107. InitHint();
  108.  
  109. const unsigned char *version = glGetString(GL_VERSION);
  110. if( !version )
  111. {
  112. printf("There was an error creating the OpenGL context!\n");
  113. return 1;
  114. }
  115.  
  116. SDL_GL_MakeCurrent( window, glContext );
  117.  
  118. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
  119. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
  120.  
  121. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
  122. SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
  123. SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
  124. SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
  125.  
  126. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  127. SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
  128.  
  129. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  130.  
  131. SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
  132. SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
  133. SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
  134. SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);
  135.  
  136. SDL_GL_SetSwapInterval( 1 );
  137.  
  138. if( !SDL_SetHint( SDL_HINT_RENDER_VSYNC, "1" ) )
  139. {
  140. printf( "Application:Init: Warning: Vsync not enabled!\n" );
  141. }
  142.  
  143. glewExperimental = GL_TRUE;
  144. GLenum glew_status = glewInit();
  145. if( glew_status != 0 )
  146. {
  147. printf( "Error: %s\n", glewGetErrorString(glew_status) );
  148. return 1;
  149. }
  150.  
  151. const float triangleVertices[] = {
  152. 0.0f, 0.5f, 0.0f, 1.0f,
  153. 0.5f, -0.366f, 0.0f, 1.0f,
  154. -0.5f, -0.366f, 0.0f, 1.0f,
  155. //next part contains vertex colors
  156. 1.0f, 0.0f, 0.0f, 1.0f,
  157. 0.0f, 1.0f, 0.0f, 1.0f,
  158. 0.0f, 0.0f, 1.0f, 1.0f
  159. }; //we love you vertices!
  160.  
  161. GLuint theShaderProgram;
  162. theShaderProgram = BuildShaderProgram( "base\\vs1.glsl", "base\\fs1.glsl" );
  163. if( theShaderProgram == 0 )
  164. {
  165. SDL_Quit();
  166. return 0;
  167. }
  168. immediate[0].xyz[0] = 1.0f;
  169. immediate[0].xyz[1] = 0.5f;
  170. immediate[0].xyz[2] = 0.0f;
  171. immediate[0].xyz[3] = 1.0f;
  172. immediate[0].c[0] = 1.0f;
  173. immediate[0].c[1] = 0.0f;
  174. immediate[0].c[2] = 0.0f;
  175. immediate[0].c[3] = 1.0f;
  176.  
  177. immediate[1].xyz[0] = 0.5f;
  178. immediate[1].xyz[1] = -0.366f;
  179. immediate[1].xyz[2] = 0.0f;
  180. immediate[1].xyz[3] = 1.0f;
  181. immediate[1].c[0] = 0.0f;
  182. immediate[1].c[1] = 1.0f;
  183. immediate[1].c[2] = 0.0f;
  184. immediate[1].c[3] = 1.0f;
  185.  
  186. immediate[2].xyz[0] = -0.5f;
  187. immediate[2].xyz[1] = -0.366f;
  188. immediate[2].xyz[2] = 0.0f;
  189. immediate[2].xyz[3] = 1.0f;
  190. immediate[2].c[0] = 0.0f;
  191. immediate[2].c[1] = 0.0f;
  192. immediate[2].c[2] = 1.0f;
  193. immediate[2].c[3] = 1.0f;
  194. GLuint vao;
  195. glGenVertexArrays(1, &vao);
  196. glBindVertexArray(vao);
  197.  
  198. /*GLuint triangleBufferObject;
  199. glGenBuffers(1, &triangleBufferObject);
  200. glBindBuffer(GL_ARRAY_BUFFER, triangleBufferObject);
  201. glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
  202.  
  203. glEnableVertexAttribArray( VertexBuffer::VERT_POSITION );
  204. glEnableVertexAttribArray( VertexBuffer::VERT_COLOR );
  205. glVertexAttribPointer( VertexBuffer::VERT_POSITION, 4, GL_FLOAT, GL_FALSE, 0, 0);
  206. glVertexAttribPointer( VertexBuffer::VERT_COLOR, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);*/
  207.  
  208. GLuint triangleBufferObject;
  209. glGenBuffers(1, &triangleBufferObject);
  210. glBindBuffer( GL_ARRAY_BUFFER, triangleBufferObject );
  211. glBufferData( GL_ARRAY_BUFFER, sizeof(Vertex)*MAX_VERTS, NULL, GL_STATIC_DRAW );
  212. glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(Vertex)*MAX_VERTS, immediate );
  213.  
  214. glEnableVertexAttribArray( VertexBuffer::VERT_POSITION );
  215. glEnableVertexAttribArray( VertexBuffer::VERT_COLOR );
  216.  
  217. glVertexAttribPointer( VertexBuffer::VERT_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof( Vertex ), (const void*)offsetof( Vertex, xyz ) );
  218. glVertexAttribPointer( VertexBuffer::VERT_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof( Vertex ), (const void*)offsetof( Vertex, c ) );
  219.  
  220.  
  221. glBindBuffer( GL_ARRAY_BUFFER, 0 );
  222. glBindVertexArray( 0 );
  223. GLCheckError();
  224. SDL_Event e;
  225. bool bGameLoopRunning = true;
  226. while( bGameLoopRunning )
  227. {
  228. if ( SDL_PollEvent(&e) )
  229. {
  230. if( e.type == SDL_QUIT )
  231. {
  232. bGameLoopRunning = false;
  233. }
  234. if( e.type == SDL_KEYUP && e.key.keysym.sym == SDLK_ESCAPE )
  235. {
  236. bGameLoopRunning = false;
  237. }
  238. if( e.type == SDL_KEYUP && e.key.keysym.sym == SDLK_F1 )
  239. {
  240. /*immediate[0].xyz[0] = 0.0f;
  241. glBindBuffer( GL_ARRAY_BUFFER, triangleBufferObject );
  242. glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(Vertex)*MAX_VERTS, immediate );
  243. glBindBuffer( GL_ARRAY_BUFFER, 0 );*/
  244. glBindBuffer( GL_ARRAY_BUFFER, triangleBufferObject );
  245. float *v = (float*)glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
  246. v[0] = 0.0f;
  247. glBindBuffer( GL_ARRAY_BUFFER, triangleBufferObject );
  248. glUnmapBuffer( GL_ARRAY_BUFFER );
  249. GLCheckError();
  250. }
  251. }
  252.  
  253. glClearColor( 0.3f, 0.4f, 0.4f, 1.0f );
  254. glClear(GL_COLOR_BUFFER_BIT);
  255.  
  256. glUseProgram(theShaderProgram);
  257.  
  258. glBindVertexArray( vao );
  259. glDrawArraysInstanced( GL_TRIANGLES, 0, 3, 1 );
  260. glBindVertexArray( 0 );
  261.  
  262. glUseProgram(0);
  263.  
  264. SDL_GL_SwapWindow(window);
  265. GLCheckError();
  266. }
  267.  
  268. SDL_GL_DeleteContext(glContext);
  269. SDL_Quit();
  270. return 0;
  271. }
  272.  
  273. GLuint BuildShaderProgram(const char *vsPath, const char *fsPath)
  274. {
  275. GLuint vertexShader;
  276. GLuint fragmentShader;
  277.  
  278. vertexShader = CreateShader( GL_VERTEX_SHADER, vsPath );
  279. fragmentShader = CreateShader( GL_FRAGMENT_SHADER, fsPath );
  280.  
  281. GLuint tempProgram;
  282. tempProgram = glCreateProgram();
  283.  
  284. glAttachShader( tempProgram, vertexShader );
  285. glAttachShader( tempProgram, fragmentShader );
  286.  
  287. glLinkProgram( tempProgram );
  288.  
  289. GLint status;
  290. glGetProgramiv( tempProgram, GL_LINK_STATUS, &status );
  291. if( status == GL_FALSE )
  292. {
  293. GLint infoLogLength;
  294. glGetProgramiv( tempProgram, GL_INFO_LOG_LENGTH, &infoLogLength );
  295.  
  296. GLchar strInfoLog[4096];
  297. glGetProgramInfoLog( tempProgram, infoLogLength, NULL, strInfoLog );
  298. printf("Shader linker failure: %s\n", strInfoLog);
  299.  
  300. return -1;
  301. }
  302. else
  303. {
  304. printf("Shader linked sucessfully!\n");
  305. }
  306.  
  307. glDetachShader( tempProgram, vertexShader );
  308. glDetachShader( tempProgram, fragmentShader );
  309.  
  310. return tempProgram;
  311. }
  312.  
  313. GLuint CreateShader(GLenum eShaderType, const char *strShaderFile)
  314. {
  315. char shaderSource[4096];
  316. char inChar;
  317. FILE *shaderFile;
  318. int i = 0;
  319.  
  320. shaderFile = fopen(strShaderFile, "r");
  321. while(fscanf(shaderFile,"%c",&inChar) > 0)
  322. {
  323. shaderSource[i++] = inChar;
  324. }
  325. shaderSource[i - 1] = '\0';
  326. fclose(shaderFile);
  327. //printf( "%s\n\n", shaderSource );
  328.  
  329. GLuint shader = glCreateShader(eShaderType);
  330. const char *ss = shaderSource;
  331. glShaderSource(shader, 1, &ss, NULL);
  332.  
  333. glCompileShader(shader);
  334.  
  335. GLint status;
  336. glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  337. if (status == GL_FALSE)
  338. {
  339. GLint infoLogLength;
  340. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
  341.  
  342. GLchar strInfoLog[4096];
  343. glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
  344.  
  345. char strShaderType[16];
  346. switch( eShaderType )
  347. {
  348. case GL_VERTEX_SHADER: sprintf(strShaderType, "vertex"); break;
  349. case GL_GEOMETRY_SHADER: sprintf(strShaderType, "geometry"); break;
  350. case GL_FRAGMENT_SHADER: sprintf(strShaderType, "fragment"); break;
  351. }
  352.  
  353. printf( "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
  354. return -1;
  355. }
  356. else
  357. {
  358. printf( "Shader compiled sucessfully!\n" );
  359. }
  360.  
  361. return shader;
  362. }
  363.  
  364.  
  365. void Init()
  366. {
  367. FILE *file;
  368. file = fopen( "log", "w" );
  369. if( !file )
  370. {
  371. fprintf( stderr, "%s", "Cannot open file\n" );
  372. return;
  373. }
  374. fclose( file );
  375. }
  376.  
  377. void Printf( const char *format, ... )
  378. {
  379. va_list list;
  380. FILE *file;
  381.  
  382. file = fopen( "log", "a" );
  383. if( !file )
  384. {
  385. fprintf( stderr, "%s", "Cannot open file\n" );
  386. return;
  387. }
  388. va_start( list, format );
  389. vfprintf( file, format, list );
  390. va_end( list );
  391.  
  392. fclose( file );
  393. }
  394.  
  395. void InitHint()
  396. {
  397. if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) )
  398. {
  399. Printf( "Warning: Linear texture filtering not enabled!\n" );
  400. }
  401. if( !SDL_SetHint( SDL_HINT_RENDER_VSYNC, "1" ) )
  402. {
  403. Printf( "Warning: Vsync not enabled!\n" );
  404. }
  405. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement