#include #include #include #include #include "opengl.h" #include "readfile.h" shaderProgram_t sp; GLuint createShader ( const char *shaderFile, GLenum shaderType ) { const char *strShaderType; if (shaderType == GL_VERTEX_SHADER) { strShaderType = "vertex"; } else if (shaderType == GL_GEOMETRY_SHADER) { strShaderType = "geometry"; } else if (shaderType == GL_FRAGMENT_SHADER) { strShaderType = "fragment"; } else { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Unrecognized shader type."); exit(EXIT_FAILURE); } GLuint shader = glCreateShader(shaderType); if (!shader) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Error create shader type %s.", strShaderType); exit(EXIT_FAILURE); } GLchar *content = readFile(shaderFile); glShaderSource(shader, 1, (const GLchar **)&content, NULL); SDL_free(content); glCompileShader(shader); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLint infoLen; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); GLchar *info = SDL_malloc(sizeof(GLchar) * (infoLen + 1)); glGetShaderInfoLog(shader, infoLen, NULL, info); SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Filed to compile %s shader:\n%s.", strShaderType, info); exit(EXIT_FAILURE); } return shader; } void createProgram ( GLuint *shaders, int len ) { sp.program = glCreateProgram(); if (!sp.program) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Can't to create shader program."); exit(EXIT_FAILURE); } for (int i = 0; i < len; i++) { glAttachShader(sp.program, shaders[i]); } glLinkProgram(sp.program); GLint status; glGetProgramiv(sp.program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLint infoLen; glGetProgramiv(sp.program, GL_INFO_LOG_LENGTH, &infoLen); GLchar *info = SDL_malloc(sizeof(GLchar) * (infoLen + 1)); glGetProgramInfoLog(sp.program, infoLen, NULL, info); SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Link failed: %s", info); exit(EXIT_FAILURE); } } void createBuffer ( void ) { GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; float vertices[] = { -1.0f, -1.0f, -2.0f, 1.0f, // left-bottom -1.0f, 1.0f, -2.0f, 1.0f, // left-top 1.0f, 1.0f, -2.0f, 1.0f, // right-top 1.0f, -1.0f, -2.0f, 1.0f, // right-bottom // colours 1.0f, 0.0f, 0.0f, 1.0f, // red 0.0f, 1.0f, 0.0f, 1.0f, // green 1.0f, 0.0f, 1.0f, 1.0f, // purple 1.0f, 1.0f, 0.0f, 1.0f // yellow }; glGenBuffers(1, &sp.vbo); glBindBuffer(GL_ARRAY_BUFFER, sp.vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &sp.ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sp.ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void setUniformLocation ( void ) { sp.projMatrLoc = glGetUniformLocation(sp.program, "projMatr"); } void startShaderProg ( void ) { createBuffer(); GLuint shaders[] = { createShader("vertex.glsl", GL_VERTEX_SHADER), createShader("fragment.glsl", GL_FRAGMENT_SHADER) }; int len = sizeof(shaders) / sizeof(shaders[0]); createProgram(shaders, len); for (int i = 0; i < len; i++) { glDeleteShader(shaders[i]); } setUniformLocation(); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glDepthRange(0.0f, 1.0f); } void _GLBuffer( void ) { glClearColor(0.0f, 0.0f, 1.0f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(sp.program); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, sp.vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sp.ibo); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void *) (4*4*sizeof(float))); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glUseProgram(0); }