static void ogl_unlock_region_backbuffer(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y) { const int lock_format = bitmap->locked_region.format; bool popmatrix = false; GLenum e; GLint program = 0; ALLEGRO_DISPLAY *display = al_get_current_display(); if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { // FIXME: This is a hack where we temporarily disable the active shader. // It will only work on Desktop OpenGL in non-strict mode where we even // can switch back to the fixed pipeline. The correct way would be to not // use any OpenGL 2 functions (like glDrawPixels). Probably we will want // separate OpenGL <= 2 (including OpenGL ES 1) and OpenGL >= 3 (including // OpenGL ES >= 2) drivers at some point. glGetIntegerv(GL_CURRENT_PROGRAM, &program); glUseProgram(0); } /* glWindowPos2i may not be available. */ if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_1_4) { glWindowPos2i(bitmap->lock_x, gl_y); } else { /* glRasterPos is affected by the current modelview and projection * matrices (so maybe we actually need to reset both of them?). * The coordinate is also clipped; the small offset was required to * prevent it being culled on one of my machines. --pw * * Consider using glWindowPos2fMESAemulate from: * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ */ glPushMatrix(); glLoadIdentity(); glRasterPos2f(bitmap->lock_x, bitmap->lock_y + bitmap->lock_h - 1e-4f); popmatrix = true; } glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDrawPixels(bitmap->lock_w, bitmap->lock_h, get_glformat(lock_format, 2), get_glformat(lock_format, 1), ogl_bitmap->lock_buffer); e = glGetError(); if (e) { ALLEGRO_ERROR("glDrawPixels for format %s failed (%s).\n", _al_pixel_format_name(lock_format), _al_gl_error_string(e)); } if (popmatrix) { glPopMatrix(); } if (program != 0) { glUseProgram(program); } }
static bool set_opengl_blending(ALLEGRO_DISPLAY *d) { const int blend_modes[4] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }; const int blend_equations[3] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; (void)d; al_get_separate_blender(&op, &src_color, &dst_color, &op_alpha, &src_alpha, &dst_alpha); #if defined ALLEGRO_IPHONE || defined ALLEGRO_GP2XWIZ if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_2_0) { glEnable(GL_BLEND); glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); return true; } else { glEnable(GL_BLEND); glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); glBlendEquation(blend_equations[op]); return true; } #else if (d->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) { glEnable(GL_BLEND); glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); if (d->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); } else glBlendEquation(blend_equations[op]); return true; } else { if (src_color == src_alpha && dst_color == dst_alpha) { glEnable(GL_BLEND); glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); glBlendEquation(blend_equations[op]); return true; } } #endif return false; }
int main (int argc, char **argv) { g_type_init (); al_init (); al_init_image_addon (); al_set_new_display_option (ALLEGRO_RED_SIZE, 8, ALLEGRO_REQUIRE); al_set_new_display_option (ALLEGRO_GREEN_SIZE, 8, ALLEGRO_REQUIRE); al_set_new_display_option (ALLEGRO_BLUE_SIZE, 8, ALLEGRO_REQUIRE); al_set_new_display_option (ALLEGRO_ALPHA_SIZE, 8, ALLEGRO_REQUIRE); /* Nouveau = good */ /* al_set_new_display_option (ALLEGRO_AUX_BUFFERS, 4, ALLEGRO_REQUIRE); */ al_set_new_display_flags (ALLEGRO_WINDOWED | ALLEGRO_OPENGL); ALLEGRO_DISPLAY *disp; disp = al_create_display (640, 480); xassert (disp); g_xassert (al_get_opengl_extension_list ()->ALLEGRO_GL_ARB_depth_texture); g_xassert (al_get_opengl_extension_list ()->ALLEGRO_GL_ARB_framebuffer_object); al_set_target_backbuffer (disp); printf ("OPENGL %x\n", al_get_opengl_version ()); blender_bmp = al_load_bitmap ("../data/n1img0.bmp"); g_xassert (640 == al_get_bitmap_width (blender_bmp) && 480 == al_get_bitmap_height (blender_bmp)); blender_tex = al_get_opengl_texture (blender_bmp); g_xassert (blender_tex); GLint glvar; /* Query GL_MAX_DRAW_BUFFERS, GL_MAX_COLOR_ATTACHMENTS */ glGetIntegerv (GL_MAX_DRAW_BUFFERS, &glvar); xassert (4 <= glvar); glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &glvar); xassert (4 <= glvar); derp (); al_flip_display (); al_rest (2); return EXIT_SUCCESS; }
static void ogl_unlock_region_backbuffer(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y) { const int lock_format = bitmap->locked_region.format; bool popmatrix = false; GLenum e; /* glWindowPos2i may not be available. */ if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_1_4) { glWindowPos2i(bitmap->lock_x, gl_y); } else { /* glRasterPos is affected by the current modelview and projection * matrices (so maybe we actually need to reset both of them?). * The coordinate is also clipped; the small offset was required to * prevent it being culled on one of my machines. --pw * * Consider using glWindowPos2fMESAemulate from: * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ */ glPushMatrix(); glLoadIdentity(); glRasterPos2f(bitmap->lock_x, bitmap->lock_y + bitmap->lock_h - 1e-4f); popmatrix = true; } glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDrawPixels(bitmap->lock_w, bitmap->lock_h, get_glformat(lock_format, 2), get_glformat(lock_format, 1), ogl_bitmap->lock_buffer); e = glGetError(); if (e) { ALLEGRO_ERROR("glDrawPixels for format %s failed (%s).\n", _al_format_name(lock_format), _al_gl_error_string(e)); } if (popmatrix) { glPopMatrix(); } }
static bool _ogl_is_extension_supported(const char *extension, ALLEGRO_DISPLAY *disp) { int ret = 0; GLubyte const *ext_str; #if !defined ALLEGRO_IPHONE && !defined ALLEGRO_ANDROID int v = al_get_opengl_version(); #endif (void)disp; #if defined ALLEGRO_GP2XWIZ return false; #endif #if !defined ALLEGRO_IPHONE && !defined ALLEGRO_ANDROID if (disp->flags & ALLEGRO_OPENGL_3_0 || v >= _ALLEGRO_OPENGL_VERSION_3_0) { int i; GLint ext_cnt; glGetIntegerv(GL_NUM_EXTENSIONS, &ext_cnt); for (i = 0; i < ext_cnt; i++) { ext_str = glGetStringi(GL_EXTENSIONS, i); if (ext_str && !strcmp(extension, (char*)ext_str)) { ret = 1; break; } } } else #endif { ext_str = glGetString(GL_EXTENSIONS); if (!ext_str) return false; ret = _al_ogl_look_for_an_extension(extension, ext_str); } #ifdef ALLEGRO_WINDOWS if (!ret && strncmp(extension, "WGL", 3) == 0) { ALLEGRO_DISPLAY_WGL *wgl_disp = (void*)disp; _ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB; if (!wgl_disp->dc) return false; _wglGetExtensionsStringARB = (void *) wglGetProcAddress("wglGetExtensionsStringARB"); if (_wglGetExtensionsStringARB) { ret = _al_ogl_look_for_an_extension(extension, (const GLubyte *) _wglGetExtensionsStringARB(wgl_disp->dc)); } } #elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX if (!ret && strncmp(extension, "GLX", 3) == 0) { ALLEGRO_SYSTEM_XGLX *sys = (void*)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx_disp = (void*)disp; char const *ext; if (!sys->gfxdisplay) return false; ext = glXQueryExtensionsString(sys->gfxdisplay, glx_disp->xscreen); if (!ext) { /* work around driver bugs? */ ext = ""; } ret = _al_ogl_look_for_an_extension(extension, (const GLubyte *)ext); } #endif return ret; }