#include #include #include #include #include #include #include #define ASSERT(x) if (!(x)) raise(SIGTRAP) #define GL_CALL(x) GLClearError();\ x;\ ASSERT(GLLogCall(#x, __FILE__, __LINE__)) static void GLClearError() { while(glGetError() != GL_NO_ERROR); } static bool GLLogCall(const char *function_name, const char *file, int line) { while(GLenum error = glGetError()) { std::cout << "Open GL error lel: (0x" << std::hex << error << "): " << file << ": " << function_name << ":" << std::dec << line << std::endl; return false; } return true; } struct ShaderProgramSource { std::string vertexSource; std::string fragmentSource; }; static ShaderProgramSource ParseShader(const std::string& path) { std::fstream stream(path); std::string line; std::stringstream ss[2]; enum { VERTEX = 0, FRAGMENT = 1, NONE = -1 } mode = NONE; while (getline(stream, line)) { if(line.find("#shader") != std::string::npos) { if(line.find("vertex") != std::string::npos) { mode = VERTEX; } else if(line.find("fragment") != std::string::npos) { mode = FRAGMENT; } } else { ss[(int)mode] << line << "\n"; } } return ShaderProgramSource { ss[0].str(), ss[1].str() }; } static GLuint CompileShader(unsigned int type, std::string &source) { GLuint id = glCreateShader(type); const char *src = source.c_str(); glShaderSource(id, 1, &src, nullptr); glCompileShader(id); int result; glGetShaderiv(id, GL_COMPILE_STATUS, &result); if(result == GL_FALSE) { int len; glGetShaderiv(id, GL_INFO_LOG_LENGTH, &len); char *val = new char[len]; glGetShaderInfoLog(id, len, &len, val); std::cout << "You dumb fuck " << val; glDeleteShader(id); return 0; } return id; } static GLuint CreateShader(std::string &vertexShader, std::string &fragmentShader) { GLuint program = glCreateProgram(); GLuint vs = CompileShader(GL_VERTEX_SHADER, vertexShader); GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader); glAttachShader(program, vs); glAttachShader(program, fs); glLinkProgram(program); glValidateProgram(program); glDeleteShader(vs); glDeleteShader(fs); return program; } int main(void) { GLFWwindow* window; /* Initialize the library */ if (!glfwInit()) return -1; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } /* Make the window's context current */ glfwMakeContextCurrent(window); if (glewInit() != GLEW_OK) { std::cout << "Ure fucked\n"; } std::cout << glGetString(GL_VERSION) << std::endl; float positions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5F, 0.5f }; unsigned int indicies[] = { 0, 1, 2, 2, 3, 0 }; GLuint vao; GL_CALL(glGenVertexArrays(1, &vao)); GL_CALL(glBindVertexArray(vao)); GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, 4 * 2 * sizeof(float), positions, GL_STATIC_DRAW); GL_CALL(glEnableVertexAttribArray(0)); GL_CALL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0)); GLuint index_buffer_object; glGenBuffers(1, &index_buffer_object); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_object); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indicies, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); ShaderProgramSource source = ParseShader("../res/shaders/Basic.shader"); GLuint shader = CreateShader(source.vertexSource, source.fragmentSource); glUseProgram(shader); GLuint location = glGetUniformLocation(shader, "u_Color"); ASSERT(location != -1); glUniform4f(location, 0.2f, 0.3f, 1.0f, 1.0f); /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { /* Render here */ /* Swap front and back buffers */ glfwSwapBuffers(window); //glDrawArrays(GL_TRIANGLES, 0, 3); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); /* Poll for and process events */ glfwPollEvents(); } glDeleteProgram(shader); glfwTerminate(); return 0; }