Commit: 8327795f8db13b4a66ba70c4bc01091bab1d847b
Author: Mike Erwin
Date:   Mon Oct 17 20:33:59 2016 -0400
Branches: blender2.8
https://developer.blender.org/rB8327795f8db13b4a66ba70c4bc01091bab1d847b

OpenGL: draw image empties with new API

This extensive rewrite caches the image texture in VRAM. Can handle images up 
to OpenGL limits (8K or 16K).

Part of T49043 & T49450

===================================================================

M       source/blender/editors/space_view3d/drawobject.c

===================================================================

diff --git a/source/blender/editors/space_view3d/drawobject.c 
b/source/blender/editors/space_view3d/drawobject.c
index 9472624..408d27e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -633,92 +633,104 @@ void drawaxes(const float viewmat_local[4][4], float 
size, char drawtype)
 static void draw_empty_image(Object *ob, const short dflag, const unsigned 
char ob_wire_col[4])
 {
        Image *ima = ob->data;
-       ImBuf *ibuf = BKE_image_acquire_ibuf(ima, ob->iuser, NULL);
 
-       if (ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) {
-               IMB_rect_from_float(ibuf);
-       }
+       const float ob_alpha = ob->col[3];
+       float width, height;
 
-       int ima_x, ima_y;
+       const int texUnit = GL_TEXTURE0;
+       int bindcode = 0;
 
-       /* Get the buffer dimensions so we can fallback to fake ones */
-       if (ibuf && ibuf->rect) {
-               ima_x = ibuf->x;
-               ima_y = ibuf->y;
+       if (ima) {
+               if (ob_alpha > 0.0f) {
+                       glActiveTexture(texUnit);
+                       bindcode = GPU_verify_image(ima, ob->iuser, 
GL_TEXTURE_2D, 0, false, false, false);
+                       /* don't bother drawing the image if alpha = 0 */
+               }
+
+               int w, h;
+               BKE_image_get_size(ima, ob->iuser, &w, &h);
+               width = w;
+               height = h;
        }
        else {
-               ima_x = 1;
-               ima_y = 1;
+               /* if no image, make it a 1x1 empty square, honor scale & 
offset */
+               width = height = 1.0f;
        }
 
-       float sca_x = 1.0f;
-       float sca_y = 1.0f;
+       const float aspect = height / width;
 
-       /* Get the image aspect even if the buffer is invalid */
-       if (ima) {
-               if (ima->aspx > ima->aspy) {
-                       sca_y = ima->aspy / ima->aspx;
-               }
-               else if (ima->aspx < ima->aspy) {
-                       sca_x = ima->aspx / ima->aspy;
-               }
-       }
+       float left = ob->ima_ofs[0];
+       float right = ob->ima_ofs[0] + ob->empty_drawsize;
+       float top = ob->ima_ofs[1] + ob->empty_drawsize * aspect;
+       float bottom = ob->ima_ofs[1];
 
-       /* Calculate the scale center based on object's origin */
-       float ofs_x = ob->ima_ofs[0] * ima_x;
-       float ofs_y = ob->ima_ofs[1] * ima_y;
+       bool use_blend = false;
 
-       glMatrixMode(GL_MODELVIEW);
-       glPushMatrix();
+       if (bindcode) {
+               use_blend = ob_alpha < 1.0f || BKE_image_has_alpha(ima);
 
-       /* Calculate Image scale */
-       float scale = ob->empty_drawsize / max_ff((float)ima_x * sca_x, 
(float)ima_y * sca_y);
+               if (use_blend) {
+                       glEnable(GL_BLEND);
+                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               }
 
-       /* Set the object scale */
-       glScalef(scale * sca_x, scale * sca_y, 1.0f);
+               VertexFormat *format = immVertexFormat();
+               unsigned pos = add_attrib(format, "position", GL_FLOAT, 2, 
KEEP_FLOAT);
+               unsigned texCoord = add_attrib(format, "texcoord", GL_FLOAT, 2, 
KEEP_FLOAT);
+               immBindBuiltinProgram(GPU_SHADER_2D_TEXTURE_2D); /* TODO: 
rename GPU_SHADER_3D_IMAGE_2D_MODULATE_ALPHA */
+               immUniform1f("alpha", ob_alpha);
+               immUniform1i("texture_map", texUnit); /* TODO: rename "image" */
 
-       if (ibuf && ibuf->rect) {
-               const bool use_clip = (U.glalphaclip != 1.0f);
-               int zoomfilter = (U.gameflags & USER_DISABLE_MIPMAP) ? 
GL_NEAREST : GL_LINEAR;
-               /* Setup GL params */
-               glEnable(GL_BLEND);
-               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               immBegin(GL_TRIANGLE_FAN, 4);
+               immAttrib2f(texCoord, 0.0f, 0.0f);
+               immVertex2f(pos, left, bottom);
 
-               if (use_clip) {
-                       glEnable(GL_ALPHA_TEST);
-                       glAlphaFunc(GL_GREATER, U.glalphaclip);
-               }
+               immAttrib2f(texCoord, 1.0f, 0.0f);
+               immVertex2f(pos, right, bottom);
 
-               /* Use the object color and alpha */
-               glColor4fv(ob->col);
+               immAttrib2f(texCoord, 1.0f, 1.0f);
+               immVertex2f(pos, right, top);
 
-               /* Draw the Image on the screen */
-               glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, 
GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect);
+               immAttrib2f(texCoord, 0.0f, 1.0f);
+               immVertex2f(pos, left, top);
+               immEnd();
 
-               glDisable(GL_BLEND);
+               immUnbindProgram();
 
-               if (use_clip) {
-                       glDisable(GL_ALPHA_TEST);
-                       glAlphaFunc(GL_ALWAYS, 0.0f);
-               }
+               glBindTexture(GL_TEXTURE_2D, 0); /* necessary? */
        }
 
-       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-               glColor3ubv(ob_wire_col);
+       /* Draw the image outline */
+       glLineWidth(1.5f);
+       unsigned pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 2, 
KEEP_FLOAT);
+
+       const bool picking = dflag & DRAW_CONSTCOLOR;
+       if (picking) {
+               /* TODO: deal with picking separately, use this function just 
to draw */
+               immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
+               if (use_blend) {
+                       glDisable(GL_BLEND);
+               }
+
+               imm_draw_line_box(pos, left, bottom, right, top);
        }
+       else {
+               immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+               immUniformColor3ubv(ob_wire_col);
+               glEnable(GL_LINE_SMOOTH);
 
-       /* Calculate the outline vertex positions */
-       glBegin(GL_LINE_LOOP);
-       glVertex2f(ofs_x, ofs_y);
-       glVertex2f(ofs_x + ima_x, ofs_y);
-       glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
-       glVertex2f(ofs_x, ofs_y + ima_y);
-       glEnd();
+               if (!use_blend) {
+                       glEnable(GL_BLEND);
+                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               }
 
-       /* Reset GL settings */
-       glPopMatrix();
+               imm_draw_line_box(pos, left, bottom, right, top);
 
-       BKE_image_release_ibuf(ima, ibuf, NULL);
+               glDisable(GL_LINE_SMOOTH);
+               glDisable(GL_BLEND);
+       }
+
+       immUnbindProgram();
 }
 
 static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float 
cent[3], float rad, const float tmat[4][4])

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to