From 3733eb6340ba34dc68022f58de731c8ec5fb274b Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Tue, 2 Sep 2014 15:57:22 +0200 Subject: Fix T41682. Bring back shading in texture painting. This works now but it uses 3 texture units instead of two. Most GPUs of DirectX 8 (OpenGL 1.4 should cover that) functionality even should have those, but some old GPUs might not work with that. In any case, I hope we will be moving to OpenGL 2.1 requirement soon anyway where 4-8 texture units are usually the norm. --- source/blender/blenkernel/intern/cdderivedmesh.c | 8 +-- source/blender/blenkernel/intern/subsurf_ccg.c | 24 +++---- source/blender/editors/space_view3d/drawmesh.c | 82 ++++++++++++++++-------- source/blender/gpu/intern/gpu_buffers.c | 24 +++---- 4 files changed, 84 insertions(+), 54 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 4369ef1a26d..116f9d9e64c 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -802,7 +802,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); if (tf) glTexCoord2fv(tf->uv[0]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); mvert = &mv[mf->v1]; if (lnors) glNormal3sv((const GLshort *)lnors[0][0]); @@ -810,7 +810,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, glVertex3fv(mvert->co); if (tf) glTexCoord2fv(tf->uv[1]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); mvert = &mv[mf->v2]; if (lnors) glNormal3sv((const GLshort *)lnors[0][1]); @@ -818,7 +818,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, glVertex3fv(mvert->co); if (tf) glTexCoord2fv(tf->uv[2]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); mvert = &mv[mf->v3]; if (lnors) glNormal3sv((const GLshort *)lnors[0][2]); @@ -827,7 +827,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if (mf->v4) { if (tf) glTexCoord2fv(tf->uv[3]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); mvert = &mv[mf->v4]; if (lnors) glNormal3sv((const GLshort *)lnors[0][3]); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 79c348ac181..2e96eecebcf 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -2398,25 +2398,25 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1); if (tf) glTexCoord2fv(tf->uv[1]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); glNormal3sv(ln[0][1]); glVertex3fv(d_co); if (tf) glTexCoord2fv(tf->uv[2]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); glNormal3sv(ln[0][2]); glVertex3fv(c_co); if (tf) glTexCoord2fv(tf->uv[3]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); glNormal3sv(ln[0][3]); glVertex3fv(b_co); if (tf) glTexCoord2fv(tf->uv[0]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); glNormal3sv(ln[0][0]); glVertex3fv(a_co); @@ -2438,13 +2438,13 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, b = CCG_grid_elem(&key, faceGridData, x, y + 1); if (tf) glTexCoord2fv(tf->uv[0]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); glNormal3fv(CCG_elem_no(&key, a)); glVertex3fv(CCG_elem_co(&key, a)); if (tf) glTexCoord2fv(tf->uv[1]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); glNormal3fv(CCG_elem_no(&key, b)); glVertex3fv(CCG_elem_co(&key, b)); @@ -2460,13 +2460,13 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, b = CCG_grid_elem(&key, faceGridData, x, y + 1); if (tf) glTexCoord2fv(tf->uv[3]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); glNormal3fv(CCG_elem_no(&key, a)); glVertex3fv(CCG_elem_co(&key, a)); if (tf) glTexCoord2fv(tf->uv[2]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); glNormal3fv(CCG_elem_no(&key, b)); glVertex3fv(CCG_elem_co(&key, b)); @@ -2491,22 +2491,22 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, ccgDM_glNormalFast(a_co, b_co, c_co, d_co); if (tf) glTexCoord2fv(tf->uv[1]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); glVertex3fv(d_co); if (tf) glTexCoord2fv(tf->uv[2]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); glVertex3fv(c_co); if (tf) glTexCoord2fv(tf->uv[3]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); glVertex3fv(b_co); if (tf) glTexCoord2fv(tf->uv[0]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); glVertex3fv(a_co); diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index dd9b9dea02a..d919db7a223 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -214,16 +214,14 @@ static struct TextureDrawState { Object *ob; Image *stencil; /* texture painting stencil */ Image *canvas; /* texture painting canvas, for image mode */ - bool stencil_invert; bool use_game_mat; int is_lit, is_tex; int color_profile; bool use_backface_culling; unsigned char obcol[4]; - float stencil_col[4]; bool is_texpaint; bool texpaint_material; /* use material slots for texture painting */ -} Gtexdraw = {NULL, NULL, NULL, false, false, 0, 0, 0, false, {0, 0, 0, 0}, {0.0f, 0.0f, 0.0f, 1.0f}, false, false}; +} Gtexdraw = {NULL, NULL, NULL, false, 0, 0, 0, false, {0, 0, 0, 0}, false, false}; static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw) { @@ -308,14 +306,24 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * c_badtex = false; if (GPU_verify_image(ima, NULL, 0, 1, 0, false)) { glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, ima->bindcode); + glActiveTexture(GL_TEXTURE0); } else { + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glActiveTexture(GL_TEXTURE0); + c_badtex = true; GPU_clear_tpage(true); glDisable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBindTexture(GL_TEXTURE_2D, 0); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } } else { @@ -396,35 +404,51 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O Gtexdraw.ob = ob; Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL; - Gtexdraw.stencil_invert = ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0); Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT); - copy_v3_v3(Gtexdraw.stencil_col, imapaint->stencil_col); Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL); Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas; Gtexdraw.is_tex = is_tex; - /* load the stencil texture here */ - if (Gtexdraw.is_texpaint && (Gtexdraw.stencil != NULL)) { + /* naughty multitexturing hacks to quickly support stencil + shading + alpha blending + * in new texpaint code. The better solution here would be to support GLSL */ + if (Gtexdraw.is_texpaint) { glActiveTexture(GL_TEXTURE1); - if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) { - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Gtexdraw.stencil_col); - if (!Gtexdraw.stencil_invert) { - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR); - } - else { - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + + /* load the stencil texture here */ + if (Gtexdraw.stencil != NULL) { + glActiveTexture(GL_TEXTURE2); + if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) { + float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f}; + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col); + if ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) == 0) { + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR); + } + else { + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); + } } } glActiveTexture(GL_TEXTURE0); } - + Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene); Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0; Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0; @@ -439,14 +463,20 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O static void draw_textured_end(void) { if (Gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) { + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glBindTexture(GL_TEXTURE_2D, 0); + if (Gtexdraw.stencil != NULL) { - glActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE2); glDisable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); } + glActiveTexture(GL_TEXTURE0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* manual reset, since we don't use tpage */ glBindTexture(GL_TEXTURE_2D, 0); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 698e72a6b35..5d2c9cd3a90 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -63,12 +63,12 @@ #include "bmesh.h" typedef enum { - GPU_BUFFER_VERTEX_STATE = 1, - GPU_BUFFER_NORMAL_STATE = 2, - GPU_BUFFER_TEXCOORD_UNIT_0_STATE = 4, - GPU_BUFFER_TEXCOORD_UNIT_1_STATE = 8, - GPU_BUFFER_COLOR_STATE = 16, - GPU_BUFFER_ELEMENT_STATE = 32, + GPU_BUFFER_VERTEX_STATE = (1 << 0), + GPU_BUFFER_NORMAL_STATE = (1 << 1), + GPU_BUFFER_TEXCOORD_UNIT_0_STATE = (1 << 2), + GPU_BUFFER_TEXCOORD_UNIT_2_STATE = (1 << 3), + GPU_BUFFER_COLOR_STATE = (1 << 4), + GPU_BUFFER_ELEMENT_STATE = (1 << 5), } GPUBufferState; #define MAX_GPU_ATTRIB_DATA 32 @@ -1159,20 +1159,20 @@ void GPU_texpaint_uv_setup(DerivedMesh *dm) if (useVBOs) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id); glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0); - glClientActiveTexture(GL_TEXTURE1); + glClientActiveTexture(GL_TEXTURE2); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), BUFFER_OFFSET(2 * sizeof(float))); glClientActiveTexture(GL_TEXTURE0); } else { glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv->pointer); - glClientActiveTexture(GL_TEXTURE1); + glClientActiveTexture(GL_TEXTURE2); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv->pointer + 2 * sizeof(float)); glClientActiveTexture(GL_TEXTURE0); } - GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_1_STATE; + GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE; } @@ -1335,8 +1335,8 @@ void GPU_buffer_unbind(void) glDisableClientState(GL_NORMAL_ARRAY); if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_0_STATE) glDisableClientState(GL_TEXTURE_COORD_ARRAY); - if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_1_STATE) { - glClientActiveTexture(GL_TEXTURE1); + if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_2_STATE) { + glClientActiveTexture(GL_TEXTURE2); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE0); } @@ -1348,7 +1348,7 @@ void GPU_buffer_unbind(void) } } GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE | - GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_1_STATE | + GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE | GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE); for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) { -- cgit v1.2.3