#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/vertex_color.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/vertex_color.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 // color 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top }; struct location { struct { unsigned int position; unsigned int color; } attrib; }; int main() { 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, "position"); location.attrib.color = glGetAttribLocation(shaderProgram, "color"); printf("attributes:\n position %u\n color %u\n", location.attrib.position, location.attrib.color); 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)) * 6, (void*)0 ); glVertexAttribPointer(location.attrib.color, 3, GL_FLOAT, GL_FALSE, (sizeof (float)) * 6, (void*)(3 * 4) ); glEnableVertexAttribArray(location.attrib.position); glEnableVertexAttribArray(location.attrib.color); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }