Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/drawmesh.c')
-rw-r--r--source/blender/src/drawmesh.c999
1 files changed, 999 insertions, 0 deletions
diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c
new file mode 100644
index 00000000000..805dbe84693
--- /dev/null
+++ b/source/blender/src/drawmesh.c
@@ -0,0 +1,999 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+#include <math.h>
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+
+#include "IMB_imbuf_types.h"
+
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_property_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_bmfont.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_image.h"
+#include "BKE_property.h"
+#include "BKE_global.h"
+#include "BKE_displist.h"
+#include "BKE_object.h"
+#include "BKE_material.h"
+
+#include "BIF_gl.h"
+#include "BIF_mywindow.h"
+
+#include "BDR_editface.h"
+#include "BDR_vpaint.h"
+#include "BDR_drawmesh.h"
+
+#include "BSE_drawview.h"
+
+#include "blendef.h"
+#include "nla.h"
+
+//#include "glext.h"
+/* some local functions */
+static void draw_hide_tfaces(Object *ob, Mesh *me);
+
+#if defined(GL_EXT_texture_object) && !defined(__sun__) && !defined(__APPLE__)
+
+ /* exception for mesa... not according th opengl specs */
+ #ifndef __linux__
+ #define glBindTexture(A,B) glBindTextureEXT(A,B)
+ #endif
+
+ #define glGenTextures(A,B) glGenTexturesEXT(A,B)
+ #define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B)
+ #define glPolygonOffset(A,B) glPolygonOffsetEXT(A,B)
+
+#else
+
+/* #define GL_FUNC_ADD_EXT GL_FUNC_ADD */
+/* #define GL_FUNC_REVERSE_SUBTRACT_EXT GL_FUNC_REVERSE_SUBTRACT */
+/* #define GL_POLYGON_OFFSET_EXT GL_POLYGON_OFFSET */
+
+#endif
+
+ /* (n&(n-1)) zeros the least significant bit of n */
+static int is_pow2(int num) {
+ return ((num)&(num-1))==0;
+}
+static int smaller_pow2(int num) {
+ while (!is_pow2(num))
+ num= num&(num-1);
+ return num;
+}
+
+static int fCurtile=0, fCurmode=0,fCurtileXRep=0,fCurtileYRep=0;
+static Image *fCurpage=0;
+static short fTexwindx, fTexwindy, fTexwinsx, fTexwinsy;
+static int fDoMipMap = 1;
+static int fLinearMipMap = 0;
+
+/* static int source, dest; also not used */
+
+/**
+ * Enables or disable mipmapping for realtime images.
+ * @param mipmap Turn mipmapping on (mipmap!=0) or off (mipmap==0).
+ */
+void set_mipmap(int mipmap)
+{
+ if (fDoMipMap != (mipmap != 0)) {
+ free_all_realtime_images();
+ fDoMipMap = mipmap != 0;
+ }
+}
+
+
+/**
+ * Returns the current setting for mipmapping.
+ */
+int get_mipmap(void)
+{
+ return fDoMipMap;
+}
+
+/**
+ * Enables or disable linear mipmap setting for realtime images (textures).
+ * Note that this will will destroy all texture bindings in OpenGL.
+ * @see free_realtime_image()
+ * @param mipmap Turn linear mipmapping on (linear!=0) or off (linear==0).
+ */
+void set_linear_mipmap(int linear)
+{
+ if (fLinearMipMap != (linear != 0)) {
+ free_all_realtime_images();
+ fLinearMipMap = linear != 0;
+ }
+}
+
+/**
+ * Returns the current setting for linear mipmapping.
+ */
+int get_linear_mipmap(void)
+{
+ return fLinearMipMap;
+}
+
+
+/**
+ * Resets the realtime image cache variables.
+ */
+void clear_realtime_image_cache()
+{
+ fCurpage = NULL;
+ fCurtile = 0;
+ fCurmode = 0;
+ fCurtileXRep = 0;
+ fCurtileYRep = 0;
+}
+
+/* REMEMBER! Changes here must go into my_set_tpage() as well */
+int set_tpage(TFace *tface)
+{
+ static int alphamode= -1;
+ static TFace *lasttface= 0;
+ Image *ima;
+ unsigned int *rect, *bind;
+ int tpx, tpy, tilemode, tileXRep,tileYRep;
+
+ /* afschakelen */
+ if(tface==0) {
+ if(lasttface==0) return 0;
+
+ lasttface= 0;
+ fCurtile= 0;
+ fCurpage= 0;
+ if(fCurmode!=0) {
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ }
+ fCurmode= 0;
+ fCurtileXRep=0;
+ fCurtileYRep=0;
+ alphamode= -1;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+
+ return 0;
+ }
+ lasttface= tface;
+
+ if( alphamode != tface->transp) {
+ alphamode= tface->transp;
+
+ if(alphamode) {
+ glEnable(GL_BLEND);
+
+ if(alphamode==TF_ADD) {
+ glBlendFunc(GL_ONE, GL_ONE);
+ /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */
+ }
+ else if(alphamode==TF_ALPHA) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */
+ }
+ /* else { */
+ /* glBlendFunc(GL_ONE, GL_ONE); */
+ /* glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */
+ /* } */
+ }
+ else glDisable(GL_BLEND);
+ }
+
+ ima= tface->tpage;
+
+ /* Enable or disable reflection mapping */
+ if (ima && (ima->flag & IMA_REFLECT)){
+
+// glActiveTextureARB(GL_TEXTURE0_ARB);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+
+ /* Handle multitexturing here */
+ }
+ else{
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ }
+
+ tilemode= tface->mode & TF_TILES;
+ tileXRep = 0;
+ tileYRep = 0;
+ if (ima)
+ {
+ tileXRep = ima->xrep;
+ tileYRep = ima->yrep;
+ }
+
+
+ if(ima==fCurpage && fCurtile==tface->tile && tilemode==fCurmode && fCurtileXRep==tileXRep && fCurtileYRep == tileYRep) return ima!=0;
+
+ if(tilemode!=fCurmode || fCurtileXRep!=tileXRep || fCurtileYRep != tileYRep)
+ {
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+
+ if(tilemode && ima!=0)
+ glScalef(ima->xrep, ima->yrep, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ }
+
+ if(ima==0 || ima->ok==0) {
+ glDisable(GL_TEXTURE_2D);
+
+ fCurtile= tface->tile;
+ fCurpage= 0;
+ fCurmode= tilemode;
+ fCurtileXRep = tileXRep;
+ fCurtileYRep = tileYRep;
+
+ return 0;
+ }
+
+ if(ima->ibuf==0) {
+ load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
+
+ if(ima->ibuf==0) {
+ ima->ok= 0;
+
+ fCurtile= tface->tile;
+ fCurpage= 0;
+ fCurmode= tilemode;
+ fCurtileXRep = tileXRep;
+ fCurtileYRep = tileYRep;
+
+ glDisable(GL_TEXTURE_2D);
+ return 0;
+ }
+
+ }
+
+ if(ima->tpageflag & IMA_TWINANIM) fCurtile= ima->lastframe;
+ else fCurtile= tface->tile;
+
+ if(tilemode) {
+
+ if(ima->repbind==0) make_repbind(ima);
+
+ if(fCurtile>=ima->totbind) fCurtile= 0;
+
+ /* this happens when you change repeat buttons */
+ if(ima->repbind) bind= ima->repbind+fCurtile;
+ else bind= &ima->bindcode;
+
+ if(*bind==0) {
+
+ fTexwindx= ima->ibuf->x/ima->xrep;
+ fTexwindy= ima->ibuf->y/ima->yrep;
+
+ if(fCurtile>=ima->xrep*ima->yrep) fCurtile= ima->xrep*ima->yrep-1;
+
+ fTexwinsy= fCurtile / ima->xrep;
+ fTexwinsx= fCurtile - fTexwinsy*ima->xrep;
+
+ fTexwinsx*= fTexwindx;
+ fTexwinsy*= fTexwindy;
+
+ tpx= fTexwindx;
+ tpy= fTexwindy;
+
+ rect= ima->ibuf->rect + fTexwinsy*ima->ibuf->x + fTexwinsx;
+ }
+ }
+ else {
+ bind= &ima->bindcode;
+
+ if(*bind==0) {
+ tpx= ima->ibuf->x;
+ tpy= ima->ibuf->y;
+ rect= ima->ibuf->rect;
+ }
+ }
+
+ if(*bind==0) {
+ int rectw= tpx, recth= tpy;
+ unsigned int *tilerect= NULL, *scalerect= NULL;
+
+ /*
+ * Maarten:
+ * According to Ton this code is not needed anymore. It was used only
+ * in really old Blenders.
+ * Reevan:
+ * Actually it is needed for backwards compatibility. Simpledemo 6 does not display correctly without it.
+ */
+#if 1
+ if (tilemode) {
+ int y;
+
+ tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
+ for (y=0; y<recth; y++) {
+ unsigned int *rectrow= &rect[y*ima->ibuf->x];
+ unsigned int *tilerectrow= &tilerect[y*rectw];
+
+ memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
+ }
+
+ rect= tilerect;
+ }
+#endif
+ if (!is_pow2(rectw) || !is_pow2(recth)) {
+ rectw= smaller_pow2(rectw);
+ recth= smaller_pow2(recth);
+
+ scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
+ gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
+ rect= scalerect;
+ }
+
+ glGenTextures(1, bind);
+
+ if(G.f & G_DEBUG) {
+ printf("var1: %s\n", ima->id.name+2);
+ printf("var1: %d, var2: %d\n", *bind, tpx);
+ printf("var1: %d, var2: %d\n", fCurtile, tilemode);
+ }
+ glBindTexture( GL_TEXTURE_2D, *bind);
+
+ if (!fDoMipMap)
+ {
+ 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);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ } else
+ {
+ int minfilter= fLinearMipMap?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR_MIPMAP_NEAREST;
+
+ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 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);
+ }
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ if (tilerect)
+ MEM_freeN(tilerect);
+ if (scalerect)
+ MEM_freeN(scalerect);
+ }
+ else glBindTexture( GL_TEXTURE_2D, *bind);
+
+
+
+ glEnable(GL_TEXTURE_2D);
+
+ fCurpage= ima;
+ fCurmode= tilemode;
+ fCurtileXRep = tileXRep;
+ fCurtileYRep = tileYRep;
+
+ return 1;
+}
+
+void free_realtime_image(Image *ima)
+{
+ if(ima->bindcode) {
+ glDeleteTextures(1, &ima->bindcode);
+ ima->bindcode= 0;
+ }
+ if(ima->repbind) {
+ glDeleteTextures(ima->totbind, ima->repbind);
+
+ MEM_freeN(ima->repbind);
+ ima->repbind= 0;
+ }
+}
+
+void free_all_realtime_images(void)
+{
+ Image* ima;
+
+ ima= G.main->image.first;
+ while(ima) {
+ free_realtime_image(ima);
+ ima= ima->id.next;
+ }
+}
+
+void make_repbind(Image *ima)
+{
+ if(ima==0 || ima->ibuf==0) return;
+
+ if(ima->repbind) {
+ glDeleteTextures(ima->totbind, ima->repbind);
+ MEM_freeN(ima->repbind);
+ ima->repbind= 0;
+ }
+ ima->totbind= ima->xrep*ima->yrep;
+ if(ima->totbind>1) {
+ ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind");
+ }
+}
+
+void update_realtime_textures()
+{
+ Image *ima;
+
+ ima= G.main->image.first;
+ while(ima) {
+ if(ima->tpageflag & IMA_TWINANIM) {
+ if(ima->twend >= ima->xrep*ima->yrep) ima->twend= ima->xrep*ima->yrep-1;
+
+ /* check: zit de bindcode niet het array? Vrijgeven. (nog doen) */
+
+ ima->lastframe++;
+ if(ima->lastframe > ima->twend) ima->lastframe= ima->twsta;
+
+ }
+ ima= ima->id.next;
+ }
+}
+
+
+/* XXX, this routine should die but
+ * the great wisdom of NaN has inspired
+ * its progation.
+ */
+void spack(unsigned int ucol)
+{
+ char *cp= (char *)&ucol;
+
+ glColor3ub(cp[3], cp[2], cp[1]);
+}
+
+static void draw_hide_tfaces(Object *ob, Mesh *me)
+{
+ TFace *tface;
+ MFace *mface;
+ float *v1, *v2, *v3, *v4;
+ int a;
+
+ if(me==0 || me->tface==0) return;
+
+ mface= me->mface;
+ tface= me->tface;
+
+ cpack(0x0);
+ setlinestyle(1);
+ for(a=me->totface; a>0; a--, mface++, tface++) {
+ if(mface->v3==0) continue;
+
+ if( (tface->flag & TF_HIDE)) {
+
+ v1= (me->mvert+mface->v1)->co;
+ v2= (me->mvert+mface->v2)->co;
+ v3= (me->mvert+mface->v3)->co;
+ if(mface->v4) v4= (me->mvert+mface->v4)->co; else v4= 0;
+
+ glBegin(GL_LINE_LOOP);
+ glVertex3fv( v1 );
+ glVertex3fv( v2 );
+ glVertex3fv( v3 );
+ if(mface->v4) glVertex3fv( v4 );
+ glEnd();
+ }
+ }
+ setlinestyle(0);
+}
+
+
+void draw_tfaces3D(Object *ob, Mesh *me)
+{
+ MFace *mface;
+ TFace *tface;
+ DispList *dl;
+ float *v1, *v2, *v3, *v4, *extverts= NULL;
+ int a;
+
+ if(me==0 || me->tface==0) return;
+
+ glDisable(GL_DEPTH_TEST);
+
+ mface= me->mface;
+ tface= me->tface;
+
+ dl= find_displist(&ob->disp, DL_VERTS);
+ if (dl) extverts= dl->verts;
+
+ /* SELECT faces */
+ for(a=me->totface; a>0; a--, mface++, tface++) {
+ if(mface->v3==0) continue;
+ if(tface->flag & TF_HIDE) continue;
+
+ if( tface->flag & (TF_ACTIVE|TF_SELECT) ) {
+ if (extverts) {
+ v1= extverts+3*mface->v1;
+ v2= extverts+3*mface->v2;
+ v3= extverts+3*mface->v3;
+ v4= mface->v4?(extverts+3*mface->v4):NULL;
+ } else {
+ v1= (me->mvert+mface->v1)->co;
+ v2= (me->mvert+mface->v2)->co;
+ v3= (me->mvert+mface->v3)->co;
+ v4= mface->v4?(me->mvert+mface->v4)->co:NULL;
+ }
+
+ if(tface->flag & TF_ACTIVE) {
+ /* kleuren: R=x G=y */
+ cpack(0xFF);
+ glBegin(GL_LINE_STRIP); glVertex3fv(v1); if(v4) glVertex3fv(v4); else glVertex3fv(v3); glEnd();
+ cpack(0xFF00);
+ glBegin(GL_LINE_STRIP); glVertex3fv(v1); glVertex3fv(v2); glEnd();
+ cpack(0x0);
+ glBegin(GL_LINE_STRIP); glVertex3fv(v2); glVertex3fv(v3); if(v4) glVertex3fv(v4); glEnd();
+ }
+ else {
+ cpack(0x0);
+ glBegin(GL_LINE_LOOP);
+ glVertex3fv( v1 );
+ glVertex3fv( v2 );
+ glVertex3fv( v3 );
+ if(v4) glVertex3fv( v4 );
+ glEnd();
+ }
+
+ if(tface->flag & TF_SELECT) {
+ cpack(0xFFFFFF);
+ setlinestyle(1);
+ glBegin(GL_LINE_LOOP);
+ glVertex3fv( v1 );
+ glVertex3fv( v2 );
+ glVertex3fv( v3 );
+ if(v4) glVertex3fv( v4 );
+ glEnd();
+ setlinestyle(0);
+ }
+ }
+ }
+
+ glEnable(GL_DEPTH_TEST);
+}
+
+static int set_gl_light(Object *ob)
+{
+ Base *base;
+ Lamp *la;
+ int count;
+ /* float zero[4]= {0.0, 0.0, 0.0, 0.0}; */
+ float vec[4];
+
+ vec[3]= 1.0;
+
+ for(count=0; count<8; count++) glDisable(GL_LIGHT0+count);
+
+ count= 0;
+
+ base= FIRSTBASE;
+ while(base) {
+ if(base->object->type==OB_LAMP ) {
+ if(base->lay & G.vd->lay) {
+ if(base->lay & ob->lay)
+ {
+ la= base->object->data;
+
+ glPushMatrix();
+ glLoadMatrixf((float *)G.vd->viewmat);
+
+ where_is_object_simul(base->object);
+ VECCOPY(vec, base->object->obmat[3]);
+
+ if(la->type==LA_SUN) {
+ vec[0]= base->object->obmat[2][0];
+ vec[1]= base->object->obmat[2][1];
+ vec[2]= base->object->obmat[2][2];
+ vec[3]= 0.0;
+ glLightfv(GL_LIGHT0+count, GL_POSITION, vec);
+ }
+ else {
+ vec[3]= 1.0;
+ glLightfv(GL_LIGHT0+count, GL_POSITION, vec);
+ glLightf(GL_LIGHT0+count, GL_CONSTANT_ATTENUATION, 1.0);
+ glLightf(GL_LIGHT0+count, GL_LINEAR_ATTENUATION, la->att1/la->dist);
+ /* without this next line it looks backward compatible. attennuation still is acceptable */
+ /* glLightf(GL_LIGHT0+count, GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist)); */
+
+ if(la->type==LA_SPOT) {
+ vec[0]= -base->object->obmat[2][0];
+ vec[1]= -base->object->obmat[2][1];
+ vec[2]= -base->object->obmat[2][2];
+ glLightfv(GL_LIGHT0+count, GL_SPOT_DIRECTION, vec);
+ glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, la->spotsize/2.0);
+ glLightf(GL_LIGHT0+count, GL_SPOT_EXPONENT, 128.0*la->spotblend);
+ }
+ else glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, 180.0);
+ }
+
+ vec[0]= la->energy*la->r;
+ vec[1]= la->energy*la->g;
+ vec[2]= la->energy*la->b;
+ vec[3]= 1.0;
+ glLightfv(GL_LIGHT0+count, GL_DIFFUSE, vec);
+ glLightfv(GL_LIGHT0+count, GL_SPECULAR, vec);//zero);
+ glEnable(GL_LIGHT0+count);
+
+ glPopMatrix();
+
+ count++;
+ if(count>7) break;
+ }
+ }
+ }
+ base= base->next;
+ }
+
+ return count;
+}
+
+static Material *give_current_material_or_def(Object *ob, int matnr)
+{
+ extern Material defmaterial;
+ Material *ma= give_current_material(ob, matnr);
+
+ return ma?ma:&defmaterial;
+}
+
+static int set_draw_settings_cached(int clearcache, int textured, TFace *texface, int lit, Object *litob, int litmatnr, int doublesided)
+{
+ static int c_textured;
+ static int c_lit;
+ static int c_doublesided;
+ static TFace *c_texface;
+ static Object *c_litob;
+ static int c_litmatnr;
+ static int c_badtex;
+
+ if (clearcache) {
+ c_textured= c_lit= c_doublesided= -1;
+ c_texface= (TFace*) -1;
+ c_litob= (Object*) -1;
+ c_litmatnr= -1;
+ c_badtex= 0;
+ }
+
+ if (doublesided!=c_doublesided) {
+ if (doublesided) glDisable(GL_CULL_FACE);
+ else glEnable(GL_CULL_FACE);
+
+ c_doublesided= doublesided;
+ }
+
+ if (textured!=c_textured || texface!=c_texface) {
+ if (textured) {
+ c_badtex= !set_tpage(texface);
+ } else {
+ set_tpage(0);
+ c_badtex= 0;
+ }
+ c_textured= textured;
+ c_texface= texface;
+ }
+
+ if (c_badtex) lit= 0;
+ if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) {
+ if (lit) {
+ Material *ma= give_current_material_or_def(litob, litmatnr);
+ float spec[4];
+
+ spec[0]= ma->spec*ma->specr;
+ spec[1]= ma->spec*ma->specg;
+ spec[2]= ma->spec*ma->specb;
+ spec[3]= 1.0;
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ }
+ else {
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ }
+ c_lit= lit;
+ c_litob= litob;
+ c_litmatnr= litmatnr;
+ }
+
+ return c_badtex;
+}
+
+void draw_tface_mesh(Object *ob, Mesh *me, int dt) /* maximum dt: precies volgens ingestelde waardes */
+{
+ TFace *tface;
+ MFace *mface;
+ float *extverts= NULL;
+ unsigned char obcol[4];
+ int a, mode;
+ short islight, istex;
+
+ if (!me || !me->tface) return;
+
+
+ glShadeModel(GL_SMOOTH);
+
+ islight= set_gl_light(ob);
+
+ obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
+ obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
+ obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
+ obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
+
+ /* eerst alle texture polys */
+
+ glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
+ if(G.vd->drawtype==OB_TEXTURE) istex= 1;
+ else istex= 0;
+
+ set_draw_settings_cached(1, 0, 0, 0, 0, 0, 0);
+
+ if(dt > OB_SOLID) {
+ bProperty *prop = get_property(ob, "Text");
+ MFaceInt *mfaceint= NULL;
+ int editing= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
+ MVert *mvert;
+ int totface;
+
+ if (mesh_uses_displist(me) && !editing) {
+ DispList *dl= find_displist(&me->disp, DL_MESH);
+ DispListMesh *dlm= dl->mesh;
+
+ totface= dlm->totface;
+
+ if (!dl)
+ totface= 0;
+ else {
+ totface= dlm->totface;
+ mvert= dlm->mvert;
+ mfaceint= dlm->mface;
+ tface= dlm->tface;
+ }
+ } else {
+ DispList *dl= find_displist(&ob->disp, DL_VERTS);
+ if (dl) extverts= dl->verts;
+
+ totface= me->totface;
+ mvert= me->mvert;
+ mface= me->mface;
+ tface= me->tface;
+ }
+
+ for (a=0; a<totface; a++, tface++) {
+ int v1idx, v2idx, v3idx, v4idx, mf_smooth, matnr, badtex;
+ float *v1, *v2, *v3, *v4;
+
+ if (mfaceint) {
+ MFaceInt *mf= &mfaceint[a];
+
+ v1idx= mf->v1;
+ v2idx= mf->v2;
+ v3idx= mf->v3;
+ v4idx= mf->v4;
+ mf_smooth= mf->flag & ME_SMOOTH;
+ matnr= mf->mat_nr;
+ } else {
+ MFace *mf= &mface[a];
+
+ v1idx= mf->v1;
+ v2idx= mf->v2;
+ v3idx= mf->v3;
+ v4idx= mf->v4;
+ mf_smooth= mf->flag & ME_SMOOTH;
+ matnr= mf->mat_nr;
+ }
+
+ if(v3idx==0) continue;
+ if(tface->flag & TF_HIDE) continue;
+ if(tface->mode & TF_INVISIBLE) continue;
+
+ mode= tface->mode;
+
+ if (extverts) {
+ v1= extverts+3*v1idx;
+ v2= extverts+3*v2idx;
+ v3= extverts+3*v3idx;
+ v4= v4idx?(extverts+3*v4idx):NULL;
+ } else {
+ v1= (mvert+v1idx)->co;
+ v2= (mvert+v2idx)->co;
+ v3= (mvert+v3idx)->co;
+ v4= v4idx?(mvert+v4idx)->co:NULL;
+ }
+
+ badtex= set_draw_settings_cached(0, istex && (mode&TF_TEX), tface, islight && (mode&TF_LIGHT), ob, matnr, mode&TF_TWOSIDE);
+
+ if (prop && !badtex && !editing && (mode & TF_BMFONT)) {
+ char string[MAX_PROPSTRING];
+ int characters, index;
+ Image *ima;
+ float curpos;
+
+ // The BM_FONT handling code is duplicated in the gameengine
+ // Search for 'Frank van Beek' ;-)
+
+ // string = "Frank van Beek";
+
+ set_property_valstr(prop, string);
+ characters = strlen(string);
+
+ ima = tface->tpage;
+ if (ima == NULL) {
+ characters = 0;
+ }
+
+ if (1 || !mf_smooth) {
+ float nor[3];
+
+ CalcNormFloat(v1, v2, v3, nor);
+
+ glNormal3fv(nor);
+ }
+
+ curpos= 0.0;
+ glBegin(v4?GL_QUADS:GL_TRIANGLES);
+ for (index = 0; index < characters; index++) {
+ float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
+ int character = string[index];
+ char *cp= NULL;
+
+ // lets calculate offset stuff
+ // space starts at offset 1
+ // character = character - ' ' + 1;
+
+ matrixGlyph(ima->ibuf, character, & centerx, &centery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+ movex+= curpos;
+
+ if (mode & TF_OBCOL) glColor3ubv(obcol);
+ else cp= (char *)&(tface->col[0]);
+
+ glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
+
+ glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
+
+ glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
+
+ if(v4) {
+ glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
+ }
+
+ curpos+= advance;
+ }
+ glEnd();
+ }
+ else {
+ char *cp= NULL;
+
+ if (badtex) glColor3ub(0xFF, 0x00, 0xFF);
+ else if (mode & TF_OBCOL) glColor3ubv(obcol);
+ else cp= (char *)&(tface->col[0]);
+
+ if (!mf_smooth) {
+ float nor[3];
+
+ CalcNormFloat(v1, v2, v3, nor);
+
+ glNormal3fv(nor);
+ }
+
+ glBegin(v4?GL_QUADS:GL_TRIANGLES);
+
+ glTexCoord2fv(tface->uv[0]);
+ if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+ if (mf_smooth) glNormal3sv(mvert[v1idx].no);
+ glVertex3fv(v1);
+
+ glTexCoord2fv(tface->uv[1]);
+ if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+ if (mf_smooth) glNormal3sv(mvert[v2idx].no);
+ glVertex3fv(v2);
+
+ glTexCoord2fv(tface->uv[2]);
+ if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+ if (mf_smooth) glNormal3sv(mvert[v3idx].no);
+ glVertex3fv(v3);
+
+ if(v4) {
+ glTexCoord2fv(tface->uv[3]);
+ if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+ if (mf_smooth) glNormal3sv(mvert[v4idx].no);
+ glVertex3fv(v4);
+ }
+ glEnd();
+ }
+ }
+
+ /* textures uitzetten */
+ set_tpage(0);
+ }
+
+ glShadeModel(GL_FLAT);
+ glDisable(GL_CULL_FACE);
+
+ draw_hide_tfaces(ob, me);
+
+ if(ob==OBACT && (G.f & G_FACESELECT)) {
+ draw_tfaces3D(ob, me);
+ }
+
+ /* XXX, bad patch - default_gl_light() calls
+ * glLightfv(GL_LIGHT_POSITION, ...) which
+ * is transformed by the current matrix... we
+ * need to make sure that matrix is identity.
+ *
+ * It would be better if drawmesh.c kept track
+ * of and restored the light settings it changed.
+ * - zr
+ */
+ glPushMatrix();
+ glLoadIdentity();
+ default_gl_light();
+ glPopMatrix();
+}
+
+void init_realtime_GL(void)
+{
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+
+}
+