forked from bartvdbraak/blender
Disable mipmapping in texture paint mode, so fast redrawing will now
work by default for power-of-two textures. Improved texture painting across different images a bit.
This commit is contained in:
parent
0cd62a9298
commit
9afa4619ed
@ -47,11 +47,6 @@ struct EdgeHash;
|
||||
*/
|
||||
void set_mipmap(int mipmap);
|
||||
|
||||
/**
|
||||
* Returns the current setting for mipmapping.
|
||||
*/
|
||||
int get_mipmap(void);
|
||||
|
||||
/**
|
||||
* Enables or disable linear mipmap setting for realtime images (textures).
|
||||
* Note that this will will destroy all texture bindings in OpenGL.
|
||||
@ -76,6 +71,10 @@ void free_realtime_image(struct Image *ima);
|
||||
void free_all_realtime_images(void);
|
||||
void make_repbind(struct Image *ima);
|
||||
int set_tpage(struct MTFace *tface);
|
||||
|
||||
void texpaint_enable_mipmap(void);
|
||||
void texpaint_disable_mipmap(void);
|
||||
|
||||
void draw_tface_mesh(struct Object *ob, struct Mesh *me, int dt);
|
||||
struct EdgeHash *get_tface_mesh_marked_edge_info(struct Mesh *me);
|
||||
void init_realtime_GL(void);
|
||||
|
@ -92,9 +92,10 @@ typedef struct Image {
|
||||
#define IMA_NOCOLLECT 32
|
||||
|
||||
/* tpageflag */
|
||||
#define IMA_TILES 1
|
||||
#define IMA_TWINANIM 2
|
||||
#define IMA_COLCYCLE 4 /* Depreciated */
|
||||
#define IMA_TILES 1
|
||||
#define IMA_TWINANIM 2
|
||||
#define IMA_COLCYCLE 4 /* Depreciated */
|
||||
#define IMA_MIPMAP_COMPLETE 8 /* all mipmap levels in OpenGL texture set? */
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -134,13 +134,12 @@ void set_mipmap(int mipmap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current setting for mipmapping.
|
||||
*/
|
||||
int get_mipmap(void)
|
||||
static int get_mipmap(void)
|
||||
{
|
||||
return fDoMipMap;
|
||||
return fDoMipMap && (!(G.f & G_TEXTUREPAINT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,7 +397,7 @@ int set_tpage(MTFace *tface)
|
||||
}
|
||||
glBindTexture( GL_TEXTURE_2D, *bind);
|
||||
|
||||
if (!fDoMipMap)
|
||||
if (!get_mipmap())
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@ -406,10 +405,12 @@ int set_tpage(MTFace *tface)
|
||||
} else
|
||||
{
|
||||
int minfilter= fLinearMipMap?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR_MIPMAP_NEAREST;
|
||||
|
||||
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
ima->tpageflag |= IMA_MIPMAP_COMPLETE;
|
||||
}
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
@ -435,7 +436,7 @@ int set_tpage(MTFace *tface)
|
||||
|
||||
void update_realtime_image(Image *ima, int x, int y, int w, int h)
|
||||
{
|
||||
if (ima->repbind || fDoMipMap || !ima->bindcode || !ima->ibuf ||
|
||||
if (ima->repbind || get_mipmap() || !ima->bindcode || !ima->ibuf ||
|
||||
(!is_pow2(ima->ibuf->x) || !is_pow2(ima->ibuf->y)) ||
|
||||
(w == 0) || (h == 0)) {
|
||||
/* these special cases require full reload still */
|
||||
@ -461,6 +462,9 @@ void update_realtime_image(Image *ima, int x, int y, int w, int h)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
|
||||
|
||||
if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
|
||||
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,12 +473,14 @@ void free_realtime_image(Image *ima)
|
||||
if(ima->bindcode) {
|
||||
glDeleteTextures(1, (GLuint *)&ima->bindcode);
|
||||
ima->bindcode= 0;
|
||||
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
|
||||
}
|
||||
if(ima->repbind) {
|
||||
glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
|
||||
|
||||
MEM_freeN(ima->repbind);
|
||||
ima->repbind= NULL;
|
||||
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,10 +488,49 @@ void free_all_realtime_images(void)
|
||||
{
|
||||
Image* ima;
|
||||
|
||||
ima= G.main->image.first;
|
||||
while(ima) {
|
||||
for(ima=G.main->image.first; ima; ima=ima->id.next)
|
||||
free_realtime_image(ima);
|
||||
ima= ima->id.next;
|
||||
}
|
||||
|
||||
/* these two functions are called on entering and exiting texture paint mode,
|
||||
temporary disabling/enabling mipmapping on all images for quick texture
|
||||
updates with glTexSubImage2D. images that didn't change don't have to be
|
||||
re-uploaded to OpenGL */
|
||||
void texpaint_disable_mipmap(void)
|
||||
{
|
||||
Image* ima;
|
||||
|
||||
if(!fDoMipMap)
|
||||
return;
|
||||
|
||||
for(ima=G.main->image.first; ima; ima=ima->id.next) {
|
||||
if(ima->bindcode) {
|
||||
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void texpaint_enable_mipmap(void)
|
||||
{
|
||||
Image* ima;
|
||||
|
||||
if(!fDoMipMap)
|
||||
return;
|
||||
|
||||
for(ima=G.main->image.first; ima; ima=ima->id.next) {
|
||||
if(ima->bindcode) {
|
||||
if(ima->tpageflag & IMA_MIPMAP_COMPLETE) {
|
||||
int minfilter= fLinearMipMap?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR_MIPMAP_NEAREST;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
free_realtime_image(ima);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -497,6 +542,7 @@ void make_repbind(Image *ima)
|
||||
glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
|
||||
MEM_freeN(ima->repbind);
|
||||
ima->repbind= 0;
|
||||
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
|
||||
}
|
||||
ima->totbind= ima->xrep*ima->yrep;
|
||||
if(ima->totbind>1) {
|
||||
|
@ -78,7 +78,7 @@ void set_scene(Scene *sce) /* also see scene.c: set_scene_bg() */
|
||||
if(G.f & G_VERTEXPAINT)
|
||||
set_vpaint();
|
||||
if(G.f & G_TEXTUREPAINT)
|
||||
G.f &= ~G_TEXTUREPAINT;
|
||||
set_texturepaint();
|
||||
if(G.f & G_WEIGHTPAINT)
|
||||
set_wpaint();
|
||||
|
||||
|
@ -1505,14 +1505,18 @@ void set_texturepaint() /* toggle */
|
||||
if(me)
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
|
||||
if(G.f & G_TEXTUREPAINT)
|
||||
if(G.f & G_TEXTUREPAINT) {
|
||||
G.f &= ~G_TEXTUREPAINT;
|
||||
texpaint_enable_mipmap();
|
||||
}
|
||||
else if (me) {
|
||||
G.f |= G_TEXTUREPAINT;
|
||||
brush_check_exists(&G.scene->toolsettings->imapaint.brush);
|
||||
texpaint_disable_mipmap();
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
|
||||
/* Get the barycentric coordinates of 2d point p in 2d triangle (v1, v2, v3) */
|
||||
|
@ -544,29 +544,34 @@ static void imapaint_paint_stroke(ImagePaintState *s, BrushPainter *painter, sho
|
||||
|
||||
if (texpaint) {
|
||||
|
||||
/* pick face and image */
|
||||
/* pick new face and image */
|
||||
if (facesel_face_pick(s->me, mval, &newfaceindex, 0)) {
|
||||
newimage = (Image*)((s->me->mtface+newfaceindex)->tpage);
|
||||
texpaint_pick_uv(s->ob, s->me, newfaceindex, mval, newuv);
|
||||
if(newimage && newimage->ibuf && newimage->ibuf->rect)
|
||||
texpaint_pick_uv(s->ob, s->me, newfaceindex, mval, newuv);
|
||||
else
|
||||
newimage = NULL;
|
||||
}
|
||||
else
|
||||
newuv[0] = newuv[1] = 0.0f;
|
||||
|
||||
/* see if stroke is broken, and if so finish painting in old position */
|
||||
if (s->image) {
|
||||
if (newimage == s->image) {
|
||||
texpaint_pick_uv(s->ob, s->me, s->faceindex, mval, fwuv);
|
||||
texpaint_pick_uv(s->ob, s->me, newfaceindex, prevmval, bkuv);
|
||||
texpaint_pick_uv(s->ob, s->me, s->faceindex, mval, fwuv);
|
||||
texpaint_pick_uv(s->ob, s->me, newfaceindex, prevmval, bkuv);
|
||||
|
||||
if (newimage == s->image)
|
||||
breakstroke= texpaint_break_stroke(s->uv, fwuv, bkuv, newuv);
|
||||
}
|
||||
else
|
||||
breakstroke= 1;
|
||||
}
|
||||
else
|
||||
fwuv[0]= fwuv[1]= 0.0f;
|
||||
|
||||
if (breakstroke) {
|
||||
texpaint_pick_uv(s->ob, s->me, s->faceindex, mval, fwuv);
|
||||
redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint, fwuv,
|
||||
time, 1, pressure);
|
||||
redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint,
|
||||
fwuv, time, 1, pressure);
|
||||
imapaint_clear_partial_redraw();
|
||||
brush_painter_break_stroke(painter);
|
||||
}
|
||||
@ -579,10 +584,10 @@ static void imapaint_paint_stroke(ImagePaintState *s, BrushPainter *painter, sho
|
||||
/* paint in new image */
|
||||
if (newimage) {
|
||||
if (breakstroke)
|
||||
redraw|= imapaint_paint_sub_stroke(s, painter, newimage, texpaint,
|
||||
bkuv, time, 0, pressure);
|
||||
redraw|= imapaint_paint_sub_stroke(s, painter, newimage, texpaint, newuv,
|
||||
time, 1, pressure);
|
||||
redraw|= imapaint_paint_sub_stroke(s, painter, newimage,
|
||||
texpaint, bkuv, time, 0, pressure);
|
||||
redraw|= imapaint_paint_sub_stroke(s, painter, newimage, texpaint,
|
||||
newuv, time, 1, pressure);
|
||||
}
|
||||
|
||||
/* update state */
|
||||
|
@ -408,6 +408,9 @@ static void SaveState(void)
|
||||
init_realtime_GL();
|
||||
init_gl_stuff();
|
||||
|
||||
if(G.f & G_TEXTUREPAINT)
|
||||
texpaint_enable_mipmap();
|
||||
|
||||
if(G.scene->camera==0 || G.scene->camera->type!=OB_CAMERA)
|
||||
error("no (correct) camera");
|
||||
|
||||
@ -416,6 +419,9 @@ static void SaveState(void)
|
||||
|
||||
static void RestoreState(void)
|
||||
{
|
||||
if(G.f & G_TEXTUREPAINT)
|
||||
texpaint_disable_mipmap();
|
||||
|
||||
curarea->win_swap = 0;
|
||||
curarea->head_swap=0;
|
||||
allqueue(REDRAWVIEW3D, 1);
|
||||
|
@ -690,11 +690,8 @@ int blenderqread(unsigned short event, short val)
|
||||
set_faceselect();
|
||||
if(G.f & G_VERTEXPAINT)
|
||||
set_vpaint();
|
||||
if(G.f & G_TEXTUREPAINT) {
|
||||
G.f &= ~G_TEXTUREPAINT;
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
if(G.f & G_TEXTUREPAINT)
|
||||
set_texturepaint();
|
||||
if(G.f & G_WEIGHTPAINT)
|
||||
set_wpaint();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user