// g++ main.cpp -o main -W -Wall -pedantic `pkg-config --cflags --libs glfw3 gl` -std=c++14 -DGL_GLEXT_PROTOTYPES -g #include #include #include #include #include using namespace std; string vsSrc = "#version 150 core\n" "\n" "out vec3 color;\n" "\n" "struct Color {\n" " vec3 rgb;\n" " float k;\n" "};\n" "\n" "layout (std140) uniform Colors {\n" " Color colors[3];\n" "};\n" "\n" "vec2 co[3] = vec2[](\n" " vec2(-.5,-.5)\n" " , vec2( 0., .5)\n" " , vec2( .5,-.5)\n" " );\n" "\n" "void main() {\n" " gl_Position = vec4(co[gl_VertexID], 0., 1.);\n" " color = colors[gl_VertexID].rgb * colors[gl_VertexID].k;\n" "}"; string fsSrc = "#version 150 core\n" "in vec3 color;\n" "out vec4 frag;\n" "void main() {\n" " frag = vec4(color, 1.);\n" "}"; template struct V3 { T x; T y; T z; V3() {} V3(float x0, float y0, float z0) : x(x0), y(y0), z(z0) {} }; struct Color { V3 rgb; float k; Color(V3 rgb0 = V3(1.f, 1.f, 1.f), float k0 = 1.f) : rgb(rgb0), k(k0) {} }; int main() { if (!glfwInit()) return 1; cout << sizeof(Color) << endl; cout << offsetof(Color,k) << endl; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); auto window = glfwCreateWindow(800, 600, "Test", NULL, NULL); if (!window) { cerr << "unable to create window" << endl; glfwTerminate(); return 2; } glfwMakeContextCurrent(window); // vao stuff GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindVertexArray(0); // shader stuff GLuint vs, fs, sp; GLint info; vs = glCreateShader(GL_VERTEX_SHADER); fs = glCreateShader(GL_FRAGMENT_SHADER); sp = glCreateProgram(); auto src = vsSrc.c_str(); glShaderSource(vs, 1, &src, NULL); glCompileShader(vs); glGetShaderiv(vs, GL_COMPILE_STATUS, &info); if (info == GL_FALSE) { cerr << "failed to compile vertex shader" << endl; glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &info); GLchar *log = new char[info + 1]; glGetShaderInfoLog(vs, info, NULL, log); cerr << log << endl; delete[] log; return 3; } glAttachShader(sp, vs); src = fsSrc.c_str(); glShaderSource(fs, 1, &src, NULL); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &info); if (info == GL_FALSE) { cerr << "failed to compile fragment shader" << endl; glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &info); GLchar *log = new char[info + 1]; glGetShaderInfoLog(fs, info, NULL, log); cerr << log << endl; delete[] log; return 3; } glAttachShader(sp, fs); glLinkProgram(sp); glGetProgramiv(sp, GL_LINK_STATUS, &info); if (info == GL_FALSE) { cerr << "failed to link shader program" << endl; return 4; } glUseProgram(sp); // UBO stuff auto red = Color(V3(1, 0, 0)); auto green = Color(V3(0, 1, 0)); auto blue = Color(V3(0, 0, 1)); Color colors[3] = { Color(red), Color(green), Color(blue) }; GLuint ubo; glGenBuffers(1, &ubo); glBindBuffer(GL_ARRAY_BUFFER, ubo); glBufferData(GL_ARRAY_BUFFER, sizeof(Color) * 3, colors, GL_STREAM_DRAW); auto block = glGetUniformBlockIndex(sp, "Colors"); if (block == GL_INVALID_INDEX) { cerr << "inactive uniform block" << endl; return 5; } glUniformBlockBinding(sp, block, 0); glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 0, sizeof(Color) * 3); glBindVertexArray(vao); while (!glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteBuffers(1, &ubo); glDeleteProgram(sp); glDeleteShader(fs); glDeleteShader(vs); glDeleteVertexArrays(1, &vao); glfwTerminate(); return 0; }