Skip to content

Commit

Permalink
dirty dirt patch to restore gemat texts
Browse files Browse the repository at this point in the history
  • Loading branch information
youle31 committed Apr 25, 2017
1 parent 722c7ee commit c3b250c
Show file tree
Hide file tree
Showing 14 changed files with 339 additions and 3 deletions.
1 change: 1 addition & 0 deletions release/scripts/startup/bl_ui/properties_material.py
Expand Up @@ -671,6 +671,7 @@ def draw(self, context):
col = split.column()
col.prop(game, "use_backface_culling")
col.prop(game, "invisible")
col.prop(game, "text")
col.prop(game, "physics")
col.label(text="Face Orientation:")
col.prop(game, "face_orientation", text="")
Expand Down
1 change: 1 addition & 0 deletions source/blender/blenkernel/intern/material.c
Expand Up @@ -1811,6 +1811,7 @@ static void decode_tfaceflag(Material *ma, int flag, int convertall)
/* Special Face Properties */
if ((flag & TF_TWOSIDE) == 0) (*game).flag |= GEMAT_BACKCULL;
if (flag & TF_INVISIBLE) (*game).flag |= GEMAT_INVISIBLE;
if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT;

/* Face Orientation */
if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO;
Expand Down
128 changes: 128 additions & 0 deletions source/blender/editors/space_view3d/drawmesh.c
Expand Up @@ -777,6 +777,127 @@ static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int ind
return DM_DRAW_OPTION_NORMAL;
}

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;

/* 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;
const bool mf_smooth = (mp->flag & ME_SMOOTH) != 0;
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 v_quad_data[4][3];
const float *v_quad[4];
const float *uv_quad[4];
char string[MAX_PROPSTRING];
int characters, i, glattrib = -1, badtex = 0;

/* TEXFACE */

GPU_object_material_bind(matnr + 1, &gattribs);

for (i = 0; i < gattribs.totlayer; i++) {
if (gattribs.layer[i].type == CD_MTFACE) {
glattrib = gattribs.layer[i].glindex;
break;
}
}

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];
uv_quad[0] = luv->uv; luv++;
uv_quad[1] = luv->uv; luv++;
uv_quad[2] = luv->uv; luv++;
if (mp->totloop >= 4) {
uv_quad[3] = luv->uv;
}
else {
uv_quad[3] = NULL;
}
/* 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], v_quad_data[0]);
ddm->getVertCo(ddm, mp_vi[1], v_quad_data[1]);
ddm->getVertCo(ddm, mp_vi[2], v_quad_data[2]);
if (mp->totloop >= 4) {
ddm->getVertCo(ddm, mp_vi[3], v_quad_data[3]);
}
v_quad[0] = v_quad_data[0];
v_quad[1] = v_quad_data[1];
v_quad[2] = v_quad_data[2];
if (mp->totloop >= 4) {
v_quad[3] = v_quad_data[2];
}
else {
v_quad[3] = NULL;
}
/* 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, v_quad[0], v_quad[1], v_quad[2]);
glNormal3fv(nor);
}
GPU_render_text(
mtpoly, mode, string, characters,
(unsigned int *)tmp_mcol_pt,
v_quad, uv_quad,
glattrib);
}
}
ddm->release(ddm);
}

static int compareDrawOptions(void *userData, int cur_index, int next_index)
{
drawTFace_userData *data = userData;
Expand Down Expand Up @@ -894,6 +1015,13 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
}
}

/* draw game engine text hack */
if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
if (BKE_bproperty_object_get(ob, "Text")) {
draw_mesh_text(scene, ob, 0);
}
}

draw_textured_end();

/* draw edges and selected faces over textured mesh */
Expand Down
8 changes: 8 additions & 0 deletions source/blender/gpu/GPU_draw.h
Expand Up @@ -101,6 +101,14 @@ int GPU_scene_object_lights(
struct Scene *scene, struct Object *ob,
int lay, float viewmat[4][4], int ortho);

/* Text render
* based on moving uv coordinates */
void GPU_render_text(
struct MTexPoly *mtexpoly, int mode,
const char *textstr, int textlen, unsigned int *col,
const float *v_quad[4], const float *uv_quad[4],
int glattrib);

/* Mipmap settings
* - these will free textures on changes */

Expand Down
120 changes: 120 additions & 0 deletions source/blender/gpu/intern/gpu_draw.c
Expand Up @@ -390,6 +390,126 @@ static void gpu_verify_reflection(Image *ima)
}
}

static void gpu_mcol(unsigned int ucol)
{
/* mcol order is swapped */
const char *cp = (char *)&ucol;
glColor3ub(cp[3], cp[2], cp[1]);
}

void GPU_render_text(
MTexPoly *mtexpoly, int mode,
const char *textstr, int textlen, unsigned int *col,
const float *v_quad[4], const float *uv_quad[4],
int glattrib)
{
if ((mode & GEMAT_TEXT) && (textlen > 0) && mtexpoly->tpage) {
const float *v1 = v_quad[0];
const float *v2 = v_quad[1];
const float *v3 = v_quad[2];
const float *v4 = v_quad[3];
Image *ima = (Image *)mtexpoly->tpage;
const size_t textlen_st = textlen;
float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;

/* multiline */
float line_start = 0.0f, line_height;

if (v4)
line_height = max_ffff(v1[1], v2[1], v3[1], v4[2]) - min_ffff(v1[1], v2[1], v3[1], v4[2]);
else
line_height = max_fff(v1[1], v2[1], v3[1]) - min_fff(v1[1], v2[1], v3[1]);
line_height *= 1.2f; /* could be an option? */
/* end multiline */


/* color has been set */
if (mtexpoly->mode & TF_OBCOL)
col = NULL;
else if (!col)
glColor3f(1.0f, 1.0f, 1.0f);

glPushMatrix();

/* get the tab width */
ImBuf *first_ibuf = BKE_image_get_first_ibuf(ima);
matrixGlyph(first_ibuf, ' ', &centerx, &centery,
&sizex, &sizey, &transx, &transy, &movex, &movey, &advance);

float advance_tab = advance * 4; /* tab width could also be an option */


for (size_t index = 0; index < textlen_st;) {
unsigned int character;
float uv[4][2];

/* lets calculate offset stuff */
character = BLI_str_utf8_as_unicode_and_size_safe(textstr + index, &index);

if (character == '\n') {
glTranslatef(line_start, -line_height, 0.0f);
line_start = 0.0f;
continue;
}
else if (character == '\t') {
glTranslatef(advance_tab, 0.0f, 0.0f);
line_start -= advance_tab; /* so we can go back to the start of the line */
continue;

}
else if (character > USHRT_MAX) {
/* not much we can do here bmfonts take ushort */
character = '?';
}

/* space starts at offset 1 */
/* character = character - ' ' + 1; */
matrixGlyph(first_ibuf, character, &centerx, &centery,
&sizex, &sizey, &transx, &transy, &movex, &movey, &advance);

uv[0][0] = (uv_quad[0][0] - centerx) * sizex + transx;
uv[0][1] = (uv_quad[0][1] - centery) * sizey + transy;
uv[1][0] = (uv_quad[1][0] - centerx) * sizex + transx;
uv[1][1] = (uv_quad[1][1] - centery) * sizey + transy;
uv[2][0] = (uv_quad[2][0] - centerx) * sizex + transx;
uv[2][1] = (uv_quad[2][1] - centery) * sizey + transy;

glBegin(GL_POLYGON);
if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[0]);
else glTexCoord2fv(uv[0]);
if (col) gpu_mcol(col[0]);
glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);

if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[1]);
else glTexCoord2fv(uv[1]);
if (col) gpu_mcol(col[1]);
glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);

if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[2]);
else glTexCoord2fv(uv[2]);
if (col) gpu_mcol(col[2]);
glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);

if (v4) {
uv[3][0] = (uv_quad[3][0] - centerx) * sizex + transx;
uv[3][1] = (uv_quad[3][1] - centery) * sizey + transy;

if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[3]);
else glTexCoord2fv(uv[3]);
if (col) gpu_mcol(col[3]);
glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
}
glEnd();

glTranslatef(advance, 0.0f, 0.0f);
line_start -= advance; /* so we can go back to the start of the line */
}
glPopMatrix();

BKE_image_release_ibuf(ima, first_ibuf, NULL);
}
}

typedef struct VerifyThreadData {
ImBuf *ibuf;
float *srgb_frect;
Expand Down
1 change: 1 addition & 0 deletions source/blender/makesdna/DNA_material_types.h
Expand Up @@ -226,6 +226,7 @@ typedef struct Material {
// Game Options - flag
#define GEMAT_BACKCULL 16 /* KX_BACKCULL */
#define GEMAT_SHADED 32 /* KX_LIGHT */
#define GEMAT_TEXT 64 /* RAS_RENDER_3DPOLYGON_TEXT */
#define GEMAT_NOPHYSICS 128
#define GEMAT_INVISIBLE 256

Expand Down
5 changes: 5 additions & 0 deletions source/blender/makesrna/intern/rna_material.c
Expand Up @@ -902,6 +902,11 @@ static void rna_def_material_gamesettings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Backface Culling", "Hide Back of the face in Game Engine ");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");

prop = RNA_def_property(srna, "text", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_TEXT); /* use bitflags */
RNA_def_property_ui_text(prop, "Text", "Use material as text in Game Engine ");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");

prop = RNA_def_property(srna, "invisible", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_INVISIBLE); /* use bitflags */
RNA_def_property_ui_text(prop, "Invisible", "Make face invisible");
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
Expand Up @@ -66,7 +66,7 @@ int RAS_IPolyMaterial::ConvertFaceMode(struct GameSettings *game) const

int orimode = game->face_orientation;
int alpha_blend = game->alpha_blend;
int flags = game->flag & (GEMAT_BACKCULL);
int flags = game->flag & (GEMAT_TEXT | GEMAT_BACKCULL);

modefinal = orimode | alpha_blend | flags;

Expand Down
6 changes: 5 additions & 1 deletion source/gameengine/Rasterizer/RAS_MeshSlot.cpp
Expand Up @@ -211,7 +211,11 @@ void RAS_MeshSlot::RunNode(const RAS_RenderNodeArguments& args)
rasty->MultMatrix(mat);
}

if (istext) {
if (material->GetDrawingMode() & RAS_Rasterizer::RAS_RENDER_3DPOLYGON_TEXT) {
rasty->IndexPrimitives_3DText(this, material);
}

else if (istext) {
rasty->IndexPrimitivesText(this);
}
else {
Expand Down

0 comments on commit c3b250c

Please sign in to comment.