// compile with: // clang++ -g -o main -std=c++11 intel-minimal.cpp -I/path/to/glm -lglfw -lGL -lGLEW // To make it work on intel gpus you either have to change the uniform block // binding to 0 in line 158 or uncomment lines 123+124. #include #include #include #include #include auto vsrc = "#version 330 core\n" "#extension GL_ARB_shading_language_420pack : enable\n" "\n" "struct Constants\n" "{\n" " mat4 scale;\n" " mat4 rot;\n" "};\n" "\n" "layout(binding=2, std140) uniform Data\n" "{\n" " Constants data;\n" "};\n" "\n" "layout (location=0) in vec2 inPos;\n" "\n" "void main() {\n" " gl_Position = data.scale * data.rot * vec4(inPos, 0.0, 1.0);\n" "}\n"; auto fsrc = "#version 330 core\n" "#extension GL_ARB_shading_language_420pack : enable\n" "\n" "out vec4 color0;\n" "\n" "void main() {\n" " color0 = vec4(1,1,1,1);\n" "}\n"; struct Constants { glm::mat4 scale; glm::mat4 rot; }; int main() { // init glfw glfwInit(); glfwDefaultWindowHints(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); GLFWwindow *wnd = glfwCreateWindow(800, 600, "Test", nullptr, nullptr); glfwMakeContextCurrent(wnd); glewExperimental = GL_TRUE; glewInit(); glfwSwapInterval(1); glClearColor(0,0,0,1); // load shaders std::cout << "Vertex shader:\n" << vsrc << "\n\n" << std::endl; std::cout << "Fragment shader:\n" << fsrc << "\n\n" << std::endl; GLuint vs, fs, prog; vs = glCreateShader(GL_VERTEX_SHADER); fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vs, 1, &vsrc, nullptr); glShaderSource(fs, 1, &fsrc, nullptr); glCompileShader(vs); glCompileShader(fs); auto pbl = [](GLuint s) { GLint status, logSize; glGetShaderiv(s, GL_COMPILE_STATUS, &status); glGetShaderiv(s, GL_INFO_LOG_LENGTH, &logSize); if(logSize) { std::string log(logSize, 0); glGetShaderInfoLog(s, (GLsizei)log.size(), nullptr, &log[0]); std::cout << (status ? "Build info:" : "BUILD ERRORS:") << std::endl; std::cout << log << std::endl; } }; pbl(vs); pbl(fs); prog = glCreateProgram(); glAttachShader(prog, vs); glAttachShader(prog, fs); glLinkProgram(prog); auto pll = [](GLuint p) { GLint status, logSize; glGetProgramiv(p, GL_LINK_STATUS, &status); glGetProgramiv(p, GL_INFO_LOG_LENGTH, &logSize); if(logSize) { std::string log(logSize, 0); glGetProgramInfoLog(p, (GLsizei)log.size(), nullptr, &log[0]); std::cout << (status ? "Link info:" : "LINK ERRORS:") << std::endl; std::cout << log << std::endl; } }; pll(prog); // DOESN'T WORK WITHOUT THIS: //GLuint idx = glGetUniformBlockIndex(prog, "Data"); //glUniformBlockBinding(prog, idx, 2); // create quad float quad[] = {-1,1, -1,-1, 1,-1, -1,1, 1,-1, 1,1}; GLuint vb, vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vb); glBindBuffer(GL_ARRAY_BUFFER, vb); glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr); glBindVertexArray(0); // create uniform buffer GLuint ub; glGenBuffers(1, &ub); glBindBuffer(GL_UNIFORM_BUFFER, ub); glBufferData(GL_UNIFORM_BUFFER, sizeof(Constants), nullptr, GL_STATIC_DRAW); // main loop while(glfwWindowShouldClose(wnd) == 0) { glfwPollEvents(); // update uniform buffer { Constants c; c.scale = glm::scale(glm::vec3(0.5f, 0.5f, 0.5f)); c.rot = glm::eulerAngleZ(glfwGetTime()); glBindBufferBase(GL_UNIFORM_BUFFER, 2, ub); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(c), &c); } // render quad glClear(GL_COLOR_BUFFER_BIT); glUseProgram(prog); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); glfwSwapBuffers(wnd); } return 0; }