Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <GL/glew.h> // include GLEW and new version of GL on Windows
- #if defined(_WIN32)
- #include <GL/wglew.h>
- #elif !defined(__APPLE__) && !defined(__HAIKU__) || defined(GLEW_APPLE_GLX)
- #include <GL/glxew.h>
- #endif
- #include <GLFW/glfw3.h> // GLFW helper library
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <stdarg.h>
- #define GL_LOG_FILE "gl.log"
- //#define ALT_BUILD
- bool restart_gl_log()
- {
- FILE* file = NULL;
- fopen_s(&file, GL_LOG_FILE, "w");
- if (!file)
- {
- fprintf(stderr,
- "ERROR: could not open GL_LOG_FILE log file %s for writing\n",
- GL_LOG_FILE);
- return false;
- }
- time_t now = time(NULL);
- char* date = ctime(&now);
- fprintf(file, "GL_LOG_FILE log. local time %s\n", date);
- fclose(file);
- return true;
- }
- bool gl_log(const char* message, ...)
- {
- va_list argptr;
- FILE* file = NULL;
- fopen_s(&file, GL_LOG_FILE, "a");
- if (!file)
- {
- fprintf(stderr,
- "ERROR: could not open GL_LOG_FILE %s file for appending\n",
- GL_LOG_FILE);
- return false;
- }
- va_start(argptr, message);
- vfprintf(file, message, argptr);
- va_end(argptr);
- fclose(file);
- return true;
- }
- bool gl_log_err(const char* message, ...)
- {
- va_list argptr;
- FILE* file = NULL;
- fopen_s(&file, GL_LOG_FILE, "a");
- if (!file)
- {
- fprintf(stderr,
- "ERROR: could not open GL_LOG_FILE %s file for appending\n",
- GL_LOG_FILE);
- return false;
- }
- va_start(argptr, message);
- vfprintf(file, message, argptr);
- va_end(argptr);
- va_start(argptr, message);
- vfprintf(stderr, message, argptr);
- va_end(argptr);
- fclose(file);
- return true;
- }
- void glfw_error_callback(int error, const char* description)
- {
- gl_log_err("GLFW ERROR: code %i msg: %s\n", error, description);
- }
- void _print_shader_info_log(GLuint shader_index)
- {
- int max_length = 2048;
- int actual_length = 0;
- char log[2048];
- glGetShaderInfoLog(shader_index, max_length, &actual_length, log);
- gl_log_err("shader info log for GL index %u:\n%s\n", shader_index, log);
- }
- void _print_program_info_log(GLuint program)
- {
- int max_length = 2048;
- int actual_length = 0;
- char log[2048];
- glGetProgramInfoLog(program, max_length, &actual_length, log);
- gl_log_err("program info log for GL index %u:\n%s", program, log);
- }
- const char* GL_type_to_string(GLenum type)
- {
- switch (type)
- {
- case GL_BOOL: return "bool";
- case GL_INT: return "int";
- case GL_FLOAT: return "float";
- case GL_FLOAT_VEC2: return "vec2";
- case GL_FLOAT_VEC3: return "vec3";
- case GL_FLOAT_VEC4: return "vec4";
- case GL_FLOAT_MAT2: return "mat2";
- case GL_FLOAT_MAT3: return "mat3";
- case GL_FLOAT_MAT4: return "mat4";
- case GL_SAMPLER_2D: return "sampler2D";
- case GL_SAMPLER_3D: return "sampler3D";
- case GL_SAMPLER_CUBE: return "samplerCube";
- case GL_SAMPLER_2D_SHADOW: return "sampler2DShadow";
- default: break;
- }
- return "other";
- }
- void print_all(GLuint program)
- {
- gl_log("--------------------\nshader program %i info:\n", program);
- int params = -1;
- glGetProgramiv(program, GL_LINK_STATUS, ¶ms);
- gl_log("GL_LINK_STATUS = %i\n", params);
- glGetProgramiv(program, GL_ATTACHED_SHADERS, ¶ms);
- gl_log("GL_ATTACHED_SHADERS = %i\n", params);
- glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, ¶ms);
- gl_log("GL_ACTIVE_ATTRIBUTES = %i\n", params);
- for (int i = 0; i < params; i++)
- {
- char name[64];
- int max_length = 64;
- int actual_length = 0;
- int size = 0;
- GLenum type;
- glGetActiveAttrib(
- program,
- i,
- max_length,
- &actual_length,
- &size,
- &type,
- name
- );
- if (size > 1)
- {
- for (int j = 0; j < size; j++)
- {
- char long_name[64];
- sprintf(long_name, "%s[%i]", name, j);
- int location = glGetAttribLocation (program, long_name);
- gl_log(" %i) type:%s name:%s location:%i\n",
- i, GL_type_to_string (type), long_name, location);
- }
- }
- else
- {
- int location = glGetAttribLocation(program, name);
- gl_log(" %i) type:%s name:%s location:%i\n",
- i, GL_type_to_string(type), name, location);
- }
- }
- glGetProgramiv(program, GL_ACTIVE_UNIFORMS, ¶ms);
- gl_log("GL_ACTIVE_UNIFORMS = %i\n", params);
- for (int i = 0; i < params; i++)
- {
- char name[64];
- int max_length = 64;
- int actual_length = 0;
- int size = 0;
- GLenum type;
- glGetActiveUniform(
- program,
- i,
- max_length,
- &actual_length,
- &size,
- &type,
- name
- );
- if (size > 1)
- {
- for (int j = 0; j < size; j++)
- {
- char long_name[64];
- sprintf(long_name, "%s[%i]", name, j);
- int location = glGetUniformLocation(program, long_name);
- gl_log(" %i) type:%s name:%s location:%i\n",
- i, GL_type_to_string(type), long_name, location);
- }
- }
- else
- {
- int location = glGetUniformLocation(program, name);
- gl_log(" %i) type:%s name:%s location:%i\n",
- i, GL_type_to_string (type), name, location);
- }
- }
- _print_program_info_log(program);
- }
- char* load_file(const char *file_name)
- {
- FILE* vfile = NULL;
- errno_t err = fopen_s(&vfile, file_name, "r");
- if (err != 0 || vfile == NULL)
- {
- fprintf(stderr, "ERROR: could not open file \"%s\": %s\n", file_name, strerror(err));
- glfwTerminate();
- return NULL;
- }
- fseek(vfile, 0, SEEK_END);
- long size = ftell(vfile);
- rewind(vfile);
- char* buffer = (char*)malloc(size + 1);
- fread(buffer, sizeof(char), size, vfile);
- fclose(vfile);
- buffer[size] = '\0';
- return buffer;
- }
- int main() {
- assert(restart_gl_log());
- // start GL context and O/S window using the GLFW helper library
- gl_log("starting GLFW\n%s\n", glfwGetVersionString());
- // register the error call-back function that we wrote, above
- glfwSetErrorCallback(glfw_error_callback);
- // start GL context and O/S window using the GLFW helper library
- if (!glfwInit())
- {
- fprintf(stderr, "ERROR: could not start GLFW3\n");
- return 1;
- }
- // uncomment these lines if on Apple OS X
- /*glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);*/
- GLFWwindow* window = glfwCreateWindow(960, 540, "Loading YUV420p Texture", NULL, NULL);
- if (!window)
- {
- fprintf(stderr, "ERROR: could not open window with GLFW3\n");
- glfwTerminate();
- return 1;
- }
- glfwMakeContextCurrent(window);
- // start GLEW
- glewExperimental = GL_TRUE;
- glewInit ();
- // get version info
- const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
- const GLubyte* version = glGetString(GL_VERSION); // version as a string
- gl_log("Renderer: %s\n", renderer);
- gl_log("OpenGL version supported %s\n", version);
- // tell GL to only draw onto a pixel if the shape is closer to the viewer
- glEnable(GL_DEPTH_TEST); // enable depth-testing
- glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
- /* OTHER STUFF GOES HERE NEXT */
- float points[] = {
- -1.0f, 1.0f, 0.0f,
- 1.0f, 1.0f, 0.0f,
- -1.0f, -1.0f, 0.0f,
- 1.0f, -1.0f, 0.0f
- };
- GLuint vbo = 0;
- glGenBuffers(1, &vbo);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, 12 * sizeof (float), points, GL_STATIC_DRAW);
- GLuint vao = 0;
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
- glEnableVertexAttribArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
- char *vertex_shader = load_file("vertex.glsl");
- if (vertex_shader == NULL)
- {
- return 1;
- }
- #ifndef ALT_BUILD
- char *fragment_shader = load_file("fragment.glsl");
- #else
- char *fragment_shader = load_file("fragment_alt.glsl");
- #endif
- if (fragment_shader == NULL)
- {
- return 1;
- }
- // create shaders
- GLuint vs = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vs, 1, &vertex_shader, NULL);
- glCompileShader(vs);
- GLint success = GL_FALSE;
- glGetShaderiv(vs, GL_COMPILE_STATUS, &success);
- if (GL_TRUE != success)
- {
- fprintf(stderr, "ERROR: GL shader index %i did not compile\n", vs);
- _print_shader_info_log(vs);
- return false; // or exit or something
- }
- GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fs, 1, &fragment_shader, NULL);
- glCompileShader(fs);
- success = GL_FALSE;
- glGetShaderiv(fs, GL_COMPILE_STATUS, &success);
- if (GL_TRUE != success)
- {
- fprintf(stderr, "ERROR: GL shader index %i did not compile\n", fs);
- _print_shader_info_log(fs);
- return false; // or exit or something
- }
- // create shader program and compile
- GLuint shader_program = glCreateProgram();
- glAttachShader(shader_program, fs);
- glAttachShader(shader_program, vs);
- glLinkProgram(shader_program);
- glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
- if (GL_TRUE != success)
- {
- fprintf(stderr, "ERROR: could not link shader program GL index %u\n", shader_program);
- _print_program_info_log(shader_program);
- return false;
- }
- print_all(shader_program);
- // release shader strings
- free(vertex_shader);
- free(fragment_shader);
- // load YUV420p texture
- GLuint texture;
- glGenTextures(1, &texture);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- char *tex = load_file("texture.yuv");
- if (tex == NULL)
- {
- return 1;
- }
- int width = 3840;
- int height = 2160;
- #ifndef ALT_BUILD
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, width, height * 3/2, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, tex);
- #else
- // In YUV420p 10-bit color is saved as 10 least significant bits of every two bytes,
- // so to load it properly as a texture we need to cheat a bit and say every two bytes
- // contain all RGBA components (in reverse order) with 5 bits per color and one,
- // most significant, bit per alpha channel. Then, in a shader, proper color need to be
- // constructed from R and G components.
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height * 3/2, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, tex);
- #endif
- free(tex);
- // set texture uniform in program
- glUseProgram(shader_program);
- GLint uniLoc = glGetUniformLocation(shader_program, "yuvTexture");
- // 'yuvTexture' sampler is set to zero to sample texture from GL_TEXTURE0 texture unit
- glUniform1i(uniLoc, 0);
- while (!glfwWindowShouldClose(window))
- {
- // wipe the drawing
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glUseProgram(shader_program);
- glBindVertexArray(vao);
- // draw points 0-3 from the currently bound VAO with current in-use shader
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- // update other events like input handling
- glfwPollEvents();
- // put the stuff we've been drawing onto the display
- glfwSwapBuffers(window);
- }
- glDeleteTextures(1, &texture);
- glDeleteProgram(shader_program);
- glDeleteShader(vs);
- glDeleteShader(fs);
- glDeleteBuffers(1, &vbo);
- glDeleteVertexArrays(1, &vao);
- // close GL context and any other GLFW resources
- glfwTerminate();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement