/* * OpenHMD - Free and Open Source API and drivers for immersive technology. * Copyright (C) 2013 Fredrik Hultin. * Copyright (C) 2013 Jakob Bornecrantz. * Distributed under the Boost 1.0 licence, see LICENSE for full text. */ /* OpenGL Test - GL Helper Functions Implementation */ #include "gl.h" #include #include #include #include #include #include #include "context.inl" #ifdef __unix #include #endif #ifndef M_PI #define M_PI 3.14159265359 #endif const uint32_t xcb_window_attrib_mask = XCB_CW_EVENT_MASK; const uint32_t xcb_window_attrib_list[] = { XCB_EVENT_MASK_BUTTON_PRESS, XCB_EVENT_MASK_EXPOSURE, XCB_EVENT_MASK_KEY_PRESS, }; void CreateWindow(const char *display_name, int window_x, int window_y, int window_width, int window_height, xcb_connection_t** out_connection, int* out_screen, xcb_window_t* out_window) { xcb_generic_error_t* error; //int iscreen; xcb_connection_t *connection = xcb_connect(NULL, NULL); if (!connection) exit(-1); if (xcb_connection_has_error(connection)) exit(-1); const xcb_setup_t* setup = xcb_get_setup(connection); xcb_screen_t* screen = xcb_setup_roots_iterator(setup).data; assert(screen != 0); xcb_window_t window = xcb_generate_id(connection); if (window <= 0) exit(-1); xcb_void_cookie_t create_cookie = xcb_create_window_checked( connection, XCB_COPY_FROM_PARENT, // depth window, screen->root, // parent window window_x, window_y, window_width, window_height, 0, // border width XCB_WINDOW_CLASS_INPUT_OUTPUT, // class screen->root_visual, // visual xcb_window_attrib_mask, xcb_window_attrib_list); xcb_void_cookie_t map_cookie = xcb_map_window_checked(connection, window); // Check errors. error = xcb_request_check(connection, create_cookie); if (error) exit(-1); error = xcb_request_check(connection, map_cookie); if (error) exit(-1); *out_connection = connection; *out_window = window; } static const EGLint egl_config_attribs[] = { //EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, //EGL_BUFFER_SIZE, 32, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, //EGL_DEPTH_SIZE, 24, //EGL_STENCIL_SIZE, 8, //EGL_SAMPLE_BUFFERS, 0, //EGL_SAMPLES, 0, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE, }; static const EGLint egl_context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; static const EGLint egl_surface_attribs[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE, }; void init_gl(gl_ctx* ctx, int w, int h) { memset(ctx, 0, sizeof(gl_ctx)); const char *x_display_name = NULL; CreateWindow(x_display_name, 0, 0, // x, y w, h, // width, height &ctx->x_connection, &ctx->x_screen, &ctx->x_window); if(ctx->x_window == NULL) { printf("CreateWindow failed\n"); exit(-1); } ctx->w = w; ctx->h = h; ctx->is_fullscreen = 0; bool bContextCreated = create_context(EGL_PLATFORM_X11_KHR, EGL_DEFAULT_DISPLAY, ctx->x_window, egl_config_attribs, egl_context_attribs, egl_surface_attribs, &ctx->egl_display, &ctx->egl_context, &ctx->egl_surface); if(!bContextCreated || ctx->egl_context == EGL_NO_CONTEXT) { printf("CreateContext failed\n"); exit(-1); } // Disable ctrl-c catching on Linux (and OS X?) #ifdef __unix signal(SIGINT, SIG_DFL); #endif printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER)); printf("OpenGL Vendor: %s\n", glGetString(GL_VENDOR)); printf("OpenGL Version: %s\n", glGetString(GL_VERSION)); // == Initialize OpenGL == glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glLoadIdentity(); glShadeModel(GL_SMOOTH); glDisable(GL_DEPTH_TEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glEnable(GL_POLYGON_SMOOTH); glLoadIdentity(); glViewport(0, 0, ctx->w, ctx->h); } void ortho(gl_ctx* ctx) { glMatrixMode(GL_PROJECTION); //glPushMatrix(); glLoadIdentity(); glOrtho(0.0f, ctx->w, ctx->h, 0.0f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); //glPushMatrix(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH); glDisable(GL_MULTISAMPLE); } void draw_cube() { glBegin(GL_QUADS); glVertex3f( 0.5f, 0.5f, -0.5f); /* Top Right Of The Quad (Top) */ glVertex3f( -0.5f, 0.5f, -0.5f); /* Top Left Of The Quad (Top) */ glVertex3f( -0.5f, 0.5f, 0.5f); /* Bottom Left Of The Quad (Top) */ glVertex3f( 0.5f, 0.5f, 0.5f); /* Bottom Right Of The Quad (Top) */ glVertex3f( 0.5f, -0.5f, 0.5f); /* Top Right Of The Quad (Botm) */ glVertex3f( -0.5f, -0.5f, 0.5f); /* Top Left Of The Quad (Botm) */ glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Botm) */ glVertex3f( 0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Botm) */ glVertex3f( 0.5f, 0.5f, 0.5f); /* Top Right Of The Quad (Front) */ glVertex3f( -0.5f, 0.5f, 0.5f); /* Top Left Of The Quad (Front) */ glVertex3f( -0.5f, -0.5f, 0.5f); /* Bottom Left Of The Quad (Front) */ glVertex3f( 0.5f, -0.5f, 0.5f); /* Bottom Right Of The Quad (Front) */ glVertex3f( 0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Back) */ glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Back) */ glVertex3f( -0.5f, 0.5f, -0.5f); /* Top Right Of The Quad (Back) */ glVertex3f( 0.5f, 0.5f, -0.5f); /* Top Left Of The Quad (Back) */ glVertex3f( -0.5f, 0.5f, 0.5f); /* Top Right Of The Quad (Left) */ glVertex3f( -0.5f, 0.5f, -0.5f); /* Top Left Of The Quad (Left) */ glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Left) */ glVertex3f( -0.5f, -0.5f, 0.5f); /* Bottom Right Of The Quad (Left) */ glVertex3f( 0.5f, 0.5f, -0.5f); /* Top Right Of The Quad (Right) */ glVertex3f( 0.5f, 0.5f, 0.5f); /* Top Left Of The Quad (Right) */ glVertex3f( 0.5f, -0.5f, 0.5f); /* Bottom Left Of The Quad (Right) */ glVertex3f( 0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Right) */ glEnd(); } static void compile_shader_src(GLuint shader, const char* src) { glShaderSource(shader, 1, &src, NULL); glCompileShader(shader); GLint status; GLint length; char log[4096] = {0}; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); glGetShaderInfoLog(shader, 4096, &length, log); if(status == GL_FALSE){ printf("compile failed %s\n", log); } } GLuint compile_shader(const char* vertex, const char* fragment) { // Create the handels GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); GLuint programShader = glCreateProgram(); // Attach the shaders to a program handel. glAttachShader(programShader, vertexShader); glAttachShader(programShader, fragmentShader); // Load and compile the Vertex Shader compile_shader_src(vertexShader, vertex); // Load and compile the Fragment Shader compile_shader_src(fragmentShader, fragment); // The shader objects are not needed any more, // the programShader is the complete shader to be used. glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glLinkProgram(programShader); GLint status; GLint length; char log[4096] = {0}; glGetProgramiv(programShader, GL_LINK_STATUS, &status); glGetProgramInfoLog(programShader, 4096, &length, log); if(status == GL_FALSE){ printf("link failed %s\n", log); } return programShader; } void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint color_tex, GLuint* depth_tex) { glGenTextures(1, depth_tex); glGenFramebuffers(1, fbo); glBindTexture(GL_TEXTURE_2D, *depth_tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, eye_width, eye_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_FRAMEBUFFER_EXT, *fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_tex, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depth_tex, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); if(status != GL_FRAMEBUFFER_COMPLETE_EXT){ printf("failed to create fbo %x\n", status); } glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); }