diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_draw.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 184 |
1 files changed, 91 insertions, 93 deletions
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 77ffa46b990..3c176912409 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -57,8 +57,7 @@ #include "GPU_draw.h" #include "GPU_extensions.h" -#include "GPU_glew.h" -#include "GPU_basic_shader.h" +#include "GPU_immediate.h" #include "RE_engine.h" @@ -128,7 +127,7 @@ static bool wm_area_test_invalid_backbuf(ScrArea *sa) if (sa->spacetype == SPACE_VIEW3D) return (((View3D *)sa->spacedata.first)->flag & V3D_INVALID_BACKBUF) != 0; else - return 1; + return true; } static void wm_region_test_render_do_draw(bScreen *screen, ScrArea *sa, ARegion *ar) @@ -372,118 +371,116 @@ static void wm_draw_triple_fail(bContext *C, wmWindow *win) { wm_draw_window_clear(win); - win->drawfail = 1; + win->drawfail = true; wm_method_draw_overlap_all(C, win, 0); } -static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) +static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) { - const int winsize_x = WM_window_pixels_x(win); - const int winsize_y = WM_window_pixels_y(win); - - GLint maxsize; - /* compute texture sizes */ - if (GLEW_ARB_texture_rectangle || GLEW_NV_texture_rectangle || GLEW_EXT_texture_rectangle) { - triple->target = GL_TEXTURE_RECTANGLE_ARB; - } - else { - triple->target = GL_TEXTURE_2D; - } - - triple->x = winsize_x; - triple->y = winsize_y; + triple->x = WM_window_pixels_x(win); + triple->y = WM_window_pixels_y(win); + +#if USE_TEXTURE_RECTANGLE + /* GL_TEXTURE_RECTANGLE is part of GL 3.1 so we can use it soon without runtime checks */ + triple->target = GL_TEXTURE_RECTANGLE; +#else + triple->target = GL_TEXTURE_2D; +#endif /* generate texture names */ glGenTextures(1, &triple->bind); - if (!triple->bind) { - /* not the typical failure case but we handle it anyway */ - printf("WM: failed to allocate texture for triple buffer drawing (glGenTextures).\n"); - return 0; - } - /* proxy texture is only guaranteed to test for the cases that * there is only one texture in use, which may not be the case */ - maxsize = GPU_max_texture_size(); + const GLint maxsize = GPU_max_texture_size(); if (triple->x > maxsize || triple->y > maxsize) { - glBindTexture(triple->target, 0); printf("WM: failed to allocate texture for triple buffer drawing " - "(texture too large for graphics card).\n"); - return 0; + "(texture too large for graphics card).\n"); + return false; } /* setup actual texture */ glBindTexture(triple->target, triple->bind); - glTexImage2D(triple->target, 0, GL_RGB8, triple->x, triple->y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + + /* no mipmaps */ +#if USE_TEXTURE_RECTANGLE + /* already has no mipmaps */ +#else + glTexParameteri(triple->target, GL_TEXTURE_MAX_LEVEL, 0); + /* GL_TEXTURE_BASE_LEVEL = 0 by default */ +#endif + glTexParameteri(triple->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(triple->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindTexture(triple->target, 0); - /* not sure if this works everywhere .. */ - if (glGetError() == GL_OUT_OF_MEMORY) { - printf("WM: failed to allocate texture for triple buffer drawing (out of memory).\n"); - return 0; - } + glTexImage2D(triple->target, 0, GL_RGB8, triple->x, triple->y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + + glBindTexture(triple->target, 0); - return 1; + return true; } -void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha, bool is_interlace) +void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha) { const int sizex = WM_window_pixels_x(win); const int sizey = WM_window_pixels_y(win); - float halfx, halfy, ratiox, ratioy; - /* wmOrtho for the screen has this same offset */ - ratiox = sizex; - ratioy = sizey; - halfx = GLA_PIXEL_OFS; - halfy = GLA_PIXEL_OFS; + float ratiox = sizex; + float ratioy = sizey; + float halfx = GLA_PIXEL_OFS; + float halfy = GLA_PIXEL_OFS; +#if USE_TEXTURE_RECTANGLE /* texture rectangle has unnormalized coordinates */ - if (triple->target == GL_TEXTURE_2D) { - ratiox /= triple->x; - ratioy /= triple->y; - halfx /= triple->x; - halfy /= triple->y; - } +#else + ratiox /= triple->x; + ratioy /= triple->y; + halfx /= triple->x; + halfy /= triple->y; +#endif - /* interlace stereo buffer bind the shader before calling wm_triple_draw_textures */ - if (is_interlace) { - glEnable(triple->target); - } - else { - GPU_basic_shader_bind((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_TEXTURE_2D : GPU_SHADER_TEXTURE_RECT); - } + VertexFormat *format = immVertexFormat(); + unsigned int texcoord = VertexFormat_add_attrib(format, "texCoord", COMP_F32, 2, KEEP_FLOAT); + unsigned int pos = VertexFormat_add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT); + const int activeTex = 7; /* arbitrary */ + glActiveTexture(GL_TEXTURE0 + activeTex); glBindTexture(triple->target, triple->bind); - glColor4f(1.0f, 1.0f, 1.0f, alpha); - glBegin(GL_QUADS); - glTexCoord2f(halfx, halfy); - glVertex2f(0, 0); +#if USE_TEXTURE_RECTANGLE + immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA); +#else + immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA); + /* TODO: make pure 2D version + * and a 2D_IMAGE (replace, not modulate) version for when alpha = 1.0 + */ +#endif + immUniform1f("alpha", alpha); + immUniform1i("image", activeTex); - glTexCoord2f(ratiox + halfx, halfy); - glVertex2f(sizex, 0); + immBegin(PRIM_TRIANGLE_FAN, 4); - glTexCoord2f(ratiox + halfx, ratioy + halfy); - glVertex2f(sizex, sizey); + immAttrib2f(texcoord, halfx, halfy); + immVertex2f(pos, 0.0f, 0.0f); - glTexCoord2f(halfx, ratioy + halfy); - glVertex2f(0, sizey); - glEnd(); + immAttrib2f(texcoord, ratiox + halfx, halfy); + immVertex2f(pos, sizex, 0.0f); - glBindTexture(triple->target, 0); + immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy); + immVertex2f(pos, sizex, sizey); - if (is_interlace) { - glDisable(triple->target); - } - else { - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } + immAttrib2f(texcoord, halfx, ratioy + halfy); + immVertex2f(pos, 0.0f, sizey); + + immEnd(); + immUnbindProgram(); + + glBindTexture(triple->target, 0); + if (activeTex != 0) + glActiveTexture(GL_TEXTURE0); } static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) @@ -492,8 +489,8 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) const int sizey = WM_window_pixels_y(win); glBindTexture(triple->target, triple->bind); + /* what is GL_READ_BUFFER right now? */ glCopyTexSubImage2D(triple->target, 0, 0, 0, 0, 0, sizex, sizey); - glBindTexture(triple->target, 0); } @@ -506,7 +503,7 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *tripl wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct, true); glEnable(GL_BLEND); - wm_triple_draw_textures(win, triple, 1.0f - fac, false); + wm_triple_draw_textures(win, triple, 1.0f - fac); glDisable(GL_BLEND); } } @@ -514,20 +511,21 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *tripl static void wm_method_draw_triple(bContext *C, wmWindow *win) { wmWindowManager *wm = CTX_wm_manager(C); - wmDrawTriple *triple; wmDrawData *dd, *dd_next, *drawdata = win->drawdata.first; bScreen *screen = win->screen; ScrArea *sa; ARegion *ar; - int copytex = false; + bool copytex = false; if (drawdata && drawdata->triple) { - glClearColor(0, 0, 0, 0); +#if 0 /* why do we need to clear before overwriting? */ + glClearColor(1, 1, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#endif wmSubWindowSet(win, screen->mainwin); - wm_triple_draw_textures(win, drawdata->triple, 1.0f, false); + wm_triple_draw_textures(win, drawdata->triple, 1.0f); } else { /* we run it when we start OR when we turn stereo on */ @@ -554,7 +552,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) MEM_freeN(dd); } - triple = drawdata->triple; + wmDrawTriple *triple = drawdata->triple; /* draw marked area regions */ for (sa = screen->areabase.first; sa; sa = sa->next) { @@ -562,7 +560,6 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { - if (ar->overlap == false) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); @@ -662,12 +659,14 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, StereoVi if (drawdata && drawdata->triple) { if (id == 0) { +#if 0 /* why do we need to clear before overwriting? */ glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#endif wmSubWindowSet(win, screen->mainwin); - wm_triple_draw_textures(win, drawdata->triple, 1.0f, false); + wm_triple_draw_textures(win, drawdata->triple, 1.0f); } } else { @@ -849,20 +848,20 @@ static bool wm_draw_update_test_window(wmWindow *win) } if (do_draw) - return 1; + return true; if (win->screen->do_refresh) - return 1; + return true; if (win->screen->do_draw) - return 1; + return true; if (win->screen->do_draw_gesture) - return 1; + return true; if (win->screen->do_draw_paintcursor) - return 1; + return true; if (win->screen->do_draw_drag) - return 1; + return true; - return 0; + return false; } static int wm_automatic_draw_method(wmWindow *win) @@ -916,7 +915,6 @@ void wm_draw_update(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; - int drawmethod; #ifdef WITH_OPENSUBDIV BKE_subsurf_free_unused_buffers(); @@ -952,7 +950,7 @@ void wm_draw_update(bContext *C) if (win->screen->do_refresh) ED_screen_refresh(wm, win); - drawmethod = wm_automatic_draw_method(win); + int drawmethod = wm_automatic_draw_method(win); if (win->drawfail) wm_method_draw_overlap_all(C, win, 0); |