Revision: 15867 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15867 Author: blendix Date: 2008-07-29 17:48:31 +0200 (Tue, 29 Jul 2008)
Log Message: ----------- Game Engine: alpha blending and sorting ======================================= Alpha blending + sorting was revised, to fix bugs and get it to work more predictable. * A new per texture face "Sort" setting defines if the face is alpha sorted or not, instead of abusing the "ZTransp" setting as it did before. * Existing files are converted to hopefully match the old behavior as much as possible with a version patch. * On new meshes the Sort flag is disabled by the default, to avoid unexpected and hard to find slowdowns. * Alpha sorting for faces was incredibly slow. Sorting faces in a mesh with 600 faces lowered the framerate from 200 to 70 fps in my test.. the sorting there case goes about 15x faster now, but it is still advised to use Clip Alpha if possible instead of regular Alpha. * There still various limitations in the alpha sorting code, I've added some comments to the code about this. Some docs at the bottom of the page: http://www.blender.org/development/current-projects/changes-since-246/realtime-glsl-materials/ Merged some fixes from the apricot branch, most important change is that tangents are now exactly the same as the rest of Blender, instead of being computed in the game engine with a different algorithm. Also, the subversion was bumped to 1. Modified Paths: -------------- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h trunk/blender/source/blender/blenkernel/BKE_blender.h trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c trunk/blender/source/blender/blenkernel/intern/customdata.c trunk/blender/source/blender/blenloader/intern/readfile.c trunk/blender/source/blender/makesdna/DNA_customdata_types.h trunk/blender/source/blender/makesdna/DNA_meshdata_types.h trunk/blender/source/blender/src/buttons_editing.c trunk/blender/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp trunk/blender/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp trunk/blender/source/gameengine/Ketsji/BL_BlenderShader.cpp trunk/blender/source/gameengine/Ketsji/BL_BlenderShader.h trunk/blender/source/gameengine/Ketsji/BL_Material.h trunk/blender/source/gameengine/Ketsji/BL_Texture.cpp trunk/blender/source/gameengine/Ketsji/KX_BlenderMaterial.cpp trunk/blender/source/gameengine/Ketsji/KX_BlenderMaterial.h trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.cpp trunk/blender/source/gameengine/Ketsji/KX_PolygonMaterial.cpp trunk/blender/source/gameengine/Ketsji/KX_PolygonMaterial.h trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp trunk/blender/source/gameengine/Rasterizer/RAS_BucketManager.cpp trunk/blender/source/gameengine/Rasterizer/RAS_BucketManager.h trunk/blender/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp trunk/blender/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h trunk/blender/source/gameengine/Rasterizer/RAS_IRasterizer.h trunk/blender/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp trunk/blender/source/gameengine/Rasterizer/RAS_MaterialBucket.h trunk/blender/source/gameengine/Rasterizer/RAS_MeshObject.cpp trunk/blender/source/gameengine/Rasterizer/RAS_MeshObject.h trunk/blender/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp trunk/blender/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h trunk/blender/source/gameengine/Rasterizer/RAS_Polygon.cpp Removed Paths: ------------- trunk/blender/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp trunk/blender/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h =================================================================== --- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2008-07-29 15:27:03 UTC (rev 15866) +++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2008-07-29 15:48:31 UTC (rev 15867) @@ -437,5 +437,7 @@ /* determines required DerivedMesh data according to view and edit modes */ CustomDataMask get_viewedit_datamask(); +void DM_add_tangent_layer(DerivedMesh *dm); + #endif Modified: trunk/blender/source/blender/blenkernel/BKE_blender.h =================================================================== --- trunk/blender/source/blender/blenkernel/BKE_blender.h 2008-07-29 15:27:03 UTC (rev 15866) +++ trunk/blender/source/blender/blenkernel/BKE_blender.h 2008-07-29 15:48:31 UTC (rev 15867) @@ -41,7 +41,7 @@ struct MemFile; #define BLENDER_VERSION 246 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 #define BLENDER_MINVERSION 245 #define BLENDER_MINSUBVERSION 15 Modified: trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c =================================================================== --- trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c 2008-07-29 15:27:03 UTC (rev 15866) +++ trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c 2008-07-29 15:48:31 UTC (rev 15867) @@ -59,6 +59,7 @@ #include "BLI_edgehash.h" #include "BLI_editVert.h" #include "BLI_linklist.h" +#include "BLI_memarena.h" #include "BKE_cdderivedmesh.h" #include "BKE_customdata.h" @@ -2844,6 +2845,127 @@ return numleft; } +void DM_add_tangent_layer(DerivedMesh *dm) +{ + /* mesh vars */ + MTFace *mtface, *tf; + MFace *mface, *mf; + MVert *mvert, *v1, *v2, *v3, *v4; + MemArena *arena= NULL; + VertexTangent **vtangents= NULL; + float (*orco)[3]= NULL, (*tangent)[3]; + float *uv1, *uv2, *uv3, *uv4, *vtang; + float fno[3], tang[3], uv[4][2]; + int i, j, len, mf_vi[4], totvert, totface; + + if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1) + return; + + /* check we have all the needed layers */ + totvert= dm->getNumVerts(dm); + totface= dm->getNumFaces(dm); + + mvert= dm->getVertArray(dm); + mface= dm->getFaceArray(dm); + mtface= dm->getFaceDataArray(dm, CD_MTFACE); + + if(!mtface) { + orco= dm->getVertDataArray(dm, CD_ORCO); + if(!orco) + return; + } + + /* create tangent layer */ + DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL); + tangent= DM_get_face_data_layer(dm, CD_TANGENT); + + /* allocate some space */ + arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_calloc(arena); + vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent"); + + /* sum tangents at connected vertices */ + for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) { + v1= &mvert[mf->v1]; + v2= &mvert[mf->v2]; + v3= &mvert[mf->v3]; + + if (mf->v4) { + v4= &mvert[mf->v4]; + CalcNormFloat4(v4->co, v3->co, v2->co, v1->co, fno); + } + else { + v4= NULL; + CalcNormFloat(v3->co, v2->co, v1->co, fno); + } + + if(mtface) { + uv1= tf->uv[0]; + uv2= tf->uv[1]; + uv3= tf->uv[2]; + uv4= tf->uv[3]; + } + else { + uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3]; + spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]); + spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]); + spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]); + if(v4) + spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]); + } + + tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); + + if(mf->v4) { + v4= &mvert[mf->v4]; + + tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4); + } + } + + /* write tangent to layer */ + for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) { + len= (mf->v4)? 4 : 3; + + if(mtface) { + uv1= tf->uv[0]; + uv2= tf->uv[1]; + uv3= tf->uv[2]; + uv4= tf->uv[3]; + } + else { + uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3]; + spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]); + spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]); + spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]); + if(len==4) + spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]); + } + + mf_vi[0]= mf->v1; + mf_vi[1]= mf->v2; + mf_vi[2]= mf->v3; + mf_vi[3]= mf->v4; + + for(j=0; j<len; j++) { + vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]); + + VECCOPY(tangent[j], vtang); + Normalize(tangent[j]); + } + } + + BLI_memarena_free(arena); + MEM_freeN(vtangents); +} + + /* ************************* fluidsim bobj file handling **************************** */ #ifndef DISABLE_ELBEEM Modified: trunk/blender/source/blender/blenkernel/intern/customdata.c =================================================================== --- trunk/blender/source/blender/blenkernel/intern/customdata.c 2008-07-29 15:27:03 UTC (rev 15866) +++ trunk/blender/source/blender/blenkernel/intern/customdata.c 2008-07-29 15:48:31 UTC (rev 15867) @@ -532,13 +532,14 @@ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL}, {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL}, - {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol} + {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}, + {sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", - "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"}; + "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; @@ -552,7 +553,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | - CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO; + CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT; const CustomDataMask CD_MASK_BMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; const CustomDataMask CD_MASK_FACECORNERS = Modified: trunk/blender/source/blender/blenloader/intern/readfile.c =================================================================== --- trunk/blender/source/blender/blenloader/intern/readfile.c 2008-07-29 15:27:03 UTC (rev 15866) +++ trunk/blender/source/blender/blenloader/intern/readfile.c 2008-07-29 15:48:31 UTC (rev 15867) @@ -4870,6 +4870,49 @@ } } +void alphasort_version_246(FileData *fd, Library *lib, Mesh *me) +{ + Material *ma; + MFace *mf; + MTFace *tf; + int a, b, texalpha; + + /* verify we have a tface layer */ + for(b=0; b<me->fdata.totlayer; b++) + if(me->fdata.layers[b].type == CD_MTFACE) + break; + + if(b == me->fdata.totlayer) + return; + + /* if we do, set alpha sort if the game engine did it before */ + for(a=0, mf=me->mface; a<me->totface; a++, mf++) { + if(mf->mat_nr < me->totcol) { + ma= newlibadr(fd, lib, me->mat[mf->mat_nr]); + texalpha = 0; + + for(b=0; ma && b<MAX_MTEX; b++) + if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA) + texalpha = 1; + } + else { + ma= NULL; + texalpha = 0; + } + + for(b=0; b<me->fdata.totlayer; b++) { + if(me->fdata.layers[b].type == CD_MTFACE) { + tf = ((MTFace*)me->fdata.layers[b].data) + a; + + tf->mode &= ~TF_ALPHASORT; + if(ma && (ma->mode & MA_ZTRA)) + if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP))) + tf->mode |= TF_ALPHASORT; + } + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -7714,8 +7757,9 @@ } /* sun/sky */ - if ((main->versionfile < 246) ){ + if(main->versionfile < 246) { Lamp *la; + for(la=main->lamp.first; la; la= la->id.next) { la->sun_effect_type = 0; la->horizon_brightness = 1.0; @@ -7731,6 +7775,13 @@ } } + if(main->versionfile <= 246 && main->subversionfile < 1){ + Mesh *me; + + for(me=main->mesh.first; me; me= me->id.next) + alphasort_version_246(fd, lib, me); + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ Modified: trunk/blender/source/blender/makesdna/DNA_customdata_types.h =================================================================== --- trunk/blender/source/blender/makesdna/DNA_customdata_types.h 2008-07-29 15:27:03 UTC (rev 15866) +++ trunk/blender/source/blender/makesdna/DNA_customdata_types.h 2008-07-29 15:48:31 UTC (rev 15867) @@ -71,7 +71,8 @@ #define CD_MTEXPOLY 15 #define CD_MLOOPUV 16 #define CD_MLOOPCOL 17 -#define CD_NUMTYPES 18 +#define CD_TANGENT 18 +#define CD_NUMTYPES 19 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -92,6 +93,7 @@ #define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY) #define CD_MASK_MLOOPUV (1 << CD_MLOOPUV) #define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL) +#define CD_MASK_TANGENT (1 << CD_TANGENT) /* CustomData.flag */ Modified: trunk/blender/source/blender/makesdna/DNA_meshdata_types.h =================================================================== --- trunk/blender/source/blender/makesdna/DNA_meshdata_types.h 2008-07-29 15:27:03 UTC (rev 15866) +++ trunk/blender/source/blender/makesdna/DNA_meshdata_types.h 2008-07-29 15:48:31 UTC (rev 15867) @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs