示例#1
0
/* byte to byte pixels, input and output 4-channel RGBA */
void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
                               int profile_to, int profile_from, bool predivide,
                               int width, int height, int stride_to, int stride_from)
{
	float tmp[4];
	int x, y;

	/* we need valid profiles */
	BLI_assert(profile_to != IB_PROFILE_NONE);
	BLI_assert(profile_from != IB_PROFILE_NONE);

	/* always RGBA input */
	for (y = 0; y < height; y++) {
		const uchar *from = rect_from + stride_from * y * 4;
		uchar *to = rect_to + stride_to * y * 4;

		if (profile_to == profile_from) {
			/* same profile, copy */
			memcpy(to, from, sizeof(uchar) * 4 * width);
		}
		else if (profile_to == IB_PROFILE_LINEAR_RGB) {
			/* convert to sRGB to linear */
			if (predivide) {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					srgb_to_linearrgb_predivide_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
			else {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					srgb_to_linearrgb_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
		}
		else if (profile_to == IB_PROFILE_SRGB) {
			/* convert from linear to sRGB */
			if (predivide) {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					linearrgb_to_srgb_predivide_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
			else {
				for (x = 0; x < width; x++, from += 4, to += 4) {
					rgba_uchar_to_float(tmp, from);
					linearrgb_to_srgb_v4(tmp, tmp);
					rgba_float_to_uchar(to, tmp);
				}
			}
		}
	}
}
示例#2
0
void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, const float color[4])
{
	int x, y;

	/* blank image */
	if (rect_float) {
		for (y = 0; y < height; y++) {
			for (x = 0; x < width; x++) {
				copy_v4_v4(rect_float, color);
				rect_float += 4;
			}
		}
	}
	
	if (rect) {
		unsigned char ccol[4];

		rgba_float_to_uchar(ccol, color);

		for (y = 0; y < height; y++) {
			for (x = 0; x < width; x++) {
				
				rect[0] = ccol[0];
				rect[1] = ccol[1];
				rect[2] = ccol[2];
				rect[3] = ccol[3];
				rect += 4;
			}
		}
	}
}
示例#3
0
static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
{
	unsigned char obcol[4];
	bool is_tex, solidtex;
	Mesh *me = ob->data;

	/* XXX scene->obedit warning */

	/* texture draw is abused for mask selection mode, do this so wire draw
	 * with face selection in weight paint is not lit. */
	if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
		solidtex = false;
		Gtexdraw.is_lit = 0;
	}
	else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE)) {
		/* draw with default lights in solid draw mode and edit mode */
		solidtex = true;
		Gtexdraw.is_lit = -1;
	}
	else {
		/* draw with lights in the scene otherwise */
		solidtex = false;
		if (v3d->flag2 & V3D_SHADELESS_TEX)
			Gtexdraw.is_lit = 0;
		else
			Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
	}
	
	rgba_float_to_uchar(obcol, ob->col);

	if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = true;
	else is_tex = false;

	Gtexdraw.ob = ob;
	Gtexdraw.is_tex = is_tex;

	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;

	memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
	set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
	glShadeModel(GL_SMOOTH);
	glCullFace(GL_BACK);
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TWOSIDED) ? GL_TRUE : GL_FALSE);
}
示例#4
0
/* update rectangular section of the brush image */
static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
                                       int origx, int origy, int w, int h, int xt, int yt)
{
    Scene *scene = painter->scene;
    Brush *brush = painter->brush;

    rctf tex_mapping = painter->tex_mapping;
    rctf mask_mapping = painter->mask_mapping;
    struct ImagePool *pool = painter->pool;

    bool use_masking = painter->cache.use_masking;
    bool use_color_correction = painter->cache.use_color_correction;
    bool use_float = painter->cache.use_float;
    bool is_texbrush = painter->cache.is_texbrush;
    bool is_maskbrush = painter->cache.is_maskbrush;
    bool use_texture_old = (oldtexibuf != NULL);

    int x, y, thread = 0;
    float brush_rgb[3];

    ImBuf *ibuf = painter->cache.ibuf;
    ImBuf *texibuf = painter->cache.texibuf;
    unsigned short *mask = painter->cache.mask;

    /* get brush color */
    if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
        copy_v3_v3(brush_rgb, brush->rgb);

        if (use_color_correction)
            srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
    }
    else {
        brush_rgb[0] = 1.0f;
        brush_rgb[1] = 1.0f;
        brush_rgb[2] = 1.0f;
    }

    /* fill pixes */
    for (y = origy; y < h; y++) {
        for (x = origx; x < w; x++) {
            /* sample texture and multiply with brush color */
            float texco[3], rgba[4];

            if (!use_texture_old) {
                if (is_texbrush) {
                    brush_imbuf_tex_co(&tex_mapping, x, y, texco);
                    BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
                    /* TODO(sergey): Support texture paint color space. */
                    if (!use_float) {
                        linearrgb_to_srgb_v3_v3(rgba, rgba);
                    }
                    mul_v3_v3(rgba, brush_rgb);
                }
                else {
                    copy_v3_v3(rgba, brush_rgb);
                    rgba[3] = 1.0f;
                }

                if (is_maskbrush) {
                    brush_imbuf_tex_co(&mask_mapping, x, y, texco);
                    rgba[3] *= BKE_brush_sample_masktex(scene, brush, texco, thread, pool);
                }
            }

            if (use_float) {
                /* handle float pixel */
                float *bf = ibuf->rect_float + (y * ibuf->x + x) * 4;
                float *tf = texibuf->rect_float + (y * texibuf->x + x) * 4;

                /* read from old texture buffer */
                if (use_texture_old) {
                    float *otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
                    copy_v4_v4(rgba, otf);
                }

                /* write to new texture buffer */
                copy_v4_v4(tf, rgba);

                /* if not using masking, multiply in the mask now */
                if (!use_masking) {
                    unsigned short *m = mask + (y * ibuf->x + x);
                    rgba[3] *= *m * (1.0f / 65535.0f);
                }

                /* output premultiplied float image, mf was already premultiplied */
                mul_v3_v3fl(bf, rgba, rgba[3]);
                bf[3] = rgba[3];
            }
            else {
                unsigned char crgba[4];

                /* handle byte pixel */
                unsigned char *b = (unsigned char *)ibuf->rect + (y * ibuf->x + x) * 4;
                unsigned char *t = (unsigned char *)texibuf->rect + (y * texibuf->x + x) * 4;

                /* read from old texture buffer */
                if (use_texture_old) {
                    unsigned char *ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
                    crgba[0] = ot[0];
                    crgba[1] = ot[1];
                    crgba[2] = ot[2];
                    crgba[3] = ot[3];
                }
                else
                    rgba_float_to_uchar(crgba, rgba);

                /* write to new texture buffer */
                t[0] = crgba[0];
                t[1] = crgba[1];
                t[2] = crgba[2];
                t[3] = crgba[3];

                /* if not using masking, multiply in the mask now */
                if (!use_masking) {
                    unsigned short *m = mask + (y * ibuf->x + x);
                    crgba[3] = (crgba[3] * (*m)) / 65535;
                }

                /* write to brush image buffer */
                b[0] = crgba[0];
                b[1] = crgba[1];
                b[2] = crgba[2];
                b[3] = crgba[3];
            }
        }
    }
}
示例#5
0
文件: divers.c 项目: dfelinto/blender
/* float to byte pixels, output 4-channel RGBA */
void IMB_buffer_byte_from_float_mask(uchar *rect_to,
                                     const float *rect_from,
                                     int channels_from,
                                     float dither,
                                     bool predivide,
                                     int width,
                                     int height,
                                     int stride_to,
                                     int stride_from,
                                     char *mask)
{
  int x, y;
  DitherContext *di = NULL;
  float inv_width = 1.0f / width, inv_height = 1.0f / height;

  if (dither) {
    di = create_dither_context(dither);
  }

  for (y = 0; y < height; y++) {
    float t = y * inv_height;

    if (channels_from == 1) {
      /* single channel input */
      const float *from = rect_from + ((size_t)stride_from) * y;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      for (x = 0; x < width; x++, from++, to += 4) {
        if (*mask++ == FILTER_MASK_USED) {
          to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]);
        }
      }
    }
    else if (channels_from == 3) {
      /* RGB input */
      const float *from = rect_from + ((size_t)stride_from) * y * 3;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      for (x = 0; x < width; x++, from += 3, to += 4) {
        if (*mask++ == FILTER_MASK_USED) {
          rgb_float_to_uchar(to, from);
          to[3] = 255;
        }
      }
    }
    else if (channels_from == 4) {
      /* RGBA input */
      const float *from = rect_from + ((size_t)stride_from) * y * 4;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      float straight[4];

      if (dither && predivide) {
        for (x = 0; x < width; x++, from += 4, to += 4) {
          if (*mask++ == FILTER_MASK_USED) {
            premul_to_straight_v4_v4(straight, from);
            float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t);
          }
        }
      }
      else if (dither) {
        for (x = 0; x < width; x++, from += 4, to += 4) {
          if (*mask++ == FILTER_MASK_USED) {
            float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t);
          }
        }
      }
      else if (predivide) {
        for (x = 0; x < width; x++, from += 4, to += 4) {
          if (*mask++ == FILTER_MASK_USED) {
            premul_to_straight_v4_v4(straight, from);
            rgba_float_to_uchar(to, straight);
          }
        }
      }
      else {
        for (x = 0; x < width; x++, from += 4, to += 4) {
          if (*mask++ == FILTER_MASK_USED) {
            rgba_float_to_uchar(to, from);
          }
        }
      }
    }
  }

  if (dither) {
    clear_dither_context(di);
  }
}
示例#6
0
文件: divers.c 项目: dfelinto/blender
/* float to byte pixels, output 4-channel RGBA */
void IMB_buffer_byte_from_float(uchar *rect_to,
                                const float *rect_from,
                                int channels_from,
                                float dither,
                                int profile_to,
                                int profile_from,
                                bool predivide,
                                int width,
                                int height,
                                int stride_to,
                                int stride_from)
{
  float tmp[4];
  int x, y;
  DitherContext *di = NULL;
  float inv_width = 1.0f / width;
  float inv_height = 1.0f / height;

  /* we need valid profiles */
  BLI_assert(profile_to != IB_PROFILE_NONE);
  BLI_assert(profile_from != IB_PROFILE_NONE);

  if (dither) {
    di = create_dither_context(dither);
  }

  for (y = 0; y < height; y++) {
    float t = y * inv_height;

    if (channels_from == 1) {
      /* single channel input */
      const float *from = rect_from + ((size_t)stride_from) * y;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      for (x = 0; x < width; x++, from++, to += 4) {
        to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]);
      }
    }
    else if (channels_from == 3) {
      /* RGB input */
      const float *from = rect_from + ((size_t)stride_from) * y * 3;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      if (profile_to == profile_from) {
        /* no color space conversion */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          rgb_float_to_uchar(to, from);
          to[3] = 255;
        }
      }
      else if (profile_to == IB_PROFILE_SRGB) {
        /* convert from linear to sRGB */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          linearrgb_to_srgb_v3_v3(tmp, from);
          rgb_float_to_uchar(to, tmp);
          to[3] = 255;
        }
      }
      else if (profile_to == IB_PROFILE_LINEAR_RGB) {
        /* convert from sRGB to linear */
        for (x = 0; x < width; x++, from += 3, to += 4) {
          srgb_to_linearrgb_v3_v3(tmp, from);
          rgb_float_to_uchar(to, tmp);
          to[3] = 255;
        }
      }
    }
    else if (channels_from == 4) {
      /* RGBA input */
      const float *from = rect_from + ((size_t)stride_from) * y * 4;
      uchar *to = rect_to + ((size_t)stride_to) * y * 4;

      if (profile_to == profile_from) {
        float straight[4];

        /* no color space conversion */
        if (dither && predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t);
          }
        }
        else if (dither) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t);
          }
        }
        else if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            rgba_float_to_uchar(to, straight);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            rgba_float_to_uchar(to, from);
          }
        }
      }
      else if (profile_to == IB_PROFILE_SRGB) {
        /* convert from linear to sRGB */
        unsigned short us[4];
        float straight[4];

        if (dither && predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t);
          }
        }
        else if (dither) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t);
          }
        }
        else if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            premul_to_straight_v4_v4(straight, from);
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_v4(to, us);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            linearrgb_to_srgb_ushort4(us, from);
            ushort_to_byte_v4(to, us);
          }
        }
      }
      else if (profile_to == IB_PROFILE_LINEAR_RGB) {
        /* convert from sRGB to linear */
        if (dither && predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_predivide_v4(tmp, from);
            float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t);
          }
        }
        else if (dither) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_v4(tmp, from);
            float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t);
          }
        }
        else if (predivide) {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_predivide_v4(tmp, from);
            rgba_float_to_uchar(to, tmp);
          }
        }
        else {
          for (x = 0; x < width; x++, from += 4, to += 4) {
            srgb_to_linearrgb_v4(tmp, from);
            rgba_float_to_uchar(to, tmp);
          }
        }
      }
    }
  }

  if (dither) {
    clear_dither_context(di);
  }
}
示例#7
0
/* update rectangular section of the brush image */
static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
                                       int origx, int origy, int w, int h, int xt, int yt)
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;

	const char *display_device = scene->display_settings.display_device;
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);

	rctf tex_mapping = painter->tex_mapping;
	struct ImagePool *pool = painter->pool;

	bool use_color_correction = painter->cache.use_color_correction;
	bool use_float = painter->cache.use_float;
	bool is_texbrush = painter->cache.is_texbrush;
	bool use_texture_old = (oldtexibuf != NULL);

	int x, y, thread = 0;
	float brush_rgb[3];

	ImBuf *ibuf = painter->cache.ibuf;
	ImBuf *texibuf = painter->cache.texibuf;

	/* get brush color */
	if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
		paint_brush_color_get(scene, brush, use_color_correction, painter->cache.invert, 0.0, 1.0, brush_rgb, display);
	}
	else {
		brush_rgb[0] = 1.0f;
		brush_rgb[1] = 1.0f;
		brush_rgb[2] = 1.0f;
	}

	/* fill pixels */
	for (y = origy; y < h; y++) {
		for (x = origx; x < w; x++) {
			/* sample texture and multiply with brush color */
			float texco[3], rgba[4];

			if (!use_texture_old) {
				if (is_texbrush) {
					brush_imbuf_tex_co(&tex_mapping, x, y, texco);
					BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
					/* TODO(sergey): Support texture paint color space. */
					if (!use_float) {
						IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
					}
					mul_v3_v3(rgba, brush_rgb);
				}
				else {
					copy_v3_v3(rgba, brush_rgb);
					rgba[3] = 1.0f;
				}
			}

			if (use_float) {
				/* handle float pixel */
				float *bf = ibuf->rect_float + (y * ibuf->x + x) * 4;
				float *tf = texibuf->rect_float + (y * texibuf->x + x) * 4;

				/* read from old texture buffer */
				if (use_texture_old) {
					const float *otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
					copy_v4_v4(rgba, otf);
				}

				/* write to new texture buffer */
				copy_v4_v4(tf, rgba);

				/* output premultiplied float image, mf was already premultiplied */
				mul_v3_v3fl(bf, rgba, rgba[3]);
				bf[3] = rgba[3];
			}
			else {
				unsigned char crgba[4];

				/* handle byte pixel */
				unsigned char *b = (unsigned char *)ibuf->rect + (y * ibuf->x + x) * 4;
				unsigned char *t = (unsigned char *)texibuf->rect + (y * texibuf->x + x) * 4;

				/* read from old texture buffer */
				if (use_texture_old) {
					unsigned char *ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
					crgba[0] = ot[0];
					crgba[1] = ot[1];
					crgba[2] = ot[2];
					crgba[3] = ot[3];
				}
				else
					rgba_float_to_uchar(crgba, rgba);

				/* write to new texture buffer */
				t[0] = crgba[0];
				t[1] = crgba[1];
				t[2] = crgba[2];
				t[3] = crgba[3];

				/* write to brush image buffer */
				b[0] = crgba[0];
				b[1] = crgba[1];
				b[2] = crgba[2];
				b[3] = crgba[3];
			}
		}
	}
}
static void mloopcol_from_float(MLoopCol *mloopcol, const float col[3])
{
	rgba_float_to_uchar((unsigned char *)&mloopcol->r, col);
}
示例#9
0
static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
                                     int x, int y, int w, int h, int xt, int yt,
                                     const float pos[2])
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;
	ImBuf *ibuf, *maskibuf, *texibuf;
	float *bf, *mf, *tf, *otf = NULL, xoff, yoff, xy[2], rgba[4];
	unsigned char *b, *m, *t, *ot = NULL;
	int dotexold, origx = x, origy = y;
	const int radius = BKE_brush_size_get(painter->scene, brush);

	xoff = -radius + 0.5f;
	yoff = -radius + 0.5f;
	xoff += (int)pos[0] - (int)painter->startpaintpos[0];
	yoff += (int)pos[1] - (int)painter->startpaintpos[1];

	ibuf = painter->cache.ibuf;
	texibuf = painter->cache.texibuf;
	maskibuf = painter->cache.maskibuf;

	dotexold = (oldtexibuf != NULL);

	/* not sure if it's actually needed or it's a mistake in coords/sizes
	 * calculation in brush_painter_fixed_tex_partial_update(), but without this
	 * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
	w = min_ii(w, ibuf->x);
	h = min_ii(h, ibuf->y);

	if (painter->cache.flt) {
		for (; y < h; y++) {
			bf = ibuf->rect_float + (y * ibuf->x + origx) * 4;
			tf = texibuf->rect_float + (y * texibuf->x + origx) * 4;
			mf = maskibuf->rect_float + (y * maskibuf->x + origx) * 4;

			if (dotexold)
				otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + xt) * 4;

			for (x = origx; x < w; x++, bf += 4, mf += 4, tf += 4) {
				if (dotexold) {
					copy_v3_v3(tf, otf);
					tf[3] = otf[3];
					otf += 4;
				}
				else {
					xy[0] = x + xoff;
					xy[1] = y + yoff;

					BKE_brush_sample_tex(scene, brush, xy, tf, 0);
				}

				bf[0] = tf[0] * mf[0];
				bf[1] = tf[1] * mf[1];
				bf[2] = tf[2] * mf[2];
				bf[3] = tf[3] * mf[3];
			}
		}
	}
	else {
		for (; y < h; y++) {
			b = (unsigned char *)ibuf->rect + (y * ibuf->x + origx) * 4;
			t = (unsigned char *)texibuf->rect + (y * texibuf->x + origx) * 4;
			m = (unsigned char *)maskibuf->rect + (y * maskibuf->x + origx) * 4;

			if (dotexold)
				ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + xt) * 4;

			for (x = origx; x < w; x++, b += 4, m += 4, t += 4) {
				if (dotexold) {
					t[0] = ot[0];
					t[1] = ot[1];
					t[2] = ot[2];
					t[3] = ot[3];
					ot += 4;
				}
				else {
					xy[0] = x + xoff;
					xy[1] = y + yoff;

					BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
					rgba_float_to_uchar(t, rgba);
				}

				b[0] = t[0] * m[0] / 255;
				b[1] = t[1] * m[1] / 255;
				b[2] = t[2] * m[2] / 255;
				b[3] = t[3] * m[3] / 255;
			}
		}
	}
}
static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
{
	unsigned char obcol[4];
	bool is_tex, solidtex;
	Mesh *me = ob->data;
	ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;

	/* XXX scene->obedit warning */

	/* texture draw is abused for mask selection mode, do this so wire draw
	 * with face selection in weight paint is not lit. */
	if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
		solidtex = false;
		Gtexdraw.is_lit = 0;
	}
	else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE) ||
	        (BKE_scene_use_new_shading_nodes(scene) && (ob->mode & OB_MODE_TEXTURE_PAINT))) {
		/* draw with default lights in solid draw mode and edit mode */
		solidtex = true;
		Gtexdraw.is_lit = -1;
	}
	else {
		/* draw with lights in the scene otherwise */
		solidtex = false;
		if (v3d->flag2 & V3D_SHADELESS_TEX)
			Gtexdraw.is_lit = 0;
		else
			Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
	}
	
	rgba_float_to_uchar(obcol, ob->col);

	if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = true;
	else is_tex = false;

	Gtexdraw.ob = ob;
	Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL;
	Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
	Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
	Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas;
	Gtexdraw.is_tex = is_tex;

	/* 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);
		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_PREVIOUS);
		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_PREVIOUS);
		
		/* 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;

	memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
	set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
	glShadeModel(GL_SMOOTH);
	glCullFace(GL_BACK);
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TWOSIDED) ? GL_TRUE : GL_FALSE);
}
示例#11
0
/* TODO, use define for 'texfall' arg */
void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
{
    ImBuf *ibuf;
    float xy[2], rgba[4], *dstf;
    int x, y, rowbytes, xoff, yoff, imbflag;
    const int radius = BKE_brush_size_get(scene, brush);
    unsigned char *dst, crgb[3];
    const float alpha = BKE_brush_alpha_get(scene, brush);
    float brush_rgb[3];

    imbflag = (flt) ? IB_rectfloat : IB_rect;
    xoff = -bufsize / 2.0f + 0.5f;
    yoff = -bufsize / 2.0f + 0.5f;
    rowbytes = bufsize * 4;

    if (*outbuf)
        ibuf = *outbuf;
    else
        ibuf = IMB_allocImBuf(bufsize, bufsize, 32, imbflag);

    if (flt) {
        copy_v3_v3(brush_rgb, brush->rgb);
        if (use_color_correction) {
            srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
        }

        for (y = 0; y < ibuf->y; y++) {
            dstf = ibuf->rect_float + y * rowbytes;

            for (x = 0; x < ibuf->x; x++, dstf += 4) {
                xy[0] = x + xoff;
                xy[1] = y + yoff;

                if (texfall == 0) {
                    copy_v3_v3(dstf, brush_rgb);
                    dstf[3] = alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
                }
                else if (texfall == 1) {
                    BKE_brush_sample_tex(scene, brush, xy, dstf, 0);
                }
                else {
                    BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
                    mul_v3_v3v3(dstf, rgba, brush_rgb);
                    dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
                }
            }
        }
    }
    else {
        float alpha_f; /* final float alpha to convert to char */
        rgb_float_to_uchar(crgb, brush->rgb);

        for (y = 0; y < ibuf->y; y++) {
            dst = (unsigned char *)ibuf->rect + y * rowbytes;

            for (x = 0; x < ibuf->x; x++, dst += 4) {
                xy[0] = x + xoff;
                xy[1] = y + yoff;

                if (texfall == 0) {
                    alpha_f = alpha * BKE_brush_curve_strength(brush, len_v2(xy), radius);

                    dst[0] = crgb[0];
                    dst[1] = crgb[1];
                    dst[2] = crgb[2];
                    dst[3] = FTOCHAR(alpha_f);
                }
                else if (texfall == 1) {
                    BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
                    rgba_float_to_uchar(dst, rgba);
                }
                else if (texfall == 2) {
                    BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
                    mul_v3_v3(rgba, brush->rgb);
                    alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);

                    rgb_float_to_uchar(dst, rgba);

                    dst[3] = FTOCHAR(alpha_f);
                }
                else {
                    BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
                    alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);

                    dst[0] = crgb[0];
                    dst[1] = crgb[1];
                    dst[2] = crgb[2];
                    dst[3] = FTOCHAR(alpha_f);
                }
            }
        }
    }

    *outbuf = ibuf;
}