#include #include #include #include #include #include static Display *dpy; static GLXWindow glx_window; static float rotations[10] = { 0.0f, 0.0f, /* rotations[1] from shader should refer to this */ 0.0f, 0.0f, 85.0f, /* but instead it refers to this */ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; static const GLfloat verts[3][2] = { { -0.5, -0.5 }, { 0.5, -0.5 }, { 0, 0.5 } }; static const GLfloat colors[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; static const char *vert_shader_text = "#version 300 es\n\n" "const float pi = 3.14159265358979323846;\n" "layout(std140) uniform my_block\n" "{\n" " float rotations[10];\n" "};\n" "in vec4 pos;\n" "in vec4 color;\n" "out vec4 v_color;\n" "void main() {\n" " float angle = rotations[1]; \n" /* This appears to be 85.0 when should be 0.0 */ " mat4 rotation = mat4 (cos(pi * angle / 180.0), 0.0, sin(pi * angle / 180.0), 0.0,\n" " 0.0, 1.0, 0.0, 0.0,\n" " -sin(pi * angle / 180.0), 0.0, cos(pi * angle / 180.0), 0.0,\n" " 0.0, 0.0, 0.0, 1.0);\n" " gl_Position = rotation * pos;\n" " v_color = color;\n" "}\n"; static const char *frag_shader_text = "#version 300 es\n\n" "in vec4 v_color;\n" "out vec4 color;\n" "void main() {\n" " color = v_color;\n" "}\n"; static GLuint buff[3]; static GLuint frag, vert; static GLuint program; static GLuint create_shader(const char *source, GLenum shader_type) { GLuint shader; GLint status; shader = glCreateShader(shader_type); assert(shader != 0); glShaderSource(shader, 1, (const char **)&source, NULL); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (!status) { printf("Failed to compile shader\n"); exit(1); } return shader; } static void run() { glViewport(0, 0, 640, 480); glClearColor(0.0, 0.0, 0.0, 0.5); glClear(GL_COLOR_BUFFER_BIT); glBindBuffer(GL_ARRAY_BUFFER, buff[0]); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, buff[1]); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glXSwapBuffers(dpy, glx_window); } int main(int argc, char *argv[]) { int config_attribs[] = { GLX_DOUBLEBUFFER, True, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_BUFFER_SIZE, 32, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, None }; static int ctx_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_RENDER_TYPE, GLX_RGBA_TYPE, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, None }; int n; GLXFBConfig *configs; int vID; XVisualInfo *visual, template; XSetWindowAttributes wa; Colormap colormap; Window window; XSizeHints sh; GLXContext ctx; GLint status; GLuint vao; PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB; dpy = XOpenDisplay(NULL); if (!dpy) { printf("Failed to open display\n"); exit(1); } configs = glXChooseFBConfig(dpy, DefaultScreen(dpy), config_attribs, &n); if (n <= 0) { printf("Failed to choose config\n"); exit(1); } if (glXGetFBConfigAttrib(dpy, configs[0], GLX_VISUAL_ID, &vID) != Success) { printf("Failed to get config attrib\n"); exit(1); } template.visualid = vID; if ((visual = XGetVisualInfo(dpy, VisualIDMask, &template, &n)) == NULL) { printf("Failed in XGetVisualInfo\n"); exit(1); } colormap = XCreateColormap(dpy, RootWindow(dpy, DefaultScreen(dpy)), visual->visual, AllocNone); wa.colormap = colormap; wa.background_pixel = 0xFF95FF94; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | ExposureMask; window = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)), 0, 0, 640, 480, 0, visual->depth, InputOutput, visual->visual, CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &wa); if (window == 0) { printf("Couldn't create window\n"); exit(1); } sh.flags = USPosition; sh.x = 0; sh.y = 0; XSetStandardProperties(dpy, window, "std140 bug", "std140 bug", None, 0, 0, &sh); XMapWindow(dpy, window); XSetWMColormapWindows(dpy, window, &window, 1); XFlush(dpy); glx_window = glXCreateWindow(dpy, configs[0], window, NULL); if (!glx_window) { printf("Failed to create GLX surface\n"); exit(1); } glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB("glXCreateContextAttribsARB"); ctx = glXCreateContextAttribsARB(dpy, configs[0], NULL, True, ctx_attribs); if (!ctx) { printf("Failed to create GLX context\n"); exit(1); } if (!glXMakeContextCurrent(dpy, glx_window, glx_window, ctx)) { printf("Failed to make GLX context current\n"); exit(1); } glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(3, buff); glBindBuffer(GL_ARRAY_BUFFER, buff[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, buff[1]); glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, buff[2]); glBufferData(GL_ARRAY_BUFFER, sizeof(rotations), rotations, GL_STATIC_DRAW); frag = create_shader(frag_shader_text, GL_FRAGMENT_SHADER); vert = create_shader(vert_shader_text, GL_VERTEX_SHADER); program = glCreateProgram(); glAttachShader(program, frag); glAttachShader(program, vert); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); if (!status) { printf("Failed to link program\n"); exit(1); } glUseProgram(program); glBindAttribLocation(program, 0, "pos"); glBindAttribLocation(program, 1, "color"); glLinkProgram(program); glUniformBlockBinding(program, 0, 0); glBindBufferBase(GL_UNIFORM_BUFFER, 0, buff[2]); while (1) { run(); } return 0; }