#include #include #include #include #include #include #include #include #include #include #include static void * read_file(const char * filename) { int fd = open(filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "open(%s): %s\n", filename, strerror(errno)); return NULL; } off_t size = lseek(fd, 0, SEEK_END); if (size == (off_t)-1) { fprintf(stderr, "lseek(%s, SEEK_END): %s\n", filename, strerror(errno)); return NULL; } off_t start = lseek(fd, 0, SEEK_SET); if (start == (off_t)-1) { fprintf(stderr, "lseek(%s, SEEK_SET): %s\n", filename, strerror(errno)); return NULL; } void * buf = malloc(size+1); ssize_t read_size = read(fd, buf, size); if (read_size == -1) { fprintf(stderr, "read(%s): %s\n", filename, strerror(errno)); return NULL; } ((char*)buf)[read_size] = 0; return buf; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } unsigned int compile_shaders() { void * vertexShaderSource = read_file("src/texture.vp.glsl"); unsigned int vertexShader; vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, (const char **)&vertexShaderSource, NULL); glCompileShader(vertexShader); { int success; char infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if(!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); printf("vertex shader compile failed:\n%s\n", infoLog); } } free(vertexShaderSource); void * fragmentShaderSource = read_file("src/texture_blur2.fp.glsl"); unsigned int fragmentShader; fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, (const char **)&fragmentShaderSource, NULL); glCompileShader(fragmentShader); { int success; char infoLog[512]; glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if(!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); printf("fragment shader compile failed:\n%s\n", infoLog); } } free(fragmentShaderSource); unsigned int shaderProgram; shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); { int success; char infoLog[512]; glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if(!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); printf("program link failed:\n%s\n", infoLog); } } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); return shaderProgram; } static int make_buffer(unsigned int target, const void * data, size_t size) { unsigned int buffer; glGenBuffers(1, &buffer); glBindBuffer(target, buffer); glBufferData(target, size, data, GL_STATIC_DRAW); return buffer; } static const float vertex_buffer_data[] = { // position // texture 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // top right 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, // bottom right -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, // bottom left -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // top left 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // top right -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, // bottom left }; struct location { struct { unsigned int position; unsigned int texture; } attrib; struct { unsigned int texture1; } uniform; }; int main() { glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11); glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); //glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); GLFWwindow* window = glfwCreateWindow(1600, 1200, "LearnOpenGL", NULL, NULL); if (window == NULL) { const char* description; glfwGetError(&description); printf("Failed to create GLFW window: %s\n", description); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glViewport(0, 0, 1600, 1200); //glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); unsigned int vertex_buffer = make_buffer(GL_ARRAY_BUFFER, vertex_buffer_data, (sizeof (vertex_buffer_data))); printf("compile start\n"); unsigned int shaderProgram = compile_shaders(); printf("compile end\n"); struct location location; location.attrib.position = glGetAttribLocation(shaderProgram, "pos"); location.attrib.texture = glGetAttribLocation(shaderProgram, "tex"); printf("attributes:\n position %u\n texture %u\n", location.attrib.position, location.attrib.texture); location.uniform.texture1 = glGetUniformLocation(shaderProgram, "texture1"); printf("uniforms:\n texture %u\n", location.uniform.texture1); unsigned int texture1; glGenTextures(1, &texture1); glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, texture1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); void * texture_buf = read_file("texture/butterfly_128x128_argb8888.data"); assert(texture_buf != NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_buf); free(texture_buf); while(!glfwWindowShouldClose(window)) { if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); //glClearColor(0.1f, 0.1f, 0.1f, 0.1f); //glClear(GL_COLOR_BUFFER_BIT); // // render // glUseProgram(shaderProgram); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glVertexAttribPointer(location.attrib.position, 3, GL_FLOAT, GL_FALSE, (sizeof (float)) * 5, (void*)0 ); glVertexAttribPointer(location.attrib.texture, 2, GL_FLOAT, GL_FALSE, (sizeof (float)) * 5, (void*)(3 * 4) ); glEnableVertexAttribArray(location.attrib.position); glEnableVertexAttribArray(location.attrib.texture); glUniform1i(location.uniform.texture1, 0); glDrawArrays(GL_TRIANGLES, 0, 6); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }