Advertisement
Guest User

main.cpp

a guest
Jul 21st, 2016
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.54 KB | None | 0 0
  1. #include <GL/glew.h> // include GLEW and new version of GL on Windows
  2. #if defined(_WIN32)
  3. #include <GL/wglew.h>
  4. #elif !defined(__APPLE__) && !defined(__HAIKU__) || defined(GLEW_APPLE_GLX)
  5. #include <GL/glxew.h>
  6. #endif
  7. #include <GLFW/glfw3.h> // GLFW helper library
  8.  
  9. #include <assert.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <time.h>
  13. #include <stdarg.h>
  14.  
  15. #define GL_LOG_FILE "gl.log"
  16.  
  17. //#define ALT_BUILD
  18.  
  19. bool restart_gl_log()
  20. {
  21.     FILE* file = NULL;
  22.     fopen_s(&file, GL_LOG_FILE, "w");
  23.     if (!file)
  24.     {
  25.         fprintf(stderr,
  26.         "ERROR: could not open GL_LOG_FILE log file %s for writing\n",
  27.         GL_LOG_FILE);
  28.         return false;
  29.     }
  30.  
  31.     time_t now = time(NULL);
  32.     char* date = ctime(&now);
  33.     fprintf(file, "GL_LOG_FILE log. local time %s\n", date);
  34.     fclose(file);
  35.     return true;
  36. }
  37.  
  38. bool gl_log(const char* message, ...)
  39. {
  40.     va_list argptr;
  41.     FILE* file = NULL;
  42.     fopen_s(&file, GL_LOG_FILE, "a");
  43.     if (!file)
  44.     {
  45.         fprintf(stderr,
  46.                 "ERROR: could not open GL_LOG_FILE %s file for appending\n",
  47.                 GL_LOG_FILE);
  48.         return false;
  49.     }
  50.     va_start(argptr, message);
  51.     vfprintf(file, message, argptr);
  52.     va_end(argptr);
  53.     fclose(file);
  54.     return true;
  55. }
  56.  
  57. bool gl_log_err(const char* message, ...)
  58. {
  59.     va_list argptr;
  60.     FILE* file = NULL;
  61.     fopen_s(&file, GL_LOG_FILE, "a");
  62.     if (!file)
  63.     {
  64.         fprintf(stderr,
  65.                 "ERROR: could not open GL_LOG_FILE %s file for appending\n",
  66.                 GL_LOG_FILE);
  67.         return false;
  68.     }
  69.  
  70.     va_start(argptr, message);
  71.     vfprintf(file, message, argptr);
  72.     va_end(argptr);
  73.     va_start(argptr, message);
  74.     vfprintf(stderr, message, argptr);
  75.     va_end(argptr);
  76.     fclose(file);
  77.     return true;
  78. }
  79.  
  80. void glfw_error_callback(int error, const char* description)
  81. {
  82.     gl_log_err("GLFW ERROR: code %i msg: %s\n", error, description);
  83. }
  84.  
  85. void _print_shader_info_log(GLuint shader_index)
  86. {
  87.   int max_length = 2048;
  88.   int actual_length = 0;
  89.   char log[2048];
  90.   glGetShaderInfoLog(shader_index, max_length, &actual_length, log);
  91.   gl_log_err("shader info log for GL index %u:\n%s\n", shader_index, log);
  92. }
  93.  
  94. void _print_program_info_log(GLuint program)
  95. {
  96.   int max_length = 2048;
  97.   int actual_length = 0;
  98.   char log[2048];
  99.   glGetProgramInfoLog(program, max_length, &actual_length, log);
  100.   gl_log_err("program info log for GL index %u:\n%s", program, log);
  101. }
  102.  
  103. const char* GL_type_to_string(GLenum type)
  104. {
  105.     switch (type)
  106.     {
  107.     case GL_BOOL: return "bool";
  108.     case GL_INT: return "int";
  109.     case GL_FLOAT: return "float";
  110.     case GL_FLOAT_VEC2: return "vec2";
  111.     case GL_FLOAT_VEC3: return "vec3";
  112.     case GL_FLOAT_VEC4: return "vec4";
  113.     case GL_FLOAT_MAT2: return "mat2";
  114.     case GL_FLOAT_MAT3: return "mat3";
  115.     case GL_FLOAT_MAT4: return "mat4";
  116.     case GL_SAMPLER_2D: return "sampler2D";
  117.     case GL_SAMPLER_3D: return "sampler3D";
  118.     case GL_SAMPLER_CUBE: return "samplerCube";
  119.     case GL_SAMPLER_2D_SHADOW: return "sampler2DShadow";
  120.     default: break;
  121.     }
  122.  
  123.     return "other";
  124. }
  125.  
  126. void print_all(GLuint program)
  127. {
  128.     gl_log("--------------------\nshader program %i info:\n", program);
  129.     int params = -1;
  130.     glGetProgramiv(program, GL_LINK_STATUS, &params);
  131.     gl_log("GL_LINK_STATUS = %i\n", params);
  132.  
  133.     glGetProgramiv(program, GL_ATTACHED_SHADERS, &params);
  134.     gl_log("GL_ATTACHED_SHADERS = %i\n", params);
  135.  
  136.     glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &params);
  137.     gl_log("GL_ACTIVE_ATTRIBUTES = %i\n", params);
  138.     for (int i = 0; i < params; i++)
  139.     {
  140.         char name[64];
  141.         int max_length = 64;
  142.         int actual_length = 0;
  143.         int size = 0;
  144.         GLenum type;
  145.         glGetActiveAttrib(
  146.             program,
  147.             i,
  148.             max_length,
  149.             &actual_length,
  150.             &size,
  151.             &type,
  152.             name
  153.             );
  154.         if (size > 1)
  155.         {
  156.             for (int j = 0; j < size; j++)
  157.             {
  158.                 char long_name[64];
  159.                 sprintf(long_name, "%s[%i]", name, j);
  160.                 int location = glGetAttribLocation (program, long_name);
  161.                 gl_log("  %i) type:%s name:%s location:%i\n",
  162.                     i, GL_type_to_string (type), long_name, location);
  163.             }
  164.         }
  165.         else
  166.         {
  167.             int location = glGetAttribLocation(program, name);
  168.             gl_log("  %i) type:%s name:%s location:%i\n",
  169.                 i, GL_type_to_string(type), name, location);
  170.         }
  171.     }
  172.  
  173.     glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &params);
  174.     gl_log("GL_ACTIVE_UNIFORMS = %i\n", params);
  175.     for (int i = 0; i < params; i++)
  176.     {
  177.         char name[64];
  178.         int max_length = 64;
  179.         int actual_length = 0;
  180.         int size = 0;
  181.         GLenum type;
  182.         glGetActiveUniform(
  183.             program,
  184.             i,
  185.             max_length,
  186.             &actual_length,
  187.             &size,
  188.             &type,
  189.             name
  190.             );
  191.         if (size > 1)
  192.         {
  193.             for (int j = 0; j < size; j++)
  194.             {
  195.                 char long_name[64];
  196.                 sprintf(long_name, "%s[%i]", name, j);
  197.                 int location = glGetUniformLocation(program, long_name);
  198.                 gl_log("  %i) type:%s name:%s location:%i\n",
  199.                     i, GL_type_to_string(type), long_name, location);
  200.             }
  201.         }
  202.         else
  203.         {
  204.             int location = glGetUniformLocation(program, name);
  205.             gl_log("  %i) type:%s name:%s location:%i\n",
  206.                 i, GL_type_to_string (type), name, location);
  207.         }
  208.     }
  209.  
  210.     _print_program_info_log(program);
  211. }
  212.  
  213. char* load_file(const char *file_name)
  214. {
  215.     FILE* vfile = NULL;
  216.     errno_t err = fopen_s(&vfile, file_name, "r");
  217.     if (err != 0 || vfile == NULL)
  218.     {
  219.         fprintf(stderr, "ERROR: could not open file \"%s\": %s\n", file_name, strerror(err));
  220.         glfwTerminate();
  221.         return NULL;
  222.     }
  223.  
  224.     fseek(vfile, 0, SEEK_END);
  225.     long size = ftell(vfile);
  226.     rewind(vfile);
  227.     char* buffer = (char*)malloc(size + 1);
  228.     fread(buffer, sizeof(char), size, vfile);
  229.     fclose(vfile);
  230.  
  231.     buffer[size] = '\0';
  232.  
  233.     return buffer;
  234. }
  235.  
  236. int main() {
  237.     assert(restart_gl_log());
  238.     // start GL context and O/S window using the GLFW helper library
  239.     gl_log("starting GLFW\n%s\n", glfwGetVersionString());
  240.     // register the error call-back function that we wrote, above
  241.     glfwSetErrorCallback(glfw_error_callback);
  242.  
  243.     // start GL context and O/S window using the GLFW helper library
  244.     if (!glfwInit())
  245.     {
  246.         fprintf(stderr, "ERROR: could not start GLFW3\n");
  247.         return 1;
  248.     }
  249.  
  250.     // uncomment these lines if on Apple OS X
  251.     /*glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  252.     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  253.     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  254.     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);*/
  255.  
  256.     GLFWwindow* window = glfwCreateWindow(960, 540, "Loading YUV420p Texture", NULL, NULL);
  257.     if (!window)
  258.     {
  259.         fprintf(stderr, "ERROR: could not open window with GLFW3\n");
  260.         glfwTerminate();
  261.         return 1;
  262.     }
  263.  
  264.     glfwMakeContextCurrent(window);
  265.                                  
  266.     // start GLEW
  267.     glewExperimental = GL_TRUE;
  268.     glewInit ();
  269.  
  270.     // get version info
  271.     const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
  272.     const GLubyte* version = glGetString(GL_VERSION); // version as a string
  273.     gl_log("Renderer: %s\n", renderer);
  274.     gl_log("OpenGL version supported %s\n", version);
  275.  
  276.     // tell GL to only draw onto a pixel if the shape is closer to the viewer
  277.     glEnable(GL_DEPTH_TEST); // enable depth-testing
  278.     glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
  279.  
  280.     /* OTHER STUFF GOES HERE NEXT */
  281.     float points[] = {
  282.         -1.0f,  1.0f,  0.0f,
  283.         1.0f, 1.0f,  0.0f,
  284.         -1.0f, -1.0f,  0.0f,
  285.         1.0f, -1.0f,  0.0f
  286.     };
  287.     GLuint vbo = 0;
  288.     glGenBuffers(1, &vbo);
  289.     glBindBuffer(GL_ARRAY_BUFFER, vbo);
  290.     glBufferData(GL_ARRAY_BUFFER, 12 * sizeof (float), points, GL_STATIC_DRAW);
  291.  
  292.     GLuint vao = 0;
  293.     glGenVertexArrays(1, &vao);
  294.     glBindVertexArray(vao);
  295.     glEnableVertexAttribArray(0);
  296.     glBindBuffer(GL_ARRAY_BUFFER, vbo);
  297.     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
  298.  
  299.     char *vertex_shader = load_file("vertex.glsl");
  300.     if (vertex_shader == NULL)
  301.     {
  302.         return 1;
  303.     }
  304.  
  305. #ifndef ALT_BUILD
  306.     char *fragment_shader = load_file("fragment.glsl");
  307. #else
  308.     char *fragment_shader = load_file("fragment_alt.glsl");
  309. #endif
  310.     if (fragment_shader == NULL)
  311.     {
  312.         return 1;
  313.     }
  314.  
  315.     // create shaders
  316.     GLuint vs = glCreateShader(GL_VERTEX_SHADER);
  317.     glShaderSource(vs, 1, &vertex_shader, NULL);
  318.     glCompileShader(vs);
  319.     GLint success = GL_FALSE;
  320.     glGetShaderiv(vs, GL_COMPILE_STATUS, &success);
  321.     if (GL_TRUE != success)
  322.     {
  323.         fprintf(stderr, "ERROR: GL shader index %i did not compile\n", vs);
  324.         _print_shader_info_log(vs);
  325.         return false; // or exit or something
  326.     }
  327.  
  328.     GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
  329.     glShaderSource(fs, 1, &fragment_shader, NULL);
  330.     glCompileShader(fs);
  331.     success = GL_FALSE;
  332.     glGetShaderiv(fs, GL_COMPILE_STATUS, &success);
  333.     if (GL_TRUE != success)
  334.     {
  335.         fprintf(stderr, "ERROR: GL shader index %i did not compile\n", fs);
  336.         _print_shader_info_log(fs);
  337.         return false; // or exit or something
  338.     }
  339.  
  340.     // create shader program and compile
  341.     GLuint shader_program = glCreateProgram();
  342.     glAttachShader(shader_program, fs);
  343.     glAttachShader(shader_program, vs);
  344.     glLinkProgram(shader_program);
  345.     glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
  346.     if (GL_TRUE != success)
  347.     {
  348.         fprintf(stderr, "ERROR: could not link shader program GL index %u\n", shader_program);
  349.         _print_program_info_log(shader_program);
  350.         return false;
  351.     }
  352.  
  353.     print_all(shader_program);
  354.  
  355.     // release shader strings
  356.     free(vertex_shader);
  357.     free(fragment_shader);
  358.  
  359.     // load YUV420p texture
  360.     GLuint texture;
  361.     glGenTextures(1, &texture);
  362.     glActiveTexture(GL_TEXTURE0);
  363.     glBindTexture(GL_TEXTURE_2D, texture);
  364.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  365.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  366.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  367.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  368.  
  369.     char *tex = load_file("texture.yuv");
  370.     if (tex == NULL)
  371.     {
  372.         return 1;
  373.     }
  374.    
  375.     int width = 3840;
  376.     int height = 2160;
  377. #ifndef ALT_BUILD
  378.     glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, width, height * 3/2, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, tex);
  379. #else
  380.     // In YUV420p 10-bit color is saved as 10 least significant bits of every two bytes,
  381.     // so to load it properly as a texture we need to cheat a bit and say every two bytes
  382.     // contain all RGBA components (in reverse order) with 5 bits per color and one,
  383.     // most significant, bit per alpha channel. Then, in a shader, proper color need to be
  384.     // constructed from R and G components.
  385.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height * 3/2, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, tex);
  386. #endif
  387.     free(tex);
  388.  
  389.     // set texture uniform in program
  390.     glUseProgram(shader_program);
  391.     GLint uniLoc = glGetUniformLocation(shader_program, "yuvTexture");
  392.     // 'yuvTexture' sampler is set to zero to sample texture from GL_TEXTURE0 texture unit
  393.     glUniform1i(uniLoc, 0);
  394.  
  395.     while (!glfwWindowShouldClose(window))
  396.     {
  397.         // wipe the drawing
  398.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  399.        
  400.         glUseProgram(shader_program);
  401.         glBindVertexArray(vao);
  402.  
  403.         // draw points 0-3 from the currently bound VAO with current in-use shader
  404.         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  405.         // update other events like input handling
  406.         glfwPollEvents();
  407.         // put the stuff we've been drawing onto the display
  408.         glfwSwapBuffers(window);
  409.     }
  410.    
  411.     glDeleteTextures(1, &texture);
  412.  
  413.     glDeleteProgram(shader_program);
  414.     glDeleteShader(vs);
  415.     glDeleteShader(fs);
  416.  
  417.     glDeleteBuffers(1, &vbo);
  418.     glDeleteVertexArrays(1, &vao);
  419.  
  420.     // close GL context and any other GLFW resources
  421.     glfwTerminate();
  422.     return 0;
  423. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement