Example #1
0
static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mcol), int matnr)
{
	Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);

	if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;

	if (tface)
		set_draw_settings_cached(0, tface, ma, Gtexdraw);

	/* always use color from mcol, as set in update_tface_color_layer */
	return DM_DRAW_OPTION_NORMAL;
}
Example #2
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);
}
Example #3
0
static DMDrawOption draw_tface__set_draw_legacy(MTexPoly *mtexpoly, const bool has_mcol, int matnr)
{
	Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
	bool invalidtexture = false;

	if (ma && (ma->game.flag & GEMAT_INVISIBLE))
		return DM_DRAW_OPTION_SKIP;

	invalidtexture = set_draw_settings_cached(0, mtexpoly, ma, Gtexdraw);

	if (mtexpoly && invalidtexture) {
		glColor3ub(0xFF, 0x00, 0xFF);
		return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
	}
	else if (!has_mcol) {
		if (mtexpoly) {
			glColor3f(1.0, 1.0, 1.0);
		}
		else {
			if (ma) {
				if (ma->shade_flag & MA_OBCOLOR) {
					glColor3ubv(Gtexdraw.obcol);
				}
				else {
					float col[3];
					if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
					else copy_v3_v3(col, &ma->r);

					glColor3fv(col);
				}
			}
			else {
				glColor3f(1.0, 1.0, 1.0);
			}
		}
		return DM_DRAW_OPTION_NORMAL; /* normal drawing (no mcols anyway, no need to turn off) */
	}
	else {
		return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
	}
}
Example #4
0
static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
{
	Mesh *me = ob->data;
	DerivedMesh *ddm;
	MPoly *mp, *mface  = me->mpoly;
	MTexPoly *mtpoly   = me->mtpoly;
	MLoopUV *mloopuv   = me->mloopuv;
	MLoopUV *luv;
	MLoopCol *mloopcol = me->mloopcol;  /* why does mcol exist? */
	MLoopCol *lcol;

	bProperty *prop = BKE_bproperty_object_get(ob, "Text");
	GPUVertexAttribs gattribs;
	int a, totpoly = me->totpoly;

	/* fake values to pass to GPU_render_text() */
	MCol  tmp_mcol[4]  = {{0}};
	MCol *tmp_mcol_pt  = mloopcol ? tmp_mcol : NULL;
	MTFace tmp_tf      = {{{0}}};

	/* don't draw without tfaces */
	if (!mtpoly || !mloopuv)
		return;

	/* don't draw when editing */
	if (ob->mode & OB_MODE_EDIT)
		return;
	else if (ob == OBACT)
		if (BKE_paint_select_elem_test(ob))
			return;

	ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);

	for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) {
		short matnr = mp->mat_nr;
		int mf_smooth = mp->flag & ME_SMOOTH;
		Material *mat = (me->mat) ? me->mat[matnr] : NULL;
		int mode = mat ? mat->game.flag : GEMAT_INVISIBLE;


		if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) {
			/* get the polygon as a tri/quad */
			int mp_vi[4];
			float v1[3], v2[3], v3[3], v4[3];
			char string[MAX_PROPSTRING];
			int characters, i, glattrib = -1, badtex = 0;


			/* TEXFACE */
			ME_MTEXFACE_CPY(&tmp_tf, mtpoly);

			if (glsl) {
				GPU_enable_material(matnr + 1, &gattribs);

				for (i = 0; i < gattribs.totlayer; i++) {
					if (gattribs.layer[i].type == CD_MTFACE) {
						glattrib = gattribs.layer[i].glindex;
						break;
					}
				}
			}
			else {
				badtex = set_draw_settings_cached(0, &tmp_tf, mat, Gtexdraw);
				if (badtex) {
					continue;
				}
			}

			mp_vi[0] = me->mloop[mp->loopstart + 0].v;
			mp_vi[1] = me->mloop[mp->loopstart + 1].v;
			mp_vi[2] = me->mloop[mp->loopstart + 2].v;
			mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0;

			/* UV */
			luv = &mloopuv[mp->loopstart];
			copy_v2_v2(tmp_tf.uv[0], luv->uv); luv++;
			copy_v2_v2(tmp_tf.uv[1], luv->uv); luv++;
			copy_v2_v2(tmp_tf.uv[2], luv->uv); luv++;
			if (mp->totloop >= 4) {
				copy_v2_v2(tmp_tf.uv[3], luv->uv);
			}

			/* COLOR */
			if (mloopcol) {
				unsigned int totloop_clamp = min_ii(4, mp->totloop);
				unsigned int j;
				lcol = &mloopcol[mp->loopstart];

				for (j = 0; j < totloop_clamp; j++, lcol++) {
					MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]);
				}
			}

			/* LOCATION */
			ddm->getVertCo(ddm, mp_vi[0], v1);
			ddm->getVertCo(ddm, mp_vi[1], v2);
			ddm->getVertCo(ddm, mp_vi[2], v3);
			if (mp->totloop >= 4) {
				ddm->getVertCo(ddm, mp_vi[3], v4);
			}



			/* The BM_FONT handling is in the gpu module, shared with the
			 * game engine, was duplicated previously */

			BKE_bproperty_set_valstr(prop, string);
			characters = strlen(string);
			
			if (!BKE_image_has_ibuf(mtpoly->tpage, NULL))
				characters = 0;

			if (!mf_smooth) {
				float nor[3];

				normal_tri_v3(nor, v1, v2, v3);

				glNormal3fv(nor);
			}

			GPU_render_text(&tmp_tf, mode, string, characters,
			                (unsigned int *)tmp_mcol_pt, v1, v2, v3, (mp->totloop >= 4 ? v4 : NULL), glattrib);
		}
	}

	ddm->release(ddm);
}
Example #5
0
static void update_tface_color_layer(DerivedMesh *dm)
{
	MTFace *tface = DM_get_tessface_data_layer(dm, CD_MTFACE);
	MFace *mface = dm->getTessFaceArray(dm);
	MCol *finalCol;
	int i, j;
	MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
	if (!mcol)
		mcol = dm->getTessFaceDataArray(dm, CD_MCOL);

	if (CustomData_has_layer(&dm->faceData, CD_TEXTURE_MCOL)) {
		finalCol = CustomData_get_layer(&dm->faceData, CD_TEXTURE_MCOL);
	}
	else {
		finalCol = MEM_mallocN(sizeof(MCol) * 4 * dm->getNumTessFaces(dm), "add_tface_color_layer");

		CustomData_add_layer(&dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData);
	}

	for (i = 0; i < dm->getNumTessFaces(dm); i++) {
		Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1);

		if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
			if (mcol)
				memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4);
			else
				for (j = 0; j < 4; j++) {
					finalCol[i * 4 + j].b = 255;
					finalCol[i * 4 + j].g = 255;
					finalCol[i * 4 + j].r = 255;
				}
		}
		else if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
			for (j = 0; j < 4; j++) {
				finalCol[i * 4 + j].b = 255;
				finalCol[i * 4 + j].g = 0;
				finalCol[i * 4 + j].r = 255;
			}
		}
		else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
			for (j = 0; j < 4; j++) {
				finalCol[i * 4 + j].b = Gtexdraw.obcol[0];
				finalCol[i * 4 + j].g = Gtexdraw.obcol[1];
				finalCol[i * 4 + j].r = Gtexdraw.obcol[2];
			}
		}
		else if (!mcol) {
			if (tface) {
				for (j = 0; j < 4; j++) {
					finalCol[i * 4 + j].b = 255;
					finalCol[i * 4 + j].g = 255;
					finalCol[i * 4 + j].r = 255;
				}
			}
			else {
				float col[3];

				if (ma) {
					if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
					else copy_v3_v3(col, &ma->r);
					
					for (j = 0; j < 4; j++) {
						finalCol[i * 4 + j].b = FTOCHAR(col[0]);
						finalCol[i * 4 + j].g = FTOCHAR(col[1]);
						finalCol[i * 4 + j].r = FTOCHAR(col[2]);
					}
				}
				else
					for (j = 0; j < 4; j++) {
						finalCol[i * 4 + j].b = 255;
						finalCol[i * 4 + j].g = 255;
						finalCol[i * 4 + j].r = 255;
					}
			}
		}
		else {
			for (j = 0; j < 4; j++) {
				finalCol[i * 4 + j].r = mcol[i * 4 + j].r;
				finalCol[i * 4 + j].g = mcol[i * 4 + j].g;
				finalCol[i * 4 + j].b = mcol[i * 4 + j].b;
			}
		}
	}
}
static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
{
	const MPoly *mp = dm->getPolyArray(dm);
	const int mpoly_num = dm->getNumPolys(dm);
	MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
	MLoopCol *finalCol;
	int i, j;
	MLoopCol *mloopcol = NULL;

	/* cache material values to avoid a lot of lookups */
	Material *ma = NULL;
	short mat_nr_prev = -1;
	enum {
		COPY_CALC,
		COPY_ORIG,
		COPY_PREV,
	} copy_mode = COPY_CALC;

	if (use_mcol) {
		mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL);
		if (!mloopcol)
			mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL);
	}

	if (CustomData_has_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL)) {
		finalCol = CustomData_get_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL);
	}
	else {
		finalCol = MEM_mallocN(sizeof(MLoopCol) * dm->numLoopData, "add_tface_color_layer");
		CustomData_add_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL, CD_ASSIGN, finalCol, dm->numLoopData);
	}

	for (i = mpoly_num; i--; mp++) {
		const short mat_nr = mp->mat_nr;

		if (UNLIKELY(mat_nr_prev != mat_nr)) {
			ma = give_current_material(Gtexdraw.ob, mat_nr + 1);
			copy_mode = COPY_CALC;
			mat_nr_prev = mat_nr;
		}

		/* avoid lookups  */
		if (copy_mode == COPY_ORIG) {
			memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
		}
		else if (copy_mode == COPY_PREV) {
			int loop_index = mp->loopstart;
			const MLoopCol *lcol_prev = &finalCol[(mp - 1)->loopstart];
			for (j = 0; j < mp->totloop; j++, loop_index++) {
				finalCol[loop_index] = *lcol_prev;
			}
		}

		/* (copy_mode == COPY_CALC) */
		else if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
			if (mloopcol) {
				memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
				copy_mode = COPY_ORIG;
			}
			else {
				memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
				copy_mode = COPY_PREV;
			}
		}
		else if (mtexpoly && set_draw_settings_cached(0, mtexpoly, ma, Gtexdraw)) {
			int loop_index = mp->loopstart;
			for (j = 0; j < mp->totloop; j++, loop_index++) {
				finalCol[loop_index].r = 255;
				finalCol[loop_index].g = 0;
				finalCol[loop_index].b = 255;
			}
			copy_mode = COPY_PREV;
		}
		else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
			int loop_index = mp->loopstart;
			for (j = 0; j < mp->totloop; j++, loop_index++) {
				copy_v3_v3_char((char *)&finalCol[loop_index].r, (char *)Gtexdraw.obcol);
			}
			copy_mode = COPY_PREV;
		}
		else {
			if (mloopcol) {
				memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
				copy_mode = COPY_ORIG;
			}
			else if (mtexpoly) {
				memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
				copy_mode = COPY_PREV;
			}
			else {
				float col[3];

				if (ma) {
					int loop_index = mp->loopstart;
					MLoopCol lcol;

					if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
					else copy_v3_v3(col, &ma->r);
					rgb_float_to_uchar((unsigned char *)&lcol.r, col);
					lcol.a = 255;
					
					for (j = 0; j < mp->totloop; j++, loop_index++) {
						finalCol[loop_index] = lcol;
					}
				}
				else {
					memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
				}
				copy_mode = COPY_PREV;
			}
		}
	}
}
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);
}