forked from bartvdbraak/blender
BGE: Some as of yet unmerged work I did in the Swiss branch. These changes include:
* Cleaning up the conversion code to avoid a per-face material conversion. Materials are now stored in buckets and only converted if a new material is found. This replaces some of Campbell's earlier work on the subject. His work wasn't as thorough, but it was much safer for a release. * Shaders are only compiled for LibLoaded materials once. Before they could be compiled twice, which could really slow things down. * Refactoring the rasterizer code to use a strategy design pattern to handle different geometry rendering methods such as immediate mode, vertex arrays and vertex buffer objects. VBOs are added, but they will be disabled in a following commit since they are still slower than vertex arrays with display lists. However, VBOs are still useful for mobile, so it's good to keep them around. * Better multi-uv support. The BGE should now be able to handle more than two UV layers, which should help it better match the viewport.
This commit is contained in:
parent
6b2af22d37
commit
ef0473994b
@ -402,14 +402,18 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
col = layout.column()
|
||||
row = col.row()
|
||||
col = row.column()
|
||||
col.prop(gs, "use_frame_rate")
|
||||
col.prop(gs, "restrict_animation_updates")
|
||||
col = row.column()
|
||||
col.prop(gs, "use_display_lists")
|
||||
col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
|
||||
|
||||
row = layout.row()
|
||||
row.prop(gs, "use_frame_rate")
|
||||
row.prop(gs, "restrict_animation_updates")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(gs, "use_display_lists")
|
||||
|
||||
row.prop(gs, "raster_storage")
|
||||
|
||||
row = layout.row()
|
||||
row.label("Exit Key")
|
||||
row.prop(gs, "exit_key", text="", event=True)
|
||||
|
@ -636,7 +636,8 @@ typedef struct GameData {
|
||||
short physicsEngine;
|
||||
short exitkey, pad;
|
||||
short ticrate, maxlogicstep, physubstep, maxphystep;
|
||||
short obstacleSimulation, pad1;
|
||||
short obstacleSimulation;
|
||||
short raster_storage;
|
||||
float levelHeight;
|
||||
float deactivationtime, lineardeactthreshold, angulardeactthreshold, pad2;
|
||||
} GameData;
|
||||
@ -663,6 +664,12 @@ typedef struct GameData {
|
||||
#define OBSTSIMULATION_TOI_rays 1
|
||||
#define OBSTSIMULATION_TOI_cells 2
|
||||
|
||||
/* Raster storage */
|
||||
#define RAS_STORE_AUTO 0
|
||||
#define RAS_STORE_IMMEDIATE 1
|
||||
#define RAS_STORE_VA 2
|
||||
#define RAS_STORE_VBO 3
|
||||
|
||||
/* GameData.flag */
|
||||
#define GAME_RESTRICT_ANIM_UPDATES (1 << 0)
|
||||
#define GAME_ENABLE_ALL_FRAMES (1 << 1)
|
||||
|
@ -2444,6 +2444,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem storage_items[] ={
|
||||
{RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"},
|
||||
{RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"},
|
||||
{RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Moderate performance, requires at least OpenGL 1.1"},
|
||||
{RAS_STORE_VBO, "VERTEX_BUFFER_OBJECT", 0, "Vertex Buffer Objects", "Best performance, requires at least OpenGL 1.4"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna = RNA_def_struct(brna, "SceneGameData", NULL);
|
||||
RNA_def_struct_sdna(srna, "GameData");
|
||||
RNA_def_struct_nested(brna, srna, "Scene");
|
||||
@ -2479,6 +2486,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine");
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "raster_storage", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "raster_storage");
|
||||
RNA_def_property_enum_items(prop, storage_items);
|
||||
RNA_def_property_ui_text(prop, "Storage", "Sets the storage mode used by the rasterizer");
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
/* Do we need it here ? (since we already have it in World */
|
||||
prop = RNA_def_property(srna, "frequency", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "freqplay");
|
||||
|
@ -58,7 +58,6 @@
|
||||
|
||||
#include "RAS_GLExtensionManager.h"
|
||||
#include "RAS_OpenGLRasterizer.h"
|
||||
#include "RAS_VAOpenGLRasterizer.h"
|
||||
#include "RAS_ListRasterizer.h"
|
||||
|
||||
#include "NG_LoopBackNetworkDeviceInterface.h"
|
||||
@ -287,16 +286,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
|
||||
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
|
||||
RAS_IRasterizer* rasterizer = NULL;
|
||||
|
||||
if (displaylists) {
|
||||
if (GLEW_VERSION_1_1 && !novertexarrays)
|
||||
rasterizer = new RAS_ListRasterizer(canvas, true, true);
|
||||
else
|
||||
rasterizer = new RAS_ListRasterizer(canvas);
|
||||
}
|
||||
else if (GLEW_VERSION_1_1 && !novertexarrays)
|
||||
rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
|
||||
//Don't use displaylists with VBOs
|
||||
//If auto starts using VBOs, make sure to check for that here
|
||||
if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO)
|
||||
rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage);
|
||||
else
|
||||
rasterizer = new RAS_OpenGLRasterizer(canvas);
|
||||
rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage);
|
||||
|
||||
// create the inputdevices
|
||||
KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
|
||||
|
@ -423,55 +423,61 @@ static void SetDefaultLightMode(Scene* scene)
|
||||
|
||||
|
||||
// --
|
||||
static void GetRGB(
|
||||
const bool use_mcol,
|
||||
MFace *mface,
|
||||
MCol *mmcol,
|
||||
Material *mat,
|
||||
unsigned int &c0,
|
||||
unsigned int &c1,
|
||||
unsigned int &c2,
|
||||
unsigned int &c3)
|
||||
static void GetRGB(short type,
|
||||
MFace* mface,
|
||||
MCol* mmcol,
|
||||
Material *mat,
|
||||
unsigned int c[4])
|
||||
{
|
||||
unsigned int color = 0xFFFFFFFFL;
|
||||
if (use_mcol) {
|
||||
// vertex colors
|
||||
|
||||
if (mmcol) {
|
||||
c0 = KX_Mcol2uint_new(mmcol[0]);
|
||||
c1 = KX_Mcol2uint_new(mmcol[1]);
|
||||
c2 = KX_Mcol2uint_new(mmcol[2]);
|
||||
switch (type) {
|
||||
case 0: // vertex colors
|
||||
{
|
||||
if (mmcol) {
|
||||
c[0] = KX_Mcol2uint_new(mmcol[0]);
|
||||
c[1] = KX_Mcol2uint_new(mmcol[1]);
|
||||
c[2] = KX_Mcol2uint_new(mmcol[2]);
|
||||
if (mface->v4)
|
||||
c[3] = KX_Mcol2uint_new(mmcol[3]);
|
||||
}
|
||||
else { // backup white
|
||||
c[0] = KX_rgbaint2uint_new(color);
|
||||
c[1] = KX_rgbaint2uint_new(color);
|
||||
c[2] = KX_rgbaint2uint_new(color);
|
||||
if (mface->v4)
|
||||
c[3] = KX_rgbaint2uint_new( color );
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
case 1: // material rgba
|
||||
{
|
||||
if (mat) {
|
||||
union {
|
||||
unsigned char cp[4];
|
||||
unsigned int integer;
|
||||
} col_converter;
|
||||
col_converter.cp[3] = (unsigned char) (mat->r * 255.0f);
|
||||
col_converter.cp[2] = (unsigned char) (mat->g * 255.0f);
|
||||
col_converter.cp[1] = (unsigned char) (mat->b * 255.0f);
|
||||
col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
|
||||
color = col_converter.integer;
|
||||
}
|
||||
c[0] = KX_rgbaint2uint_new(color);
|
||||
c[1] = KX_rgbaint2uint_new(color);
|
||||
c[2] = KX_rgbaint2uint_new(color);
|
||||
if (mface->v4)
|
||||
c3 = KX_Mcol2uint_new(mmcol[3]);
|
||||
}
|
||||
else { // backup white
|
||||
c0 = KX_rgbaint2uint_new(color);
|
||||
c1 = KX_rgbaint2uint_new(color);
|
||||
c2 = KX_rgbaint2uint_new(color);
|
||||
c[3] = KX_rgbaint2uint_new(color);
|
||||
} break;
|
||||
|
||||
default: // white
|
||||
{
|
||||
c[0] = KX_rgbaint2uint_new(color);
|
||||
c[1] = KX_rgbaint2uint_new(color);
|
||||
c[2] = KX_rgbaint2uint_new(color);
|
||||
if (mface->v4)
|
||||
c3 = KX_rgbaint2uint_new( color );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// material rgba
|
||||
if (mat) {
|
||||
union {
|
||||
unsigned char cp[4];
|
||||
unsigned int integer;
|
||||
} col_converter;
|
||||
col_converter.cp[3] = (unsigned char) (mat->r * 255.0f);
|
||||
col_converter.cp[2] = (unsigned char) (mat->g * 255.0f);
|
||||
col_converter.cp[1] = (unsigned char) (mat->b * 255.0f);
|
||||
col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
|
||||
color = col_converter.integer;
|
||||
}
|
||||
// backup white is fallback
|
||||
|
||||
c0 = KX_rgbaint2uint_new(color);
|
||||
c1 = KX_rgbaint2uint_new(color);
|
||||
c2 = KX_rgbaint2uint_new(color);
|
||||
if (mface->v4)
|
||||
c3 = KX_rgbaint2uint_new(color);
|
||||
c[3] = KX_rgbaint2uint_new(color);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,42 +486,67 @@ typedef struct MTF_localLayer {
|
||||
const char *name;
|
||||
} MTF_localLayer;
|
||||
|
||||
static void tface_to_uv_bge(const MFace *mface, const MTFace *tface, MT_Point2 uv[4])
|
||||
static void GetUVs(BL_Material *material, MTF_localLayer *layers, MFace *mface, MTFace *tface, MT_Point2 uvs[4][MAXTEX])
|
||||
{
|
||||
uv[0].setValue(tface->uv[0]);
|
||||
uv[1].setValue(tface->uv[1]);
|
||||
uv[2].setValue(tface->uv[2]);
|
||||
if (mface->v4) {
|
||||
uv[3].setValue(tface->uv[3]);
|
||||
int unit = 0;
|
||||
if (tface)
|
||||
{
|
||||
|
||||
uvs[0][0].setValue(tface->uv[0]);
|
||||
uvs[1][0].setValue(tface->uv[1]);
|
||||
uvs[2][0].setValue(tface->uv[2]);
|
||||
|
||||
if (mface->v4)
|
||||
uvs[3][0].setValue(tface->uv[3]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uvs[0][0] = uvs[1][0] = uvs[2][0] = uvs[3][0] = MT_Point2(0.f, 0.f);
|
||||
}
|
||||
|
||||
for (int vind = 0; vind<MAXTEX; vind++)
|
||||
{
|
||||
BL_Mapping &map = material->mapping[vind];
|
||||
|
||||
static void GetUV(
|
||||
MFace *mface,
|
||||
MTFace *tface,
|
||||
MTF_localLayer *layers,
|
||||
const int layer_uv[2],
|
||||
MT_Point2 uv[4],
|
||||
MT_Point2 uv2[4])
|
||||
{
|
||||
bool validface = (tface != NULL);
|
||||
if (!(map.mapping & USEUV)) continue;
|
||||
|
||||
uv2[0] = uv2[1] = uv2[2] = uv2[3] = MT_Point2(0.0f, 0.0f);
|
||||
//If no UVSet is specified, try grabbing one from the UV/Image editor
|
||||
if (map.uvCoName.IsEmpty() && tface)
|
||||
{
|
||||
uvs[0][unit].setValue(tface->uv[0]);
|
||||
uvs[1][unit].setValue(tface->uv[1]);
|
||||
uvs[2][unit].setValue(tface->uv[2]);
|
||||
|
||||
/* No material, what to do? let's see what is in the UV and set the material accordingly
|
||||
* light and visible is always on */
|
||||
if (layer_uv[0] != -1) {
|
||||
tface_to_uv_bge(mface, layers[layer_uv[0]].face, uv);
|
||||
if (layer_uv[1] != -1) {
|
||||
tface_to_uv_bge(mface, layers[layer_uv[1]].face, uv2);
|
||||
if (mface->v4)
|
||||
uvs[3][unit].setValue(tface->uv[3]);
|
||||
|
||||
++unit;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for (int lay=0; lay<MAX_MTFACE; lay++)
|
||||
{
|
||||
MTF_localLayer& layer = layers[lay];
|
||||
if (layer.face == 0) break;
|
||||
|
||||
if (map.uvCoName.IsEmpty() || strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
|
||||
{
|
||||
MT_Point2 uvSet[4];
|
||||
|
||||
uvs[0][unit].setValue(layer.face->uv[0]);
|
||||
uvs[1][unit].setValue(layer.face->uv[1]);
|
||||
uvs[2][unit].setValue(layer.face->uv[2]);
|
||||
|
||||
if (mface->v4)
|
||||
uvs[3][unit].setValue(layer.face->uv[3]);
|
||||
else
|
||||
uvs[3][unit].setValue(0.0f, 0.0f);
|
||||
|
||||
++unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (validface) {
|
||||
tface_to_uv_bge(mface, tface, uv);
|
||||
}
|
||||
else {
|
||||
// nothing at all
|
||||
uv[0] = uv[1] = uv[2] = uv[3] = MT_Point2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -526,25 +557,29 @@ static bool ConvertMaterial(
|
||||
MTFace* tface,
|
||||
const char *tfaceName,
|
||||
MFace* mface,
|
||||
MCol* mmcol, /* only for text, use first mcol, weak */
|
||||
MTF_localLayer *layers,
|
||||
int layer_uv[2],
|
||||
const bool glslmat)
|
||||
MCol* mmcol,
|
||||
bool glslmat)
|
||||
{
|
||||
material->Initialize();
|
||||
int numchan = -1, texalpha = 0;
|
||||
int texalpha = 0;
|
||||
bool validmat = (mat!=0);
|
||||
bool validface = (tface!=0);
|
||||
|
||||
short type = 0;
|
||||
if ( validmat )
|
||||
type = 1; // material color
|
||||
|
||||
material->IdMode = DEFAULT_BLENDER;
|
||||
material->glslmat = (validmat)? glslmat: false;
|
||||
material->materialindex = mface->mat_nr;
|
||||
|
||||
/* default value for being unset */
|
||||
layer_uv[0] = layer_uv[1] = -1;
|
||||
|
||||
// --------------------------------
|
||||
if (validmat) {
|
||||
|
||||
// use vertex colors by explicitly setting
|
||||
if (mat->mode &MA_VERTEXCOLP || glslmat)
|
||||
type = 0;
|
||||
|
||||
// use lighting?
|
||||
material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
|
||||
material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED;
|
||||
@ -552,7 +587,6 @@ static bool ConvertMaterial(
|
||||
// cast shadows?
|
||||
material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0;
|
||||
MTex *mttmp = 0;
|
||||
numchan = getNumTexChannels(mat);
|
||||
int valid_index = 0;
|
||||
|
||||
/* In Multitexture use the face texture if and only if
|
||||
@ -561,12 +595,9 @@ static bool ConvertMaterial(
|
||||
bool facetex = false;
|
||||
if (validface && mat->mode &MA_FACETEXTURE)
|
||||
facetex = true;
|
||||
|
||||
numchan = numchan>MAXTEX?MAXTEX:numchan;
|
||||
if (facetex && numchan == 0) numchan = 1;
|
||||
|
||||
// foreach MTex
|
||||
for (int i=0; i<numchan; i++) {
|
||||
for (int i=0; i<MAXTEX; i++) {
|
||||
// use face tex
|
||||
|
||||
if (i==0 && facetex ) {
|
||||
@ -798,14 +829,11 @@ static bool ConvertMaterial(
|
||||
material->ras_mode |= USE_LIGHT;
|
||||
}
|
||||
|
||||
const char *uvName = "", *uv2Name = "";
|
||||
|
||||
/* No material, what to do? let's see what is in the UV and set the material accordingly
|
||||
* light and visible is always on */
|
||||
if ( validface ) {
|
||||
material->tile = tface->tile;
|
||||
uvName = tfaceName;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// nothing at all
|
||||
material->alphablend = GEMAT_SOLID;
|
||||
@ -826,46 +854,20 @@ static bool ConvertMaterial(
|
||||
material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0;
|
||||
}
|
||||
|
||||
// get uv sets
|
||||
if (validmat) {
|
||||
bool isFirstSet = true;
|
||||
// XXX The RGB values here were meant to be temporary storage for the conversion process,
|
||||
// but fonts now make use of them too, so we leave them in for now.
|
||||
unsigned int rgb[4];
|
||||
GetRGB(type,mface,mmcol,mat,rgb);
|
||||
|
||||
// only two sets implemented, but any of the eight
|
||||
// sets can make up the two layers
|
||||
for (int vind = 0; vind<material->num_enabled; vind++) {
|
||||
BL_Mapping &map = material->mapping[vind];
|
||||
|
||||
if (map.uvCoName.IsEmpty()) {
|
||||
isFirstSet = false;
|
||||
}
|
||||
else {
|
||||
for (int lay=0; lay<MAX_MTFACE; lay++) {
|
||||
MTF_localLayer& layer = layers[lay];
|
||||
if (layer.face == 0) break;
|
||||
|
||||
if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) {
|
||||
if (isFirstSet) {
|
||||
layer_uv[0] = lay;
|
||||
isFirstSet = false;
|
||||
uvName = layer.name;
|
||||
}
|
||||
else if (strcmp(layer.name, uvName) != 0) {
|
||||
layer_uv[1] = lay;
|
||||
map.mapping |= USECUSTOMUV;
|
||||
uv2Name = layer.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// swap the material color, so MCol on bitmap font works
|
||||
if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT))
|
||||
{
|
||||
rgb[0] = KX_rgbaint2uint_new(rgb[0]);
|
||||
rgb[1] = KX_rgbaint2uint_new(rgb[1]);
|
||||
rgb[2] = KX_rgbaint2uint_new(rgb[2]);
|
||||
rgb[3] = KX_rgbaint2uint_new(rgb[3]);
|
||||
}
|
||||
|
||||
if (validmat && mmcol) { /* color is only for text */
|
||||
material->m_mcol = *(unsigned int *)mmcol;
|
||||
}
|
||||
material->SetUVLayerName(uvName);
|
||||
material->SetUVLayerName2(uv2Name);
|
||||
|
||||
if (validmat)
|
||||
material->matname =(mat->id.name);
|
||||
|
||||
@ -879,8 +881,189 @@ static bool ConvertMaterial(
|
||||
return true;
|
||||
}
|
||||
|
||||
RAS_MaterialBucket* material_from_mesh(Material *ma, MFace *mface, MTFace *tface, MCol *mcol, MTF_localLayer *layers, int lightlayer, unsigned int *rgb, MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT], const char *tfaceName, KX_Scene* scene, KX_BlenderSceneConverter *converter)
|
||||
{
|
||||
RAS_IPolyMaterial* polymat = converter->FindCachedPolyMaterial(ma);
|
||||
BL_Material* bl_mat = converter->FindCachedBlenderMaterial(ma);
|
||||
KX_BlenderMaterial* kx_blmat = NULL;
|
||||
KX_PolygonMaterial* kx_polymat = NULL;
|
||||
|
||||
if (converter->GetMaterials()) {
|
||||
/* do Blender Multitexture and Blender GLSL materials */
|
||||
|
||||
/* first is the BL_Material */
|
||||
if (!bl_mat)
|
||||
{
|
||||
bl_mat = new BL_Material();
|
||||
|
||||
ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
|
||||
converter->GetGLSLMaterials());
|
||||
|
||||
converter->CacheBlenderMaterial(ma, bl_mat);
|
||||
}
|
||||
|
||||
|
||||
short type = (ma) ? ((ma->mode & MA_VERTEXCOLP || bl_mat->glslmat) ? 0 : 1) : 0;
|
||||
GetRGB(type,mface,mcol,ma,rgb);
|
||||
|
||||
GetUVs(bl_mat, layers, mface, tface, uvs);
|
||||
|
||||
/* then the KX_BlenderMaterial */
|
||||
if (polymat == NULL)
|
||||
{
|
||||
kx_blmat = new KX_BlenderMaterial();
|
||||
|
||||
kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer);
|
||||
polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
|
||||
converter->CachePolyMaterial(ma, polymat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* do Texture Face materials */
|
||||
Image* bima = (tface)? (Image*)tface->tpage: NULL;
|
||||
STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
|
||||
|
||||
char alpha_blend=0;
|
||||
short tile=0;
|
||||
int tilexrep=4,tileyrep = 4;
|
||||
|
||||
/* set material properties - old TexFace */
|
||||
if (ma) {
|
||||
alpha_blend = ma->game.alpha_blend;
|
||||
/* Commented out for now. If we ever get rid of
|
||||
* "Texture Face/Singletexture" we can then think about it */
|
||||
|
||||
/* Texture Face mode ignores texture but requires "Face Textures to be True "*/
|
||||
#if 0
|
||||
if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
|
||||
bima = NULL;
|
||||
imastr = "";
|
||||
alpha_blend = GEMAT_SOLID;
|
||||
}
|
||||
else {
|
||||
alpha_blend = ma->game.alpha_blend;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* check for tface tex to fallback on */
|
||||
else {
|
||||
if (bima) {
|
||||
/* see if depth of the image is 32 */
|
||||
if (BKE_image_has_alpha(bima))
|
||||
alpha_blend = GEMAT_ALPHA;
|
||||
else
|
||||
alpha_blend = GEMAT_SOLID;
|
||||
}
|
||||
else {
|
||||
alpha_blend = GEMAT_SOLID;
|
||||
}
|
||||
}
|
||||
|
||||
if (bima) {
|
||||
tilexrep = bima->xrep;
|
||||
tileyrep = bima->yrep;
|
||||
}
|
||||
|
||||
/* set UV properties */
|
||||
if (tface) {
|
||||
uvs[0][0].setValue(tface->uv[0]);
|
||||
uvs[1][0].setValue(tface->uv[1]);
|
||||
uvs[2][0].setValue(tface->uv[2]);
|
||||
|
||||
if (mface->v4)
|
||||
uvs[3][0].setValue(tface->uv[3]);
|
||||
|
||||
tile = tface->tile;
|
||||
}
|
||||
else {
|
||||
/* no texfaces */
|
||||
tile = 0;
|
||||
}
|
||||
|
||||
/* get vertex colors */
|
||||
if (mcol) {
|
||||
/* we have vertex colors */
|
||||
rgb[0] = KX_Mcol2uint_new(mcol[0]);
|
||||
rgb[1] = KX_Mcol2uint_new(mcol[1]);
|
||||
rgb[2] = KX_Mcol2uint_new(mcol[2]);
|
||||
|
||||
if (mface->v4)
|
||||
rgb[3] = KX_Mcol2uint_new(mcol[3]);
|
||||
}
|
||||
else {
|
||||
/* no vertex colors, take from material, otherwise white */
|
||||
unsigned int color = 0xFFFFFFFFL;
|
||||
|
||||
if (ma)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char cp[4];
|
||||
unsigned int integer;
|
||||
} col_converter;
|
||||
|
||||
col_converter.cp[3] = (unsigned char) (ma->r*255.0);
|
||||
col_converter.cp[2] = (unsigned char) (ma->g*255.0);
|
||||
col_converter.cp[1] = (unsigned char) (ma->b*255.0);
|
||||
col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
|
||||
|
||||
color = col_converter.integer;
|
||||
}
|
||||
|
||||
rgb[0] = KX_rgbaint2uint_new(color);
|
||||
rgb[1] = KX_rgbaint2uint_new(color);
|
||||
rgb[2] = KX_rgbaint2uint_new(color);
|
||||
|
||||
if (mface->v4)
|
||||
rgb[3] = KX_rgbaint2uint_new(color);
|
||||
}
|
||||
|
||||
// only zsort alpha + add
|
||||
bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
|
||||
bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
|
||||
bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
|
||||
|
||||
// don't need zort anymore, deal as if it it's alpha blend
|
||||
if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
|
||||
|
||||
if (polymat == NULL)
|
||||
{
|
||||
kx_polymat = new KX_PolygonMaterial();
|
||||
kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
|
||||
tile, tilexrep, tileyrep,
|
||||
alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
|
||||
polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
|
||||
|
||||
if (ma) {
|
||||
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
|
||||
polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
|
||||
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
|
||||
}
|
||||
else {
|
||||
polymat->m_specular.setValue(0.0f,0.0f,0.0f);
|
||||
polymat->m_shininess = 35.0;
|
||||
}
|
||||
|
||||
converter->CachePolyMaterial(ma, polymat);
|
||||
}
|
||||
}
|
||||
|
||||
// see if a bucket was reused or a new one was created
|
||||
// this way only one KX_BlenderMaterial object has to exist per bucket
|
||||
bool bucketCreated;
|
||||
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
|
||||
if (bucketCreated) {
|
||||
// this is needed to free up memory afterwards
|
||||
converter->RegisterPolyMaterial(polymat);
|
||||
if (converter->GetMaterials())
|
||||
converter->RegisterBlenderMaterial(bl_mat);
|
||||
}
|
||||
|
||||
return bucket;
|
||||
}
|
||||
|
||||
/* blenderobj can be NULL, make sure its checked for */
|
||||
RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter)
|
||||
RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter, bool libloading)
|
||||
{
|
||||
RAS_MeshObject *meshobj;
|
||||
int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object.
|
||||
@ -910,7 +1093,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
|
||||
// Extract avaiable layers
|
||||
MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
|
||||
int layer_uv[2]; /* store uv1, uv2 layers */
|
||||
for (int lay=0; lay<MAX_MTFACE; lay++) {
|
||||
layers[lay].face = 0;
|
||||
layers[lay].name = "";
|
||||
@ -933,31 +1115,23 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
|
||||
meshobj->SetName(mesh->id.name + 2);
|
||||
meshobj->m_sharedvertex_map.resize(totvert);
|
||||
RAS_IPolyMaterial* polymat = NULL;
|
||||
STR_String imastr;
|
||||
// These pointers will hold persistent material structure during the conversion
|
||||
// to avoid countless allocation/deallocation of memory.
|
||||
BL_Material* bl_mat = NULL;
|
||||
KX_BlenderMaterial* kx_blmat = NULL;
|
||||
KX_PolygonMaterial* kx_polymat = NULL;
|
||||
|
||||
Material* ma = 0;
|
||||
bool collider = true;
|
||||
MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT];
|
||||
unsigned int rgb[4] = {0};
|
||||
|
||||
MT_Point3 pt[4];
|
||||
MT_Vector3 no[4];
|
||||
MT_Vector4 tan[4];
|
||||
|
||||
for (int f=0;f<totface;f++,mface++)
|
||||
{
|
||||
Material* ma = 0;
|
||||
bool collider = true;
|
||||
MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
|
||||
MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
|
||||
unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
|
||||
|
||||
MT_Point3 pt0, pt1, pt2, pt3;
|
||||
MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
|
||||
MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
|
||||
|
||||
/* get coordinates, normals and tangents */
|
||||
pt0.setValue(mvert[mface->v1].co);
|
||||
pt1.setValue(mvert[mface->v2].co);
|
||||
pt2.setValue(mvert[mface->v3].co);
|
||||
if (mface->v4) pt3.setValue(mvert[mface->v4].co);
|
||||
pt[0].setValue(mvert[mface->v1].co);
|
||||
pt[1].setValue(mvert[mface->v2].co);
|
||||
pt[2].setValue(mvert[mface->v3].co);
|
||||
if (mface->v4) pt[3].setValue(mvert[mface->v4].co);
|
||||
|
||||
if (mface->flag & ME_SMOOTH) {
|
||||
float n0[3], n1[3], n2[3], n3[3];
|
||||
@ -965,13 +1139,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
normal_short_to_float_v3(n0, mvert[mface->v1].no);
|
||||
normal_short_to_float_v3(n1, mvert[mface->v2].no);
|
||||
normal_short_to_float_v3(n2, mvert[mface->v3].no);
|
||||
no0 = n0;
|
||||
no1 = n1;
|
||||
no2 = n2;
|
||||
no[0] = n0;
|
||||
no[1] = n1;
|
||||
no[2] = n2;
|
||||
|
||||
if (mface->v4) {
|
||||
normal_short_to_float_v3(n3, mvert[mface->v4].no);
|
||||
no3 = n3;
|
||||
no[3] = n3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -982,16 +1156,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
else
|
||||
normal_tri_v3(fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
|
||||
|
||||
no0 = no1 = no2 = no3 = MT_Vector3(fno);
|
||||
no[0] = no[1] = no[2] = no[3] = MT_Vector3(fno);
|
||||
}
|
||||
|
||||
if (tangent) {
|
||||
tan0 = tangent[f*4 + 0];
|
||||
tan1 = tangent[f*4 + 1];
|
||||
tan2 = tangent[f*4 + 2];
|
||||
tan[0] = tangent[f*4 + 0];
|
||||
tan[1] = tangent[f*4 + 1];
|
||||
tan[2] = tangent[f*4 + 2];
|
||||
|
||||
if (mface->v4)
|
||||
tan3 = tangent[f*4 + 3];
|
||||
tan[3] = tangent[f*4 + 3];
|
||||
}
|
||||
if (blenderobj)
|
||||
ma = give_current_material(blenderobj, mface->mat_nr+1);
|
||||
@ -1007,171 +1181,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
bool visible = true;
|
||||
bool twoside = false;
|
||||
|
||||
if (converter->GetMaterials()) {
|
||||
const bool is_bl_mat_new = (bl_mat == NULL);
|
||||
//const bool is_kx_blmat_new = (kx_blmat == NULL);
|
||||
const bool glslmat = converter->GetGLSLMaterials();
|
||||
const bool use_mcol = ma ? (ma->mode & MA_VERTEXCOLP || glslmat) : true;
|
||||
/* do Blender Multitexture and Blender GLSL materials */
|
||||
MT_Point2 uv_1[4];
|
||||
MT_Point2 uv_2[4];
|
||||
|
||||
/* first is the BL_Material */
|
||||
if (!bl_mat) {
|
||||
bl_mat = new BL_Material();
|
||||
}
|
||||
|
||||
/* only */
|
||||
if (is_bl_mat_new || (bl_mat->material != ma)) {
|
||||
ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
|
||||
layers, layer_uv, glslmat);
|
||||
}
|
||||
|
||||
/* vertex colors and uv's from the faces */
|
||||
GetRGB(use_mcol, mface, mcol, ma, rgb0, rgb1, rgb2, rgb3);
|
||||
GetUV(mface, tface, layers, layer_uv, uv_1, uv_2);
|
||||
|
||||
uv0 = uv_1[0]; uv1 = uv_1[1];
|
||||
uv2 = uv_1[2]; uv3 = uv_1[3];
|
||||
|
||||
uv20 = uv_2[0]; uv21 = uv_2[1];
|
||||
uv22 = uv_2[2]; uv23 = uv_2[3];
|
||||
|
||||
/* then the KX_BlenderMaterial */
|
||||
if (kx_blmat == NULL)
|
||||
kx_blmat = new KX_BlenderMaterial();
|
||||
|
||||
//if (is_kx_blmat_new || !kx_blmat->IsMaterial(bl_mat)) {
|
||||
kx_blmat->Initialize(scene, bl_mat, (ma ? &ma->game : NULL));
|
||||
//}
|
||||
|
||||
polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
|
||||
}
|
||||
else {
|
||||
/* do Texture Face materials */
|
||||
Image* bima = (tface)? (Image*)tface->tpage: NULL;
|
||||
imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
|
||||
|
||||
char alpha_blend=0;
|
||||
short tile=0;
|
||||
int tilexrep=4,tileyrep = 4;
|
||||
|
||||
/* set material properties - old TexFace */
|
||||
if (ma) {
|
||||
alpha_blend = ma->game.alpha_blend;
|
||||
/* Commented out for now. If we ever get rid of
|
||||
* "Texture Face/Singletexture" we can then think about it */
|
||||
|
||||
/* Texture Face mode ignores texture but requires "Face Textures to be True "*/
|
||||
#if 0
|
||||
if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
|
||||
bima = NULL;
|
||||
imastr = "";
|
||||
alpha_blend = GEMAT_SOLID;
|
||||
}
|
||||
else {
|
||||
alpha_blend = ma->game.alpha_blend;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* check for tface tex to fallback on */
|
||||
else {
|
||||
if (bima) {
|
||||
/* see if depth of the image is 32 */
|
||||
if (BKE_image_has_alpha(bima))
|
||||
alpha_blend = GEMAT_ALPHA;
|
||||
else
|
||||
alpha_blend = GEMAT_SOLID;
|
||||
}
|
||||
else {
|
||||
alpha_blend = GEMAT_SOLID;
|
||||
}
|
||||
}
|
||||
|
||||
if (bima) {
|
||||
tilexrep = bima->xrep;
|
||||
tileyrep = bima->yrep;
|
||||
}
|
||||
|
||||
/* set UV properties */
|
||||
if (tface) {
|
||||
uv0.setValue(tface->uv[0]);
|
||||
uv1.setValue(tface->uv[1]);
|
||||
uv2.setValue(tface->uv[2]);
|
||||
|
||||
if (mface->v4)
|
||||
uv3.setValue(tface->uv[3]);
|
||||
|
||||
tile = tface->tile;
|
||||
}
|
||||
else {
|
||||
/* no texfaces */
|
||||
tile = 0;
|
||||
}
|
||||
|
||||
/* get vertex colors */
|
||||
if (mcol) {
|
||||
/* we have vertex colors */
|
||||
rgb0 = KX_Mcol2uint_new(mcol[0]);
|
||||
rgb1 = KX_Mcol2uint_new(mcol[1]);
|
||||
rgb2 = KX_Mcol2uint_new(mcol[2]);
|
||||
|
||||
if (mface->v4)
|
||||
rgb3 = KX_Mcol2uint_new(mcol[3]);
|
||||
}
|
||||
else {
|
||||
/* no vertex colors, take from material, otherwise white */
|
||||
unsigned int color = 0xFFFFFFFFL;
|
||||
|
||||
if (ma)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char cp[4];
|
||||
unsigned int integer;
|
||||
} col_converter;
|
||||
|
||||
col_converter.cp[3] = (unsigned char) (ma->r * 255.0f);
|
||||
col_converter.cp[2] = (unsigned char) (ma->g * 255.0f);
|
||||
col_converter.cp[1] = (unsigned char) (ma->b * 255.0f);
|
||||
col_converter.cp[0] = (unsigned char) (ma->alpha * 255.0f);
|
||||
|
||||
color = col_converter.integer;
|
||||
}
|
||||
|
||||
rgb0 = KX_rgbaint2uint_new(color);
|
||||
rgb1 = KX_rgbaint2uint_new(color);
|
||||
rgb2 = KX_rgbaint2uint_new(color);
|
||||
|
||||
if (mface->v4)
|
||||
rgb3 = KX_rgbaint2uint_new(color);
|
||||
}
|
||||
|
||||
// only zsort alpha + add
|
||||
bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
|
||||
bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
|
||||
bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
|
||||
|
||||
// don't need zort anymore, deal as if it it's alpha blend
|
||||
if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
|
||||
|
||||
if (kx_polymat == NULL)
|
||||
kx_polymat = new KX_PolygonMaterial();
|
||||
kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
|
||||
tile, tilexrep, tileyrep,
|
||||
alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
|
||||
polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
|
||||
|
||||
if (ma) {
|
||||
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
|
||||
polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
|
||||
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
|
||||
}
|
||||
else {
|
||||
polymat->m_specular.setValue(0.0f,0.0f,0.0f);
|
||||
polymat->m_shininess = 35.0;
|
||||
}
|
||||
}
|
||||
RAS_MaterialBucket* bucket = material_from_mesh(ma, mface, tface, mcol, layers, lightlayer, rgb, uvs, tfaceName, scene, converter);
|
||||
|
||||
// set render flags
|
||||
if (ma)
|
||||
@ -1188,30 +1198,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
|
||||
/* mark face as flat, so vertices are split */
|
||||
bool flat = (mface->flag & ME_SMOOTH) == 0;
|
||||
|
||||
// see if a bucket was reused or a new one was created
|
||||
// this way only one KX_BlenderMaterial object has to exist per bucket
|
||||
bool bucketCreated;
|
||||
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
|
||||
if (bucketCreated) {
|
||||
// this is needed to free up memory afterwards
|
||||
converter->RegisterPolyMaterial(polymat);
|
||||
if (converter->GetMaterials()) {
|
||||
converter->RegisterBlenderMaterial(bl_mat);
|
||||
// the poly material has been stored in the bucket, next time we must create a new one
|
||||
bl_mat = NULL;
|
||||
kx_blmat = NULL;
|
||||
} else {
|
||||
// the poly material has been stored in the bucket, next time we must create a new one
|
||||
kx_polymat = NULL;
|
||||
}
|
||||
} else {
|
||||
// from now on, use the polygon material from the material bucket
|
||||
polymat = bucket->GetPolyMaterial();
|
||||
// keep the material pointers, they will be reused for next face
|
||||
}
|
||||
|
||||
|
||||
int nverts = (mface->v4)? 4: 3;
|
||||
|
||||
RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
|
||||
|
||||
poly->SetVisible(visible);
|
||||
@ -1219,12 +1208,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
poly->SetTwoside(twoside);
|
||||
//poly->SetEdgeCode(mface->edcode);
|
||||
|
||||
meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
|
||||
meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
|
||||
meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
|
||||
meshobj->AddVertex(poly,0,pt[0],uvs[0],tan[0],rgb[0],no[0],flat,mface->v1);
|
||||
meshobj->AddVertex(poly,1,pt[1],uvs[1],tan[1],rgb[1],no[1],flat,mface->v2);
|
||||
meshobj->AddVertex(poly,2,pt[2],uvs[2],tan[2],rgb[2],no[2],flat,mface->v3);
|
||||
|
||||
if (nverts==4)
|
||||
meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
|
||||
meshobj->AddVertex(poly,3,pt[3],uvs[3],tan[3],rgb[3],no[3],flat,mface->v4);
|
||||
}
|
||||
|
||||
if (tface)
|
||||
@ -1246,22 +1235,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
|
||||
meshobj->EndConversion();
|
||||
|
||||
// pre calculate texture generation
|
||||
for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
|
||||
mit != meshobj->GetLastMaterial(); ++ mit) {
|
||||
mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer);
|
||||
// However, we want to delay this if we're libloading so we can make sure we have the right scene.
|
||||
if (!libloading) {
|
||||
for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
|
||||
mit != meshobj->GetLastMaterial(); ++ mit) {
|
||||
mit->m_bucket->GetPolyMaterial()->OnConstruction();
|
||||
}
|
||||
}
|
||||
|
||||
if (layers)
|
||||
delete []layers;
|
||||
|
||||
dm->release(dm);
|
||||
// cleanup material
|
||||
if (bl_mat)
|
||||
delete bl_mat;
|
||||
if (kx_blmat)
|
||||
delete kx_blmat;
|
||||
if (kx_polymat)
|
||||
delete kx_polymat;
|
||||
|
||||
converter->RegisterGameMesh(meshobj, mesh);
|
||||
return meshobj;
|
||||
}
|
||||
@ -1921,7 +1907,8 @@ static KX_GameObject *gameobject_from_blenderobject(
|
||||
Object *ob,
|
||||
KX_Scene *kxscene,
|
||||
RAS_IRenderTools *rendertools,
|
||||
KX_BlenderSceneConverter *converter)
|
||||
KX_BlenderSceneConverter *converter,
|
||||
bool libloading)
|
||||
{
|
||||
KX_GameObject *gameobj = NULL;
|
||||
Scene *blenderscene = kxscene->GetBlenderScene();
|
||||
@ -1958,7 +1945,7 @@ static KX_GameObject *gameobject_from_blenderobject(
|
||||
Mesh* mesh = static_cast<Mesh*>(ob->data);
|
||||
float center[3], extents[3];
|
||||
float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
|
||||
RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter);
|
||||
RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter, libloading);
|
||||
|
||||
// needed for python scripting
|
||||
kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
|
||||
@ -2332,7 +2319,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
RAS_IRenderTools* rendertools,
|
||||
RAS_ICanvas* canvas,
|
||||
KX_BlenderSceneConverter* converter,
|
||||
bool alwaysUseExpandFraming
|
||||
bool alwaysUseExpandFraming,
|
||||
bool libloading
|
||||
)
|
||||
{
|
||||
|
||||
@ -2442,7 +2430,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
base->object,
|
||||
kxscene,
|
||||
rendertools,
|
||||
converter);
|
||||
converter,
|
||||
libloading);
|
||||
|
||||
bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
|
||||
bool addobj=true;
|
||||
@ -2501,7 +2490,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
blenderobject,
|
||||
kxscene,
|
||||
rendertools,
|
||||
converter);
|
||||
converter,
|
||||
libloading);
|
||||
|
||||
// this code is copied from above except that
|
||||
// object from groups are never in active layer
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "KX_PhysicsEngineEnums.h"
|
||||
#include "SCA_IInputDevice.h"
|
||||
|
||||
class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
|
||||
class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter, bool libloading);
|
||||
|
||||
void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
class KX_Scene* kxscene,
|
||||
@ -47,7 +47,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
class RAS_IRenderTools* rendertools,
|
||||
class RAS_ICanvas* canvas,
|
||||
class KX_BlenderSceneConverter* sceneconverter,
|
||||
bool alwaysUseExpandFraming
|
||||
bool alwaysUseExpandFraming,
|
||||
bool libloading=false
|
||||
);
|
||||
|
||||
SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code);
|
||||
|
@ -151,6 +151,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
|
||||
|
||||
vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
|
||||
while (itp != m_polymaterials.end()) {
|
||||
m_polymat_cache.erase((*itp).second->GetBlenderMaterial());
|
||||
delete (*itp).second;
|
||||
itp++;
|
||||
}
|
||||
@ -158,6 +159,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
|
||||
// delete after RAS_IPolyMaterial
|
||||
vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
|
||||
while (itmat != m_materials.end()) {
|
||||
m_mat_cache.erase((*itmat).second->material);
|
||||
delete (*itmat).second;
|
||||
itmat++;
|
||||
}
|
||||
@ -286,7 +288,8 @@ struct BlenderDebugDraw : public btIDebugDraw
|
||||
|
||||
void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
|
||||
class RAS_IRenderTools* rendertools,
|
||||
class RAS_ICanvas* canvas)
|
||||
class RAS_ICanvas* canvas,
|
||||
bool libloading)
|
||||
{
|
||||
//find out which physics engine
|
||||
Scene *blenderscene = destinationscene->GetBlenderScene();
|
||||
@ -355,7 +358,8 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
|
||||
rendertools,
|
||||
canvas,
|
||||
this,
|
||||
m_alwaysUseExpandFraming
|
||||
m_alwaysUseExpandFraming,
|
||||
libloading
|
||||
);
|
||||
|
||||
//These lookup are not needed during game
|
||||
@ -406,6 +410,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
|
||||
size = m_polymaterials.size();
|
||||
for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
|
||||
if ((*polymit).first == scene) {
|
||||
m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
|
||||
delete (*polymit).second;
|
||||
*polymit = m_polymaterials.back();
|
||||
m_polymaterials.pop_back();
|
||||
@ -420,6 +425,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
|
||||
size = m_materials.size();
|
||||
for (i=0, matit=m_materials.begin(); i<size; ) {
|
||||
if ((*matit).first == scene) {
|
||||
m_mat_cache.erase((*matit).second->material);
|
||||
delete (*matit).second;
|
||||
*matit = m_materials.back();
|
||||
m_materials.pop_back();
|
||||
@ -470,6 +476,12 @@ bool KX_BlenderSceneConverter::GetGLSLMaterials()
|
||||
|
||||
void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
|
||||
{
|
||||
// First make sure we don't register the material twice
|
||||
vector<pair<KX_Scene*,BL_Material*> >::iterator it;
|
||||
for (it = m_materials.begin(); it != m_materials.end(); ++it)
|
||||
if (it->second == mat)
|
||||
return;
|
||||
|
||||
m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
|
||||
}
|
||||
|
||||
@ -540,19 +552,37 @@ RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
|
||||
{
|
||||
// First make sure we don't register the material twice
|
||||
vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator it;
|
||||
for (it = m_polymaterials.begin(); it != m_polymaterials.end(); ++it)
|
||||
if (it->second == polymat)
|
||||
return;
|
||||
m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
|
||||
}
|
||||
|
||||
void KX_BlenderSceneConverter::CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat)
|
||||
{
|
||||
m_polymat_cache[mat] = polymat;
|
||||
}
|
||||
|
||||
RAS_IPolyMaterial *KX_BlenderSceneConverter::FindCachedPolyMaterial(struct Material *mat)
|
||||
{
|
||||
return m_polymat_cache[mat];
|
||||
}
|
||||
|
||||
void KX_BlenderSceneConverter::CacheBlenderMaterial(struct Material *mat, BL_Material *blmat)
|
||||
{
|
||||
m_mat_cache[mat] = blmat;
|
||||
}
|
||||
|
||||
BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(struct Material *mat)
|
||||
{
|
||||
return m_mat_cache[mat];
|
||||
}
|
||||
|
||||
void KX_BlenderSceneConverter::RegisterInterpolatorList(
|
||||
BL_InterpolatorList *actList,
|
||||
@ -1016,7 +1046,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
|
||||
for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) {
|
||||
if (options & LIB_LOAD_VERBOSE)
|
||||
printf("MeshName: %s\n", mesh->name+2);
|
||||
RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this);
|
||||
RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this, false); // For now only use the libloading option for scenes, which need to handle materials/shaders
|
||||
scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
|
||||
}
|
||||
}
|
||||
@ -1038,7 +1068,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
|
||||
printf("SceneName: %s\n", scene->name+2);
|
||||
|
||||
/* merge into the base scene */
|
||||
KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene);
|
||||
KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene, true);
|
||||
scene_merge->MergeScene(other);
|
||||
|
||||
// RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
|
||||
@ -1302,7 +1332,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
|
||||
}
|
||||
|
||||
if (IS_TAGGED(bmat)) {
|
||||
|
||||
m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
|
||||
delete (*polymit).second;
|
||||
*polymit = m_polymaterials.back();
|
||||
m_polymaterials.pop_back();
|
||||
@ -1320,6 +1350,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
|
||||
for (i=0, matit=m_materials.begin(); i<size; ) {
|
||||
BL_Material *mat= (*matit).second;
|
||||
if (IS_TAGGED(mat->material)) {
|
||||
m_mat_cache.erase((*matit).second->material);
|
||||
delete (*matit).second;
|
||||
*matit = m_materials.back();
|
||||
m_materials.pop_back();
|
||||
@ -1469,7 +1500,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
|
||||
}
|
||||
}
|
||||
|
||||
RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this);
|
||||
RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false);
|
||||
kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
|
||||
m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
|
||||
return meshobj;
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "KX_ISceneConverter.h"
|
||||
#include "KX_IpoConvert.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class KX_WorldInfo;
|
||||
@ -58,6 +60,11 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
|
||||
vector<pair<KX_Scene*,RAS_IPolyMaterial*> > m_polymaterials;
|
||||
vector<pair<KX_Scene*,RAS_MeshObject*> > m_meshobjects;
|
||||
vector<pair<KX_Scene*,BL_Material *> > m_materials;
|
||||
|
||||
// Cached material conversions
|
||||
map<struct Material*, BL_Material*> m_mat_cache;
|
||||
map<struct Material*, RAS_IPolyMaterial*> m_polymat_cache;
|
||||
|
||||
// Should also have a list of collision shapes.
|
||||
// For the time being this is held in KX_Scene::m_shapes
|
||||
|
||||
@ -93,7 +100,8 @@ public:
|
||||
virtual void ConvertScene(
|
||||
class KX_Scene* destinationscene,
|
||||
class RAS_IRenderTools* rendertools,
|
||||
class RAS_ICanvas* canvas
|
||||
class RAS_ICanvas* canvas,
|
||||
bool libloading=false
|
||||
);
|
||||
virtual void RemoveScene(class KX_Scene *scene);
|
||||
|
||||
@ -110,8 +118,12 @@ public:
|
||||
RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/);
|
||||
|
||||
void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
|
||||
void CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat);
|
||||
RAS_IPolyMaterial *FindCachedPolyMaterial(struct Material *mat);
|
||||
|
||||
void RegisterBlenderMaterial(BL_Material *mat);
|
||||
void CacheBlenderMaterial(struct Material *mat, BL_Material *blmat);
|
||||
BL_Material *FindCachedBlenderMaterial(struct Material *mat);
|
||||
|
||||
void RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act);
|
||||
BL_InterpolatorList *FindInterpolatorList(struct bAction *for_act);
|
||||
|
@ -523,7 +523,8 @@ void BL_ConvertActuators(const char* maggiename,
|
||||
editobact->me,
|
||||
blenderobject,
|
||||
scene,
|
||||
converter
|
||||
converter,
|
||||
false
|
||||
);
|
||||
|
||||
KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator(
|
||||
|
@ -76,7 +76,6 @@ extern "C"
|
||||
#include "SCA_IActuator.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
#include "RAS_OpenGLRasterizer.h"
|
||||
#include "RAS_VAOpenGLRasterizer.h"
|
||||
#include "RAS_ListRasterizer.h"
|
||||
#include "RAS_GLExtensionManager.h"
|
||||
#include "KX_PythonInit.h"
|
||||
@ -582,16 +581,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
|
||||
if (!m_rendertools)
|
||||
goto initFailed;
|
||||
|
||||
if (useLists) {
|
||||
if (GLEW_VERSION_1_1)
|
||||
m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
|
||||
else
|
||||
m_rasterizer = new RAS_ListRasterizer(m_canvas);
|
||||
}
|
||||
else if (GLEW_VERSION_1_1)
|
||||
m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
|
||||
//Don't use displaylists with VBOs
|
||||
//If auto starts using VBOs, make sure to check for that here
|
||||
if (useLists && gm->raster_storage != RAS_STORE_VBO)
|
||||
m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage);
|
||||
else
|
||||
m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
|
||||
m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage);
|
||||
|
||||
/* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
|
||||
m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
|
||||
|
@ -95,21 +95,15 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
|
||||
|
||||
ras->SetTexCoordNum(0);
|
||||
ras->SetAttribNum(attrib_num);
|
||||
for (i=0; i<attrib_num; i++)
|
||||
for (i = 0; i < attrib_num; i++)
|
||||
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
|
||||
|
||||
for (i = 0; i < attribs.totlayer; i++) {
|
||||
if (attribs.layer[i].glindex > attrib_num)
|
||||
continue;
|
||||
|
||||
if (attribs.layer[i].type == CD_MTFACE) {
|
||||
if (!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
|
||||
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
|
||||
else if (!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
|
||||
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
|
||||
else
|
||||
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
|
||||
}
|
||||
if (attribs.layer[i].type == CD_MTFACE)
|
||||
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV, attribs.layer[i].glindex);
|
||||
else if (attribs.layer[i].type == CD_TANGENT)
|
||||
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
|
||||
else if (attribs.layer[i].type == CD_ORCO)
|
||||
|
@ -20,15 +20,6 @@ MTex* getImageFromMaterial(Material *mat, int index)
|
||||
return m?m:0;
|
||||
}
|
||||
|
||||
int getNumTexChannels( Material *mat )
|
||||
{
|
||||
int count = -1;
|
||||
if (!mat) return -1;
|
||||
|
||||
for (count =0; (count < 10) && mat->mtex[count] != 0; count++) {}
|
||||
return count;
|
||||
}
|
||||
|
||||
BL_Material::BL_Material()
|
||||
{
|
||||
Initialize();
|
||||
@ -36,7 +27,10 @@ BL_Material::BL_Material()
|
||||
|
||||
void BL_Material::Initialize()
|
||||
{
|
||||
m_mcol = 0xFFFFFFFFL;
|
||||
rgb[0] = 0;
|
||||
rgb[1] = 0;
|
||||
rgb[2] = 0;
|
||||
rgb[3] = 0;
|
||||
IdMode = 0;
|
||||
ras_mode = 0;
|
||||
glslmat = 0;
|
||||
@ -64,7 +58,7 @@ void BL_Material::Initialize()
|
||||
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAXTEX; i++) // :(
|
||||
for (i = 0; i < MAXTEX; i++) // :(
|
||||
{
|
||||
mapping[i].mapping = 0;
|
||||
mapping[i].offsets[0] = 0.f;
|
||||
@ -90,15 +84,6 @@ void BL_Material::Initialize()
|
||||
}
|
||||
}
|
||||
|
||||
void BL_Material::SetUVLayerName(const STR_String& name)
|
||||
{
|
||||
uvName = name;
|
||||
}
|
||||
void BL_Material::SetUVLayerName2(const STR_String& name)
|
||||
{
|
||||
uv2Name = name;
|
||||
}
|
||||
|
||||
void BL_Material::SetSharedMaterial(bool v)
|
||||
{
|
||||
if ((v && num_users == -1) || num_users > 1 )
|
||||
|
@ -87,13 +87,8 @@ public:
|
||||
MTFace tface; /* copy of the derived meshes tface */
|
||||
Image* img[MAXTEX];
|
||||
EnvMap* cubemap[MAXTEX];
|
||||
unsigned int m_mcol; /* for text color (only) */
|
||||
|
||||
STR_String uvName;
|
||||
STR_String uv2Name;
|
||||
|
||||
void SetUVLayerName(const STR_String &name);
|
||||
void SetUVLayerName2(const STR_String &name);
|
||||
unsigned int rgb[4];
|
||||
|
||||
void SetSharedMaterial(bool v);
|
||||
bool IsShared();
|
||||
@ -180,7 +175,6 @@ enum BL_MappingProj
|
||||
// ------------------------------------
|
||||
//extern void initBL_Material(BL_Material* mat);
|
||||
extern MTex* getImageFromMaterial(Material *mat, int index);
|
||||
extern int getNumTexChannels( Material *mat );
|
||||
// ------------------------------------
|
||||
|
||||
#endif
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
|
||||
typedef std::map<char*, BL_TextureObject> BL_TextureMap;
|
||||
static BL_TextureMap g_textureManager;
|
||||
static GLint g_max_units = -1;
|
||||
|
||||
|
||||
BL_Texture::BL_Texture()
|
||||
@ -379,14 +380,17 @@ unsigned int BL_Texture::GetTextureType() const
|
||||
|
||||
int BL_Texture::GetMaxUnits()
|
||||
{
|
||||
GLint unit=0;
|
||||
|
||||
if (GLEW_ARB_multitexture) {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
|
||||
return (MAXTEX>=unit?unit:MAXTEX);
|
||||
if (g_max_units < 0) {
|
||||
GLint unit;
|
||||
if (GLEW_ARB_multitexture) {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
|
||||
g_max_units = (MAXTEX>=unit)?unit:MAXTEX;
|
||||
} else {
|
||||
g_max_units = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return g_max_units;
|
||||
}
|
||||
|
||||
void BL_Texture::ActivateFirst()
|
||||
|
@ -60,7 +60,8 @@ KX_BlenderMaterial::KX_BlenderMaterial()
|
||||
void KX_BlenderMaterial::Initialize(
|
||||
KX_Scene *scene,
|
||||
BL_Material *data,
|
||||
GameSettings *game)
|
||||
GameSettings *game,
|
||||
int lightlayer)
|
||||
{
|
||||
RAS_IPolyMaterial::Initialize(
|
||||
data->texname[0],
|
||||
@ -84,6 +85,7 @@ void KX_BlenderMaterial::Initialize(
|
||||
mModified = 0;
|
||||
mConstructed = false;
|
||||
mPass = 0;
|
||||
mLightLayer = lightlayer;
|
||||
// --------------------------------
|
||||
// RAS_IPolyMaterial variables...
|
||||
m_flag |= RAS_BLENDERMAT;
|
||||
@ -92,16 +94,11 @@ void KX_BlenderMaterial::Initialize(
|
||||
m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0;
|
||||
m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0;
|
||||
|
||||
// figure max
|
||||
int enabled = mMaterial->num_enabled;
|
||||
int max = BL_Texture::GetMaxUnits();
|
||||
mMaterial->num_enabled = enabled>=max?max:enabled;
|
||||
|
||||
// test the sum of the various modes for equality
|
||||
// so we can ether accept or reject this material
|
||||
// as being equal, this is rather important to
|
||||
// prevent material bleeding
|
||||
for (int i=0; i<mMaterial->num_enabled; i++) {
|
||||
for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
|
||||
m_multimode += (mMaterial->flag[i] + mMaterial->blend_mode[i]);
|
||||
}
|
||||
m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT));
|
||||
@ -124,7 +121,7 @@ MTFace* KX_BlenderMaterial::GetMTFace(void) const
|
||||
unsigned int* KX_BlenderMaterial::GetMCol(void) const
|
||||
{
|
||||
// fonts on polys
|
||||
return &mMaterial->m_mcol;
|
||||
return mMaterial->rgb;
|
||||
}
|
||||
|
||||
void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
|
||||
@ -138,11 +135,6 @@ void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
|
||||
RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
|
||||
}
|
||||
|
||||
bool KX_BlenderMaterial::IsMaterial(const BL_Material *bl_mat) const
|
||||
{
|
||||
return (mMaterial == bl_mat);
|
||||
}
|
||||
|
||||
Material *KX_BlenderMaterial::GetBlenderMaterial() const
|
||||
{
|
||||
return mMaterial->material;
|
||||
@ -163,7 +155,7 @@ void KX_BlenderMaterial::InitTextures()
|
||||
{
|
||||
// for each unique material...
|
||||
int i;
|
||||
for (i=0; i<mMaterial->num_enabled; i++) {
|
||||
for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
|
||||
if ( mMaterial->mapping[i].mapping & USEENV ) {
|
||||
if (!GLEW_ARB_texture_cube_map) {
|
||||
spit("CubeMap textures not supported");
|
||||
@ -185,14 +177,14 @@ void KX_BlenderMaterial::InitTextures()
|
||||
}
|
||||
}
|
||||
|
||||
void KX_BlenderMaterial::OnConstruction(int layer)
|
||||
void KX_BlenderMaterial::OnConstruction()
|
||||
{
|
||||
if (mConstructed)
|
||||
// when material are reused between objects
|
||||
return;
|
||||
|
||||
if (mMaterial->glslmat)
|
||||
SetBlenderGLSLShader(layer);
|
||||
SetBlenderGLSLShader();
|
||||
|
||||
InitTextures();
|
||||
|
||||
@ -239,7 +231,8 @@ void KX_BlenderMaterial::OnExit()
|
||||
}
|
||||
|
||||
BL_Texture::ActivateFirst();
|
||||
for (int i=0; i<mMaterial->num_enabled; i++) {
|
||||
for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
|
||||
if (!mTextures[i].Ok()) continue;
|
||||
BL_Texture::ActivateUnit(i);
|
||||
mTextures[i].DeleteTex();
|
||||
mTextures[i].DisableUnit();
|
||||
@ -278,7 +271,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
|
||||
mShader->ApplyShader();
|
||||
|
||||
// for each enabled unit
|
||||
for (i=0; i<mMaterial->num_enabled; i++) {
|
||||
for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
|
||||
if (!mTextures[i].Ok()) continue;
|
||||
mTextures[i].ActivateTexture();
|
||||
mTextures[0].SetMapping(mMaterial->mapping[i].mapping);
|
||||
@ -354,7 +347,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
|
||||
}
|
||||
|
||||
int mode = 0,i=0;
|
||||
for (i=0; (i<mMaterial->num_enabled && i<MAXTEX); i++) {
|
||||
for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
|
||||
if ( !mTextures[i].Ok() ) continue;
|
||||
|
||||
mTextures[i].ActivateTexture();
|
||||
@ -647,16 +640,9 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
|
||||
|
||||
ras->SetTexCoordNum(mMaterial->num_enabled);
|
||||
|
||||
for (int i=0; i<mMaterial->num_enabled; i++) {
|
||||
for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
|
||||
int mode = mMaterial->mapping[i].mapping;
|
||||
|
||||
if (mode &USECUSTOMUV)
|
||||
{
|
||||
if (!mMaterial->mapping[i].uvCoName.IsEmpty())
|
||||
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( mode &(USEREFL|USEOBJ))
|
||||
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i);
|
||||
else if (mode &USEORCO)
|
||||
@ -664,7 +650,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
|
||||
else if (mode &USENORM)
|
||||
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i);
|
||||
else if (mode &USEUV)
|
||||
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i);
|
||||
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV, i);
|
||||
else if (mode &USETANG)
|
||||
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i);
|
||||
else
|
||||
@ -790,10 +776,19 @@ void KX_BlenderMaterial::UpdateIPO(
|
||||
mMaterial->ref = (float)(ref);
|
||||
}
|
||||
|
||||
void KX_BlenderMaterial::SetBlenderGLSLShader(int layer)
|
||||
void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val)
|
||||
{
|
||||
mScene= static_cast<KX_Scene *>(val);
|
||||
if (mBlenderShader)
|
||||
mBlenderShader->SetScene(mScene);
|
||||
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
void KX_BlenderMaterial::SetBlenderGLSLShader()
|
||||
{
|
||||
if (!mBlenderShader)
|
||||
mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer);
|
||||
mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, mLightLayer);
|
||||
|
||||
if (!mBlenderShader->Ok()) {
|
||||
delete mBlenderShader;
|
||||
|
@ -39,7 +39,8 @@ public:
|
||||
void Initialize(
|
||||
class KX_Scene* scene,
|
||||
BL_Material* mat,
|
||||
GameSettings* game
|
||||
GameSettings* game,
|
||||
int lightlayer
|
||||
);
|
||||
|
||||
virtual ~KX_BlenderMaterial();
|
||||
@ -76,8 +77,6 @@ public:
|
||||
TCachingInfo& cachingInfo
|
||||
)const;
|
||||
|
||||
/* mMaterial is private, but need this for conversion */
|
||||
bool IsMaterial(const BL_Material *bl_mat) const;
|
||||
Material* GetBlenderMaterial() const;
|
||||
MTFace* GetMTFace(void) const;
|
||||
unsigned int* GetMCol(void) const;
|
||||
@ -97,14 +96,7 @@ public:
|
||||
MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha
|
||||
);
|
||||
|
||||
virtual void Replace_IScene(SCA_IScene *val)
|
||||
{
|
||||
mScene= static_cast<KX_Scene *>(val);
|
||||
if (mBlenderShader)
|
||||
{
|
||||
mBlenderShader->SetScene(mScene);
|
||||
}
|
||||
};
|
||||
virtual void Replace_IScene(SCA_IScene *val);
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
// --------------------------------
|
||||
@ -125,7 +117,7 @@ public:
|
||||
|
||||
// --------------------------------
|
||||
// pre calculate to avoid pops/lag at startup
|
||||
virtual void OnConstruction(int layer);
|
||||
virtual void OnConstruction();
|
||||
|
||||
static void EndFrame();
|
||||
|
||||
@ -139,10 +131,11 @@ private:
|
||||
unsigned int mBlendFunc[2];
|
||||
bool mModified;
|
||||
bool mConstructed; // if false, don't clean on exit
|
||||
int mLightLayer;
|
||||
|
||||
void InitTextures();
|
||||
|
||||
void SetBlenderGLSLShader(int layer);
|
||||
void SetBlenderGLSLShader();
|
||||
|
||||
void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
|
||||
void ActivateTexGen( RAS_IRasterizer *ras ) const;
|
||||
|
@ -57,7 +57,8 @@ public:
|
||||
virtual void ConvertScene(
|
||||
class KX_Scene* destinationscene,
|
||||
class RAS_IRenderTools* rendertools,
|
||||
class RAS_ICanvas* canvas)=0;
|
||||
class RAS_ICanvas* canvas,
|
||||
bool libloading=false)=0;
|
||||
|
||||
virtual void RemoveScene(class KX_Scene *scene)=0;
|
||||
|
||||
|
@ -1686,7 +1686,7 @@ void KX_KetsjiEngine::RemoveScheduledScenes()
|
||||
}
|
||||
}
|
||||
|
||||
KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
|
||||
KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading)
|
||||
{
|
||||
KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
|
||||
m_mousedevice,
|
||||
@ -1697,7 +1697,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
|
||||
|
||||
m_sceneconverter->ConvertScene(tmpscene,
|
||||
m_rendertools,
|
||||
m_canvas);
|
||||
m_canvas,
|
||||
libloading);
|
||||
|
||||
return tmpscene;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ public:
|
||||
void GetOverrideFrameColor(float& r, float& g, float& b) const;
|
||||
|
||||
KX_Scene* CreateScene(const STR_String& scenename);
|
||||
KX_Scene* CreateScene(Scene *scene);
|
||||
KX_Scene* CreateScene(Scene *scene, bool libloading=false);
|
||||
|
||||
GlobalSettings* GetGlobalSettings(void);
|
||||
void SetGlobalSettings(GlobalSettings* gs);
|
||||
|
@ -338,20 +338,20 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds)
|
||||
for (i = it.startvertex; i < it.endvertex; i++) {
|
||||
RAS_TexVert *vert = &it.vertex[i];
|
||||
if (uvindex_from != -1) {
|
||||
if (uvindex_from == 0) vert->SetUV2(vert->getUV1());
|
||||
else vert->SetUV1(vert->getUV2());
|
||||
if (uvindex_from == 0) vert->SetUV(1, vert->getUV(0));
|
||||
else vert->SetUV(0, vert->getUV(1));
|
||||
}
|
||||
|
||||
switch (uvindex) {
|
||||
case 0:
|
||||
vert->TransformUV1(transform);
|
||||
vert->TransformUV(0, transform);
|
||||
break;
|
||||
case 1:
|
||||
vert->TransformUV2(transform);
|
||||
vert->TransformUV(1, transform);
|
||||
break;
|
||||
case -1:
|
||||
vert->TransformUV1(transform);
|
||||
vert->TransformUV2(transform);
|
||||
vert->TransformUV(0, transform);
|
||||
vert->TransformUV(1, transform);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ void KX_PolygonMaterial::Initialize(
|
||||
m_mcol = *mcol;
|
||||
}
|
||||
else {
|
||||
m_mcol = 0;
|
||||
memset(&m_mcol, 0, sizeof(m_mcol));
|
||||
}
|
||||
|
||||
m_material = ma;
|
||||
|
@ -60,7 +60,7 @@ class KX_PolygonMaterial : public PyObjectPlus, public RAS_IPolyMaterial
|
||||
private:
|
||||
/** Blender texture face structure. */
|
||||
mutable MTFace m_tface;
|
||||
mutable unsigned int m_mcol; /* for text color (only) */
|
||||
mutable unsigned int m_mcol;
|
||||
Material* m_material;
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
|
@ -94,6 +94,7 @@ PyAttributeDef KX_VertexProxy::Attributes[] = {
|
||||
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("XYZ", KX_VertexProxy, pyattr_get_XYZ, pyattr_set_XYZ),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("UV", KX_VertexProxy, pyattr_get_UV, pyattr_set_UV),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("uvs", KX_VertexProxy, pyattr_get_uvs, pyattr_set_uvs),
|
||||
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("color", KX_VertexProxy, pyattr_get_color, pyattr_set_color),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("normal", KX_VertexProxy, pyattr_get_normal, pyattr_set_normal),
|
||||
@ -146,25 +147,25 @@ PyObject *KX_VertexProxy::pyattr_get_a(void *self_v, const KX_PYATTRIBUTE_DEF *a
|
||||
PyObject *KX_VertexProxy::pyattr_get_u(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV1()[0]);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV(0)[0]);
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::pyattr_get_v(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV1()[1]);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV(0)[1]);
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::pyattr_get_u2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV2()[0]);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV(1)[0]);
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::pyattr_get_v2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV2()[1]);
|
||||
return PyFloat_FromDouble(self->m_vertex->getUV(1)[1]);
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
@ -176,7 +177,20 @@ PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF
|
||||
PyObject *KX_VertexProxy::pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
|
||||
return PyObjectFrom(MT_Point2(self->m_vertex->getUV1()));
|
||||
return PyObjectFrom(MT_Point2(self->m_vertex->getUV(0)));
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
|
||||
|
||||
PyObject* uvlist = PyList_New(RAS_TexVert::MAX_UNIT);
|
||||
for (int i=0; i<RAS_TexVert::MAX_UNIT; ++i)
|
||||
{
|
||||
PyList_SET_ITEM(uvlist, i, PyObjectFrom(MT_Point2(self->m_vertex->getUV(i))));
|
||||
}
|
||||
|
||||
return uvlist;
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
@ -245,9 +259,9 @@ int KX_VertexProxy::pyattr_set_u(void *self_v, const struct KX_PYATTRIBUTE_DEF *
|
||||
if (PyFloat_Check(value))
|
||||
{
|
||||
float val = PyFloat_AsDouble(value);
|
||||
MT_Point2 uv = self->m_vertex->getUV1();
|
||||
MT_Point2 uv = self->m_vertex->getUV(0);
|
||||
uv[0] = val;
|
||||
self->m_vertex->SetUV1(uv);
|
||||
self->m_vertex->SetUV(0, uv);
|
||||
self->m_mesh->SetMeshModified(true);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
@ -260,9 +274,9 @@ int KX_VertexProxy::pyattr_set_v(void *self_v, const struct KX_PYATTRIBUTE_DEF *
|
||||
if (PyFloat_Check(value))
|
||||
{
|
||||
float val = PyFloat_AsDouble(value);
|
||||
MT_Point2 uv = self->m_vertex->getUV1();
|
||||
MT_Point2 uv = self->m_vertex->getUV(0);
|
||||
uv[1] = val;
|
||||
self->m_vertex->SetUV1(uv);
|
||||
self->m_vertex->SetUV(0, uv);
|
||||
self->m_mesh->SetMeshModified(true);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
@ -275,9 +289,9 @@ int KX_VertexProxy::pyattr_set_u2(void *self_v, const struct KX_PYATTRIBUTE_DEF
|
||||
if (PyFloat_Check(value))
|
||||
{
|
||||
float val = PyFloat_AsDouble(value);
|
||||
MT_Point2 uv = self->m_vertex->getUV2();
|
||||
MT_Point2 uv = self->m_vertex->getUV(1);
|
||||
uv[0] = val;
|
||||
self->m_vertex->SetUV2(uv);
|
||||
self->m_vertex->SetUV(1, uv);
|
||||
self->m_mesh->SetMeshModified(true);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
@ -290,9 +304,9 @@ int KX_VertexProxy::pyattr_set_v2(void *self_v, const struct KX_PYATTRIBUTE_DEF
|
||||
if (PyFloat_Check(value))
|
||||
{
|
||||
float val = PyFloat_AsDouble(value);
|
||||
MT_Point2 uv = self->m_vertex->getUV2();
|
||||
MT_Point2 uv = self->m_vertex->getUV(1);
|
||||
uv[1] = val;
|
||||
self->m_vertex->SetUV2(uv);
|
||||
self->m_vertex->SetUV(1, uv);
|
||||
self->m_mesh->SetMeshModified(true);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
@ -390,7 +404,7 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
|
||||
{
|
||||
MT_Point2 vec;
|
||||
if (PyVecTo(value, vec)) {
|
||||
self->m_vertex->SetUV1(vec);
|
||||
self->m_vertex->SetUV(0, vec);
|
||||
self->m_mesh->SetMeshModified(true);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
@ -398,6 +412,32 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
int KX_VertexProxy::pyattr_set_uvs(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
|
||||
if (PySequence_Check(value))
|
||||
{
|
||||
MT_Point2 vec;
|
||||
for (int i=0; i<PySequence_Size(value) && i<RAS_TexVert::MAX_UNIT; ++i)
|
||||
{
|
||||
if (PyVecTo(PySequence_GetItem(value, i), vec))
|
||||
{
|
||||
self->m_vertex->SetUV(i, vec);
|
||||
self->m_mesh->SetMeshModified(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError, STR_String().Format("list[%d] was not a vector", i).ReadPtr());
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
self->m_mesh->SetMeshModified(true);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
|
||||
int KX_VertexProxy::pyattr_set_color(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
|
||||
@ -522,7 +562,7 @@ PyObject *KX_VertexProxy::PySetRGBA(PyObject *value)
|
||||
|
||||
PyObject *KX_VertexProxy::PyGetUV1()
|
||||
{
|
||||
return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
|
||||
return PyObjectFrom(MT_Vector2(m_vertex->getUV(0)));
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
|
||||
@ -531,31 +571,23 @@ PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
|
||||
if (!PyVecTo(value, vec))
|
||||
return NULL;
|
||||
|
||||
m_vertex->SetUV1(vec);
|
||||
m_vertex->SetUV(0, vec);
|
||||
m_mesh->SetMeshModified(true);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::PyGetUV2()
|
||||
{
|
||||
return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
|
||||
return PyObjectFrom(MT_Vector2(m_vertex->getUV(1)));
|
||||
}
|
||||
|
||||
PyObject *KX_VertexProxy::PySetUV2(PyObject *args)
|
||||
{
|
||||
MT_Point2 vec;
|
||||
unsigned int unit= RAS_TexVert::SECOND_UV;
|
||||
|
||||
PyObject *list = NULL;
|
||||
if (!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit))
|
||||
if (!PyVecTo(args, vec))
|
||||
return NULL;
|
||||
|
||||
if (!PyVecTo(list, vec))
|
||||
return NULL;
|
||||
|
||||
m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
|
||||
m_vertex->SetUnit(unit);
|
||||
m_vertex->SetUV2(vec);
|
||||
m_vertex->SetUV(1, vec);
|
||||
m_mesh->SetMeshModified(true);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
static PyObject *pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_normal(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject *pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_x(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_y(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_z(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
@ -89,6 +90,7 @@ public:
|
||||
static int pyattr_set_UV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_color(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_normal(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_uvs(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
|
||||
KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ);
|
||||
KX_PYMETHOD_O(KX_VertexProxy,SetXYZ);
|
||||
|
@ -232,6 +232,24 @@ void RAS_BucketManager::Renderbuckets(
|
||||
RenderSolidBuckets(cameratrans, rasty, rendertools);
|
||||
RenderAlphaBuckets(cameratrans, rasty, rendertools);
|
||||
|
||||
/* All meshes should be up to date now */
|
||||
/* Don't do this while processing buckets because some meshes are split between buckets */
|
||||
BucketList::iterator bit;
|
||||
list<RAS_MeshSlot>::iterator mit;
|
||||
for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) {
|
||||
RAS_MaterialBucket* bucket = *bit;
|
||||
for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
|
||||
mit->m_mesh->SetMeshModified(false);
|
||||
}
|
||||
}
|
||||
for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
|
||||
RAS_MaterialBucket* bucket = *bit;
|
||||
for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
|
||||
mit->m_mesh->SetMeshModified(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rendertools->SetClientObject(rasty, NULL);
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ public:
|
||||
/*
|
||||
* PreCalculate texture gen
|
||||
*/
|
||||
virtual void OnConstruction(int layer) {}
|
||||
virtual void OnConstruction() {}
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
|
@ -52,6 +52,7 @@ using namespace std;
|
||||
|
||||
class RAS_ICanvas;
|
||||
class RAS_IPolyMaterial;
|
||||
class RAS_MeshSlot;
|
||||
|
||||
typedef vector<unsigned short> KX_IndexArray;
|
||||
typedef vector<RAS_TexVert> KX_VertexArray;
|
||||
@ -129,7 +130,7 @@ public:
|
||||
RAS_TEXCO_GEN, //< GPU will generate texture coordinates
|
||||
RAS_TEXCO_ORCO, //< Vertex coordinates (object space)
|
||||
RAS_TEXCO_GLOB, //< Vertex coordinates (world space)
|
||||
RAS_TEXCO_UV1, //< UV coordinates
|
||||
RAS_TEXCO_UV, //< UV coordinates
|
||||
RAS_TEXCO_OBJECT, //< Use another object's position as coordinates
|
||||
RAS_TEXCO_LAVECTOR, //< Light vector as coordinates
|
||||
RAS_TEXCO_VIEW, //< View vector as coordinates
|
||||
@ -137,7 +138,6 @@ public:
|
||||
RAS_TEXCO_WINDOW, //< Window coordinates
|
||||
RAS_TEXCO_NORM, //< Normal coordinates
|
||||
RAS_TEXTANGENT, //<
|
||||
RAS_TEXCO_UV2, //<
|
||||
RAS_TEXCO_VCOL, //< Vertex Color
|
||||
RAS_TEXCO_DISABLE //< Disable this texture unit (cached)
|
||||
};
|
||||
|
@ -605,7 +605,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
|
||||
|
||||
if (ms.m_pDeformer)
|
||||
{
|
||||
ms.m_pDeformer->Apply(m_material);
|
||||
if (ms.m_pDeformer->Apply(m_material));
|
||||
ms.m_mesh->SetMeshModified(true);
|
||||
// KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_)
|
||||
}
|
||||
|
||||
@ -648,10 +649,6 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
|
||||
else
|
||||
rasty->IndexPrimitives(ms);
|
||||
|
||||
if (rasty->QueryLists())
|
||||
if (ms.m_DisplayList)
|
||||
ms.m_mesh->SetMeshModified(false);
|
||||
|
||||
rendertools->PopMatrix();
|
||||
}
|
||||
|
||||
|
@ -324,15 +324,14 @@ void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
|
||||
|
||||
void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i,
|
||||
const MT_Point3& xyz,
|
||||
const MT_Point2& uv,
|
||||
const MT_Point2& uv2,
|
||||
const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
|
||||
const MT_Vector4& tangent,
|
||||
const unsigned int rgba,
|
||||
const MT_Vector3& normal,
|
||||
bool flat,
|
||||
int origindex)
|
||||
{
|
||||
RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex);
|
||||
RAS_TexVert texvert(xyz, uvs, tangent, rgba, normal, flat, origindex);
|
||||
RAS_MeshMaterial *mmat;
|
||||
RAS_DisplayArray *darray;
|
||||
RAS_MeshSlot *slot;
|
||||
|
@ -116,8 +116,7 @@ public:
|
||||
virtual RAS_Polygon* AddPolygon(RAS_MaterialBucket *bucket, int numverts);
|
||||
virtual void AddVertex(RAS_Polygon *poly, int i,
|
||||
const MT_Point3& xyz,
|
||||
const MT_Point2& uv,
|
||||
const MT_Point2& uv2,
|
||||
const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
|
||||
const MT_Vector4& tangent,
|
||||
const unsigned int rgbacolor,
|
||||
const MT_Vector3& normal,
|
||||
|
@ -46,12 +46,17 @@ set(SRC
|
||||
RAS_GLExtensionManager.cpp
|
||||
RAS_ListRasterizer.cpp
|
||||
RAS_OpenGLRasterizer.cpp
|
||||
RAS_VAOpenGLRasterizer.cpp
|
||||
RAS_StorageIM.cpp
|
||||
RAS_StorageVA.cpp
|
||||
RAS_StorageVBO.cpp
|
||||
|
||||
RAS_GLExtensionManager.h
|
||||
RAS_IStorage.h
|
||||
RAS_ListRasterizer.h
|
||||
RAS_OpenGLRasterizer.h
|
||||
RAS_VAOpenGLRasterizer.h
|
||||
RAS_StorageIM.h
|
||||
RAS_StorageVA.h
|
||||
RAS_StorageVBO.h
|
||||
)
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __KX_STORAGE
|
||||
#define __KX_STORAGE
|
||||
|
||||
#include "RAS_MaterialBucket.h"
|
||||
|
||||
enum RAS_STORAGE_TYPE {
|
||||
RAS_AUTO_STORAGE,
|
||||
RAS_IMMEDIATE,
|
||||
RAS_VA,
|
||||
RAS_VBO
|
||||
};
|
||||
|
||||
class RAS_IStorage
|
||||
{
|
||||
|
||||
public:
|
||||
virtual ~RAS_IStorage() {};
|
||||
|
||||
virtual bool Init()=0;
|
||||
virtual void Exit()=0;
|
||||
|
||||
virtual void IndexPrimitives(RAS_MeshSlot& ms)=0;
|
||||
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms)=0;
|
||||
|
||||
virtual void SetDrawingMode(int drawingmode)=0;
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_IStorage"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_STORAGE
|
@ -106,9 +106,8 @@ bool RAS_ListSlot::End()
|
||||
|
||||
|
||||
|
||||
RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock)
|
||||
: RAS_VAOpenGLRasterizer(canvas, lock),
|
||||
mUseVertexArrays(useVertexArrays),
|
||||
RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock, int storage)
|
||||
: RAS_OpenGLRasterizer(canvas, storage),
|
||||
mATI(false)
|
||||
{
|
||||
if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc."))
|
||||
@ -238,11 +237,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
|
||||
return;
|
||||
}
|
||||
}
|
||||
// derived mesh cannot use vertex array
|
||||
if (mUseVertexArrays && !ms.m_pDerivedMesh)
|
||||
RAS_VAOpenGLRasterizer::IndexPrimitives(ms);
|
||||
else
|
||||
RAS_OpenGLRasterizer::IndexPrimitives(ms);
|
||||
|
||||
RAS_OpenGLRasterizer::IndexPrimitives(ms);
|
||||
|
||||
if (ms.m_bDisplayList) {
|
||||
localSlot->EndList();
|
||||
@ -267,13 +263,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
|
||||
}
|
||||
}
|
||||
|
||||
// workaround: note how we do not use vertex arrays for making display
|
||||
// lists, since glVertexAttribPointerARB doesn't seem to work correct
|
||||
// in display lists on ATI? either a bug in the driver or in Blender ..
|
||||
if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh)
|
||||
RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms);
|
||||
else
|
||||
RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
|
||||
RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
|
||||
|
||||
if (ms.m_bDisplayList) {
|
||||
localSlot->EndList();
|
||||
@ -283,29 +273,17 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
|
||||
|
||||
bool RAS_ListRasterizer::Init(void)
|
||||
{
|
||||
if (mUseVertexArrays) {
|
||||
return RAS_VAOpenGLRasterizer::Init();
|
||||
} else {
|
||||
return RAS_OpenGLRasterizer::Init();
|
||||
}
|
||||
return RAS_OpenGLRasterizer::Init();
|
||||
}
|
||||
|
||||
void RAS_ListRasterizer::SetDrawingMode(int drawingmode)
|
||||
{
|
||||
if (mUseVertexArrays) {
|
||||
RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode);
|
||||
} else {
|
||||
RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
|
||||
}
|
||||
RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
|
||||
}
|
||||
|
||||
void RAS_ListRasterizer::Exit()
|
||||
{
|
||||
if (mUseVertexArrays) {
|
||||
RAS_VAOpenGLRasterizer::Exit();
|
||||
} else {
|
||||
RAS_OpenGLRasterizer::Exit();
|
||||
}
|
||||
RAS_OpenGLRasterizer::Exit();
|
||||
}
|
||||
|
||||
// eof
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define __RAS_LISTRASTERIZER_H__
|
||||
|
||||
#include "RAS_MaterialBucket.h"
|
||||
#include "RAS_VAOpenGLRasterizer.h"
|
||||
#include "RAS_OpenGLRasterizer.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
@ -49,7 +49,7 @@ typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
|
||||
typedef std::vector<RAS_ListSlot*> RAS_ListSlots; // indexed by material slot number
|
||||
typedef std::map<DerivedMesh*, RAS_ListSlots*> RAS_DerivedMeshLists;
|
||||
|
||||
class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
|
||||
class RAS_ListRasterizer : public RAS_OpenGLRasterizer
|
||||
{
|
||||
bool mUseVertexArrays;
|
||||
bool mATI;
|
||||
@ -61,7 +61,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
|
||||
|
||||
public:
|
||||
void RemoveListSlot(RAS_ListSlot* list);
|
||||
RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false);
|
||||
RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock=false, int storage=RAS_AUTO_STORAGE);
|
||||
virtual ~RAS_ListRasterizer();
|
||||
|
||||
virtual void IndexPrimitives(class RAS_MeshSlot& ms);
|
||||
|
@ -43,6 +43,10 @@
|
||||
#include "MT_CmMatrix4x4.h"
|
||||
#include "RAS_IRenderTools.h" // rendering text
|
||||
|
||||
#include "RAS_StorageIM.h"
|
||||
#include "RAS_StorageVA.h"
|
||||
#include "RAS_StorageVBO.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_extensions.h"
|
||||
@ -74,7 +78,7 @@ static GLuint right_eye_vinterlace_mask[32];
|
||||
*/
|
||||
static GLuint hinterlace_mask[33];
|
||||
|
||||
RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
|
||||
RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
|
||||
:RAS_IRasterizer(canvas),
|
||||
m_2DCanvas(canvas),
|
||||
m_fogenabled(false),
|
||||
@ -93,7 +97,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
|
||||
m_attrib_num(0),
|
||||
//m_last_alphablend(GPU_BLEND_SOLID),
|
||||
m_last_frontface(true),
|
||||
m_materialCachingInfo(0)
|
||||
m_materialCachingInfo(0),
|
||||
m_storage_type(storage)
|
||||
{
|
||||
m_viewmatrix.setIdentity();
|
||||
m_viewinvmatrix.setIdentity();
|
||||
@ -107,6 +112,24 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
|
||||
hinterlace_mask[32] = 0;
|
||||
|
||||
m_prevafvalue = GPU_get_anisotropic();
|
||||
|
||||
if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/)
|
||||
{
|
||||
m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
|
||||
m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
|
||||
m_storage_type = RAS_VBO;
|
||||
}
|
||||
else if (m_storage_type == RAS_VA || m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1)
|
||||
{
|
||||
m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
|
||||
m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
|
||||
m_storage_type = RAS_VA;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
|
||||
m_storage_type = RAS_IMMEDIATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -115,10 +138,16 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
|
||||
{
|
||||
// Restore the previous AF value
|
||||
GPU_set_anisotropic(m_prevafvalue);
|
||||
if (m_failsafe_storage && m_failsafe_storage != m_storage)
|
||||
delete m_failsafe_storage;
|
||||
|
||||
if (m_storage)
|
||||
delete m_storage;
|
||||
}
|
||||
|
||||
bool RAS_OpenGLRasterizer::Init()
|
||||
{
|
||||
bool storage_init;
|
||||
GPU_state_init();
|
||||
|
||||
|
||||
@ -146,7 +175,9 @@ bool RAS_OpenGLRasterizer::Init()
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
return true;
|
||||
storage_init = m_storage->Init();
|
||||
|
||||
return true && storage_init;
|
||||
}
|
||||
|
||||
|
||||
@ -267,6 +298,8 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
|
||||
void RAS_OpenGLRasterizer::Exit()
|
||||
{
|
||||
|
||||
m_storage->Exit();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearDepth(1.0);
|
||||
@ -289,7 +322,7 @@ void RAS_OpenGLRasterizer::Exit()
|
||||
bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
|
||||
{
|
||||
m_time = time;
|
||||
m_drawingmode = drawingmode;
|
||||
SetDrawingMode(drawingmode);
|
||||
|
||||
// Blender camera routine destroys the settings
|
||||
if (m_drawingmode < KX_SOLID)
|
||||
@ -328,6 +361,8 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
|
||||
|
||||
if (m_drawingmode == KX_WIREFRAME)
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
m_storage->SetDrawingMode(drawingmode);
|
||||
}
|
||||
|
||||
int RAS_OpenGLRasterizer::GetDrawingMode()
|
||||
@ -666,7 +701,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
|
||||
glattrib = -1;
|
||||
if (GLEW_ARB_vertex_program)
|
||||
for (unit=0; unit<m_attrib_num; unit++)
|
||||
if (m_attrib[unit] == RAS_TEXCO_UV1)
|
||||
if (m_attrib[unit] == RAS_TEXCO_UV)
|
||||
glattrib = unit;
|
||||
|
||||
rendertools->RenderText(polymat->GetDrawingMode(), polymat,
|
||||
@ -708,257 +743,20 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
|
||||
m_attrib[unit] = coords;
|
||||
}
|
||||
|
||||
void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
|
||||
{
|
||||
int unit;
|
||||
|
||||
if (GLEW_ARB_multitexture) {
|
||||
for (unit=0; unit<m_texco_num; unit++) {
|
||||
if (tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
|
||||
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
|
||||
continue;
|
||||
}
|
||||
switch (m_texco[unit]) {
|
||||
case RAS_TEXCO_ORCO:
|
||||
case RAS_TEXCO_GLOB:
|
||||
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
|
||||
break;
|
||||
case RAS_TEXCO_UV1:
|
||||
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
|
||||
break;
|
||||
case RAS_TEXCO_NORM:
|
||||
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
|
||||
break;
|
||||
case RAS_TEXTANGENT:
|
||||
glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
|
||||
break;
|
||||
case RAS_TEXCO_UV2:
|
||||
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_program) {
|
||||
for (unit=0; unit<m_attrib_num; unit++) {
|
||||
switch (m_attrib[unit]) {
|
||||
case RAS_TEXCO_ORCO:
|
||||
case RAS_TEXCO_GLOB:
|
||||
glVertexAttrib3fvARB(unit, tv.getXYZ());
|
||||
break;
|
||||
case RAS_TEXCO_UV1:
|
||||
glVertexAttrib2fvARB(unit, tv.getUV1());
|
||||
break;
|
||||
case RAS_TEXCO_NORM:
|
||||
glVertexAttrib3fvARB(unit, tv.getNormal());
|
||||
break;
|
||||
case RAS_TEXTANGENT:
|
||||
glVertexAttrib4fvARB(unit, tv.getTangent());
|
||||
break;
|
||||
case RAS_TEXCO_UV2:
|
||||
glVertexAttrib2fvARB(unit, tv.getUV2());
|
||||
break;
|
||||
case RAS_TEXCO_VCOL:
|
||||
glVertexAttrib4ubvARB(unit, tv.getRGBA());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
|
||||
{
|
||||
IndexPrimitivesInternal(ms, false);
|
||||
if (ms.m_pDerivedMesh)
|
||||
m_failsafe_storage->IndexPrimitives(ms);
|
||||
else
|
||||
m_storage->IndexPrimitives(ms);
|
||||
}
|
||||
|
||||
void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
|
||||
{
|
||||
IndexPrimitivesInternal(ms, true);
|
||||
}
|
||||
|
||||
static bool current_wireframe;
|
||||
static RAS_MaterialBucket *current_bucket;
|
||||
static RAS_IPolyMaterial *current_polymat;
|
||||
static RAS_MeshSlot *current_ms;
|
||||
static RAS_MeshObject *current_mesh;
|
||||
static int current_blmat_nr;
|
||||
static GPUVertexAttribs current_gpu_attribs;
|
||||
static Image *current_image;
|
||||
static int CheckMaterialDM(int matnr, void *attribs)
|
||||
{
|
||||
// only draw the current material
|
||||
if (matnr != current_blmat_nr)
|
||||
return 0;
|
||||
GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
|
||||
if (gattribs)
|
||||
memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
static int CheckTexfaceDM(void *mcol, int index)
|
||||
{
|
||||
|
||||
// index is the original face index, retrieve the polygon
|
||||
RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
|
||||
current_mesh->GetPolygon(index) : NULL;
|
||||
if (polygon && polygon->GetMaterial() == current_bucket) {
|
||||
// must handle color.
|
||||
if (current_wireframe)
|
||||
return 2;
|
||||
if (current_ms->m_bObjectColor) {
|
||||
MT_Vector4& rgba = current_ms->m_RGBAcolor;
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
// don't use mcol
|
||||
return 2;
|
||||
}
|
||||
if (!mcol) {
|
||||
// we have to set the color from the material
|
||||
unsigned char rgba[4];
|
||||
current_polymat->GetMaterialRGBAColor(rgba);
|
||||
glColor4ubv((const GLubyte *)rgba);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
|
||||
{
|
||||
|
||||
// index is the original face index, retrieve the polygon
|
||||
if (matnr == current_blmat_nr &&
|
||||
(tface == NULL || tface->tpage == current_image)) {
|
||||
// must handle color.
|
||||
if (current_wireframe)
|
||||
return DM_DRAW_OPTION_NO_MCOL;
|
||||
if (current_ms->m_bObjectColor) {
|
||||
MT_Vector4& rgba = current_ms->m_RGBAcolor;
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
// don't use mcol
|
||||
return DM_DRAW_OPTION_NO_MCOL;
|
||||
}
|
||||
if (!has_mcol) {
|
||||
// we have to set the color from the material
|
||||
unsigned char rgba[4];
|
||||
current_polymat->GetMaterialRGBAColor(rgba);
|
||||
glColor4ubv((const GLubyte *)rgba);
|
||||
return DM_DRAW_OPTION_NO_MCOL;
|
||||
}
|
||||
return DM_DRAW_OPTION_NORMAL;
|
||||
}
|
||||
return DM_DRAW_OPTION_SKIP;
|
||||
}
|
||||
|
||||
void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
|
||||
{
|
||||
bool obcolor = ms.m_bObjectColor;
|
||||
bool wireframe = m_drawingmode <= KX_WIREFRAME;
|
||||
MT_Vector4& rgba = ms.m_RGBAcolor;
|
||||
RAS_MeshSlot::iterator it;
|
||||
|
||||
if (ms.m_pDerivedMesh) {
|
||||
// mesh data is in derived mesh,
|
||||
current_bucket = ms.m_bucket;
|
||||
current_polymat = current_bucket->GetPolyMaterial();
|
||||
current_ms = &ms;
|
||||
current_mesh = ms.m_mesh;
|
||||
current_wireframe = wireframe;
|
||||
// MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
|
||||
|
||||
// handle two-side
|
||||
if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
|
||||
this->SetCullFace(true);
|
||||
else
|
||||
this->SetCullFace(false);
|
||||
|
||||
if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
|
||||
// GetMaterialIndex return the original mface material index,
|
||||
// increment by 1 to match what derived mesh is doing
|
||||
current_blmat_nr = current_polymat->GetMaterialIndex()+1;
|
||||
// For GLSL we need to retrieve the GPU material attribute
|
||||
Material* blmat = current_polymat->GetBlenderMaterial();
|
||||
Scene* blscene = current_polymat->GetBlenderScene();
|
||||
if (!wireframe && blscene && blmat)
|
||||
GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs);
|
||||
else
|
||||
memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs));
|
||||
// DM draw can mess up blending mode, restore at the end
|
||||
int current_blend_mode = GPU_get_material_alpha_blend();
|
||||
ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
|
||||
GPU_set_material_alpha_blend(current_blend_mode);
|
||||
}
|
||||
else {
|
||||
//ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
|
||||
current_blmat_nr = current_polymat->GetMaterialIndex();
|
||||
current_image = current_polymat->GetBlenderImage();
|
||||
ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// iterate over display arrays, each containing an index + vertex array
|
||||
for (ms.begin(it); !ms.end(it); ms.next(it)) {
|
||||
RAS_TexVert *vertex;
|
||||
size_t i, j, numvert;
|
||||
|
||||
numvert = it.array->m_type;
|
||||
|
||||
if (it.array->m_type == RAS_DisplayArray::LINE) {
|
||||
// line drawing
|
||||
glBegin(GL_LINES);
|
||||
|
||||
for (i=0; i<it.totindex; i+=2)
|
||||
{
|
||||
vertex = &it.vertex[it.index[i]];
|
||||
glVertex3fv(vertex->getXYZ());
|
||||
|
||||
vertex = &it.vertex[it.index[i+1]];
|
||||
glVertex3fv(vertex->getXYZ());
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
// triangle and quad drawing
|
||||
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
|
||||
glBegin(GL_TRIANGLES);
|
||||
else
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (i=0; i<it.totindex; i+=numvert)
|
||||
{
|
||||
if (obcolor)
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
|
||||
for (j=0; j<numvert; j++) {
|
||||
vertex = &it.vertex[it.index[i+j]];
|
||||
|
||||
if (!wireframe) {
|
||||
if (!obcolor)
|
||||
glColor4ubv((const GLubyte *)(vertex->getRGBA()));
|
||||
|
||||
glNormal3fv(vertex->getNormal());
|
||||
|
||||
if (multi)
|
||||
TexCoord(*vertex);
|
||||
else
|
||||
glTexCoord2fv(vertex->getUV1());
|
||||
}
|
||||
|
||||
glVertex3fv(vertex->getXYZ());
|
||||
}
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
if (ms.m_pDerivedMesh)
|
||||
m_failsafe_storage->IndexPrimitivesMulti(ms);
|
||||
else
|
||||
m_storage->IndexPrimitivesMulti(ms);
|
||||
}
|
||||
|
||||
void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
|
||||
|
@ -41,6 +41,7 @@
|
||||
using namespace std;
|
||||
|
||||
#include "RAS_IRasterizer.h"
|
||||
#include "RAS_IStorage.h"
|
||||
#include "RAS_MaterialBucket.h"
|
||||
#include "RAS_ICanvas.h"
|
||||
|
||||
@ -83,7 +84,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
|
||||
float m_ambr;
|
||||
float m_ambg;
|
||||
float m_ambb;
|
||||
|
||||
double m_time;
|
||||
MT_Matrix4x4 m_viewmatrix;
|
||||
MT_Matrix4x4 m_viewinvmatrix;
|
||||
@ -115,9 +115,15 @@ protected:
|
||||
/** Stores the caching information for the last material activated. */
|
||||
RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
|
||||
|
||||
/** Making use of a Strategy desing pattern for storage behavior.
|
||||
Examples of concrete strategies: Vertex Arrays, VBOs, Immediate Mode*/
|
||||
int m_storage_type;
|
||||
RAS_IStorage* m_storage;
|
||||
RAS_IStorage* m_failsafe_storage; //So derived mesh can use immediate mode
|
||||
|
||||
public:
|
||||
double GetTime();
|
||||
RAS_OpenGLRasterizer(RAS_ICanvas* canv);
|
||||
RAS_OpenGLRasterizer(RAS_ICanvas* canv, int storage=RAS_AUTO_STORAGE);
|
||||
virtual ~RAS_OpenGLRasterizer();
|
||||
|
||||
/*enum DrawType
|
||||
@ -166,8 +172,6 @@ public:
|
||||
class RAS_IPolyMaterial* polymat,
|
||||
class RAS_IRenderTools* rendertools);
|
||||
|
||||
void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
|
||||
|
||||
virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat);
|
||||
virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat);
|
||||
virtual void SetViewMatrix(
|
||||
|
@ -0,0 +1,310 @@
|
||||
/*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "RAS_StorageIM.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
extern "C"{
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
}
|
||||
|
||||
RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
|
||||
m_texco_num(texco_num),
|
||||
m_texco(texco),
|
||||
m_attrib_num(attrib_num),
|
||||
m_attrib(attrib)
|
||||
{
|
||||
}
|
||||
RAS_StorageIM::~RAS_StorageIM()
|
||||
{
|
||||
}
|
||||
|
||||
bool RAS_StorageIM::Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void RAS_StorageIM::Exit()
|
||||
{
|
||||
}
|
||||
|
||||
void RAS_StorageIM::IndexPrimitives(RAS_MeshSlot& ms)
|
||||
{
|
||||
IndexPrimitivesInternal(ms, false);
|
||||
}
|
||||
|
||||
void RAS_StorageIM::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
|
||||
{
|
||||
IndexPrimitivesInternal(ms, true);
|
||||
}
|
||||
|
||||
void RAS_StorageIM::TexCoord(const RAS_TexVert &tv)
|
||||
{
|
||||
int unit;
|
||||
|
||||
if (GLEW_ARB_multitexture) {
|
||||
for (unit = 0; unit < *m_texco_num; unit++) {
|
||||
switch(m_texco[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getXYZ());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, tv.getUV(unit));
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getNormal());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
glMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, tv.getTangent());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_program) {
|
||||
int uv = 0;
|
||||
for (unit = 0; unit < *m_attrib_num; unit++) {
|
||||
switch(m_attrib[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
glVertexAttrib3fvARB(unit, tv.getXYZ());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
glVertexAttrib2fvARB(unit, tv.getUV(uv++));
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
glVertexAttrib3fvARB(unit, tv.getNormal());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
glVertexAttrib4fvARB(unit, tv.getTangent());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_VCOL:
|
||||
glVertexAttrib4ubvARB(unit, tv.getRGBA());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RAS_StorageIM::SetCullFace(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
glEnable(GL_CULL_FACE);
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
static bool current_wireframe;
|
||||
static RAS_MaterialBucket *current_bucket;
|
||||
static RAS_IPolyMaterial *current_polymat;
|
||||
static RAS_MeshSlot *current_ms;
|
||||
static RAS_MeshObject *current_mesh;
|
||||
static int current_blmat_nr;
|
||||
static GPUVertexAttribs current_gpu_attribs;
|
||||
static Image *current_image;
|
||||
static int CheckMaterialDM(int matnr, void *attribs)
|
||||
{
|
||||
// only draw the current material
|
||||
if (matnr != current_blmat_nr)
|
||||
return 0;
|
||||
GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
|
||||
if (gattribs)
|
||||
memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
static int CheckTexfaceDM(void *mcol, int index)
|
||||
{
|
||||
|
||||
// index is the original face index, retrieve the polygon
|
||||
RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
|
||||
current_mesh->GetPolygon(index) : NULL;
|
||||
if (polygon && polygon->GetMaterial() == current_bucket) {
|
||||
// must handle color.
|
||||
if (current_wireframe)
|
||||
return 2;
|
||||
if (current_ms->m_bObjectColor) {
|
||||
MT_Vector4& rgba = current_ms->m_RGBAcolor;
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
// don't use mcol
|
||||
return 2;
|
||||
}
|
||||
if (!mcol) {
|
||||
// we have to set the color from the material
|
||||
unsigned char rgba[4];
|
||||
current_polymat->GetMaterialRGBAColor(rgba);
|
||||
glColor4ubv((const GLubyte *)rgba);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
|
||||
{
|
||||
|
||||
// index is the original face index, retrieve the polygon
|
||||
if (matnr == current_blmat_nr &&
|
||||
(tface == NULL || tface->tpage == current_image)) {
|
||||
// must handle color.
|
||||
if (current_wireframe)
|
||||
return DM_DRAW_OPTION_NO_MCOL;
|
||||
if (current_ms->m_bObjectColor) {
|
||||
MT_Vector4& rgba = current_ms->m_RGBAcolor;
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
// don't use mcol
|
||||
return DM_DRAW_OPTION_NO_MCOL;
|
||||
}
|
||||
if (!has_mcol) {
|
||||
// we have to set the color from the material
|
||||
unsigned char rgba[4];
|
||||
current_polymat->GetMaterialRGBAColor(rgba);
|
||||
glColor4ubv((const GLubyte *)rgba);
|
||||
return DM_DRAW_OPTION_NO_MCOL;
|
||||
}
|
||||
return DM_DRAW_OPTION_NORMAL;
|
||||
}
|
||||
return DM_DRAW_OPTION_SKIP;
|
||||
}
|
||||
|
||||
void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
|
||||
{
|
||||
bool obcolor = ms.m_bObjectColor;
|
||||
bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
|
||||
MT_Vector4& rgba = ms.m_RGBAcolor;
|
||||
RAS_MeshSlot::iterator it;
|
||||
|
||||
if (ms.m_pDerivedMesh) {
|
||||
// mesh data is in derived mesh,
|
||||
current_bucket = ms.m_bucket;
|
||||
current_polymat = current_bucket->GetPolyMaterial();
|
||||
current_ms = &ms;
|
||||
current_mesh = ms.m_mesh;
|
||||
current_wireframe = wireframe;
|
||||
// MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
|
||||
|
||||
// handle two-side
|
||||
if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
|
||||
this->SetCullFace(true);
|
||||
else
|
||||
this->SetCullFace(false);
|
||||
|
||||
if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
|
||||
// GetMaterialIndex return the original mface material index,
|
||||
// increment by 1 to match what derived mesh is doing
|
||||
current_blmat_nr = current_polymat->GetMaterialIndex()+1;
|
||||
// For GLSL we need to retrieve the GPU material attribute
|
||||
Material* blmat = current_polymat->GetBlenderMaterial();
|
||||
Scene* blscene = current_polymat->GetBlenderScene();
|
||||
if (!wireframe && blscene && blmat)
|
||||
GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs);
|
||||
else
|
||||
memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs));
|
||||
// DM draw can mess up blending mode, restore at the end
|
||||
int current_blend_mode = GPU_get_material_alpha_blend();
|
||||
ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
|
||||
GPU_set_material_alpha_blend(current_blend_mode);
|
||||
} else {
|
||||
//ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
|
||||
current_blmat_nr = current_polymat->GetMaterialIndex();
|
||||
current_image = current_polymat->GetBlenderImage();
|
||||
ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// iterate over display arrays, each containing an index + vertex array
|
||||
for (ms.begin(it); !ms.end(it); ms.next(it)) {
|
||||
RAS_TexVert *vertex;
|
||||
size_t i, j, numvert;
|
||||
|
||||
numvert = it.array->m_type;
|
||||
|
||||
if (it.array->m_type == RAS_DisplayArray::LINE) {
|
||||
// line drawing
|
||||
glBegin(GL_LINES);
|
||||
|
||||
for (i = 0; i < it.totindex; i += 2)
|
||||
{
|
||||
vertex = &it.vertex[it.index[i]];
|
||||
glVertex3fv(vertex->getXYZ());
|
||||
|
||||
vertex = &it.vertex[it.index[i+1]];
|
||||
glVertex3fv(vertex->getXYZ());
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
// triangle and quad drawing
|
||||
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
|
||||
glBegin(GL_TRIANGLES);
|
||||
else
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (i = 0; i < it.totindex; i += numvert)
|
||||
{
|
||||
if (obcolor)
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
|
||||
for (j = 0; j < numvert; j++) {
|
||||
vertex = &it.vertex[it.index[i+j]];
|
||||
|
||||
if (!wireframe) {
|
||||
if (!obcolor)
|
||||
glColor4ubv((const GLubyte *)(vertex->getRGBA()));
|
||||
|
||||
glNormal3fv(vertex->getNormal());
|
||||
|
||||
if (multi)
|
||||
TexCoord(*vertex);
|
||||
else
|
||||
glTexCoord2fv(vertex->getUV(0));
|
||||
}
|
||||
|
||||
glVertex3fv(vertex->getXYZ());
|
||||
}
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __KX_IMMEDIATEMODESTORAGE
|
||||
#define __KX_IMMEDIATEMODESTORAGE
|
||||
|
||||
#include "RAS_IStorage.h"
|
||||
#include "RAS_IRasterizer.h"
|
||||
|
||||
class RAS_StorageIM : public RAS_IStorage
|
||||
{
|
||||
public:
|
||||
RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
|
||||
virtual ~RAS_StorageIM();
|
||||
|
||||
virtual bool Init();
|
||||
virtual void Exit();
|
||||
|
||||
virtual void IndexPrimitives(RAS_MeshSlot& ms);
|
||||
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
|
||||
|
||||
virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
|
||||
|
||||
protected:
|
||||
int m_drawingmode;
|
||||
int* m_texco_num;
|
||||
int* m_attrib_num;
|
||||
RAS_IRasterizer::TexCoGen* m_texco;
|
||||
RAS_IRasterizer::TexCoGen* m_attrib;
|
||||
|
||||
void TexCoord(const RAS_TexVert &tv);
|
||||
void SetCullFace(bool enable);
|
||||
|
||||
void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageIM"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_IMMEDIATEMODESTORAGE
|
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "RAS_StorageVA.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
|
||||
m_texco_num(texco_num),
|
||||
m_texco(texco),
|
||||
m_attrib_num(attrib_num),
|
||||
m_attrib(attrib),
|
||||
m_last_texco_num(0),
|
||||
m_last_attrib_num(0)
|
||||
{
|
||||
}
|
||||
|
||||
RAS_StorageVA::~RAS_StorageVA()
|
||||
{
|
||||
}
|
||||
|
||||
bool RAS_StorageVA::Init()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RAS_StorageVA::Exit()
|
||||
{
|
||||
}
|
||||
|
||||
void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
|
||||
{
|
||||
static const GLsizei stride = sizeof(RAS_TexVert);
|
||||
bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
|
||||
RAS_MeshSlot::iterator it;
|
||||
GLenum drawmode;
|
||||
|
||||
if (!wireframe)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
// use glDrawElements to draw each vertexarray
|
||||
for (ms.begin(it); !ms.end(it); ms.next(it)) {
|
||||
if (it.totindex == 0)
|
||||
continue;
|
||||
|
||||
// drawing mode
|
||||
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
|
||||
drawmode = GL_TRIANGLES;
|
||||
else if (it.array->m_type == RAS_DisplayArray::QUAD)
|
||||
drawmode = GL_QUADS;
|
||||
else
|
||||
drawmode = GL_LINES;
|
||||
|
||||
// colors
|
||||
if (drawmode != GL_LINES && !wireframe) {
|
||||
if (ms.m_bObjectColor) {
|
||||
const MT_Vector4& rgba = ms.m_RGBAcolor;
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
}
|
||||
else {
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
else
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
|
||||
glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
|
||||
if (!wireframe) {
|
||||
glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
|
||||
if (glIsEnabled(GL_COLOR_ARRAY))
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
|
||||
}
|
||||
|
||||
// here the actual drawing takes places
|
||||
glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
if (!wireframe) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
|
||||
{
|
||||
static const GLsizei stride = sizeof(RAS_TexVert);
|
||||
bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME, use_color_array;
|
||||
RAS_MeshSlot::iterator it;
|
||||
GLenum drawmode;
|
||||
|
||||
if (!wireframe)
|
||||
EnableTextures(true);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
// use glDrawElements to draw each vertexarray
|
||||
for (ms.begin(it); !ms.end(it); ms.next(it)) {
|
||||
if (it.totindex == 0)
|
||||
continue;
|
||||
|
||||
// drawing mode
|
||||
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
|
||||
drawmode = GL_TRIANGLES;
|
||||
else if (it.array->m_type == RAS_DisplayArray::QUAD)
|
||||
drawmode = GL_QUADS;
|
||||
else
|
||||
drawmode = GL_LINES;
|
||||
|
||||
// colors
|
||||
if (drawmode != GL_LINES && !wireframe) {
|
||||
if (ms.m_bObjectColor) {
|
||||
const MT_Vector4& rgba = ms.m_RGBAcolor;
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
use_color_array = false;
|
||||
}
|
||||
else {
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
use_color_array = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
|
||||
glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
|
||||
|
||||
if (!wireframe) {
|
||||
TexCoordPtr(it.vertex);
|
||||
if (use_color_array)
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
|
||||
}
|
||||
|
||||
// here the actual drawing takes places
|
||||
glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
if (!wireframe) {
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
EnableTextures(false);
|
||||
}
|
||||
}
|
||||
|
||||
void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv)
|
||||
{
|
||||
/* note: this function must closely match EnableTextures to enable/disable
|
||||
* the right arrays, otherwise coordinate and attribute pointers from other
|
||||
* materials can still be used and cause crashes */
|
||||
int unit;
|
||||
|
||||
if (GLEW_ARB_multitexture)
|
||||
{
|
||||
for (unit = 0; unit < *m_texco_num; unit++)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
|
||||
switch (m_texco[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit));
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_program) {
|
||||
int uv = 0;
|
||||
for (unit = 0; unit < *m_attrib_num; unit++) {
|
||||
switch (m_attrib[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++));
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_VCOL:
|
||||
glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RAS_StorageVA::EnableTextures(bool enable)
|
||||
{
|
||||
RAS_IRasterizer::TexCoGen *texco, *attrib;
|
||||
int unit, texco_num, attrib_num;
|
||||
|
||||
/* we cache last texcoords and attribs to ensure we disable the ones that
|
||||
* were actually last set */
|
||||
if (enable) {
|
||||
texco = m_texco;
|
||||
texco_num = *m_texco_num;
|
||||
attrib = m_attrib;
|
||||
attrib_num = *m_attrib_num;
|
||||
|
||||
memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num));
|
||||
m_last_texco_num = *m_texco_num;
|
||||
memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num));
|
||||
m_last_attrib_num = *m_attrib_num;
|
||||
}
|
||||
else {
|
||||
texco = m_last_texco;
|
||||
texco_num = m_last_texco_num;
|
||||
attrib = m_last_attrib;
|
||||
attrib_num = m_last_attrib_num;
|
||||
}
|
||||
|
||||
if (GLEW_ARB_multitexture) {
|
||||
for (unit = 0; unit < texco_num; unit++) {
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB + unit);
|
||||
|
||||
switch (texco[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
break;
|
||||
default:
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
else {
|
||||
if (texco_num) {
|
||||
if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_program) {
|
||||
for (unit = 0; unit < attrib_num; unit++) {
|
||||
switch (attrib[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
case RAS_IRasterizer::RAS_TEXCO_VCOL:
|
||||
if (enable) glEnableVertexAttribArrayARB(unit);
|
||||
else glDisableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
default:
|
||||
glDisableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
m_last_texco_num = 0;
|
||||
m_last_attrib_num = 0;
|
||||
}
|
||||
}
|
||||
|
@ -25,46 +25,53 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file RAS_VAOpenGLRasterizer.h
|
||||
* \ingroup bgerastogl
|
||||
*/
|
||||
#ifndef __KX_VERTEXARRAYSTORAGE
|
||||
#define __KX_VERTEXARRAYSTORAGE
|
||||
|
||||
#ifndef __RAS_VAOPENGLRASTERIZER_H__
|
||||
#define __RAS_VAOPENGLRASTERIZER_H__
|
||||
#include "RAS_IStorage.h"
|
||||
#include "RAS_IRasterizer.h"
|
||||
|
||||
#include "RAS_OpenGLRasterizer.h"
|
||||
|
||||
class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer
|
||||
class RAS_StorageVA : public RAS_IStorage
|
||||
{
|
||||
void TexCoordPtr(const RAS_TexVert *tv);
|
||||
/* bool m_Lock; */ /* UNUSED */
|
||||
|
||||
TexCoGen m_last_texco[RAS_MAX_TEXCO];
|
||||
TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
|
||||
int m_last_texco_num;
|
||||
int m_last_attrib_num;
|
||||
|
||||
public:
|
||||
RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false);
|
||||
virtual ~RAS_VAOpenGLRasterizer();
|
||||
RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
|
||||
virtual ~RAS_StorageVA();
|
||||
|
||||
virtual bool Init();
|
||||
virtual void Exit();
|
||||
|
||||
virtual void SetDrawingMode(int drawingmode);
|
||||
|
||||
virtual void IndexPrimitives(class RAS_MeshSlot& ms);
|
||||
virtual void IndexPrimitives(RAS_MeshSlot& ms);
|
||||
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
|
||||
|
||||
private:
|
||||
virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
|
||||
|
||||
protected:
|
||||
int m_drawingmode;
|
||||
|
||||
int* m_texco_num;
|
||||
int* m_attrib_num;
|
||||
|
||||
int m_last_texco_num;
|
||||
int m_last_attrib_num;
|
||||
|
||||
RAS_IRasterizer::TexCoGen* m_texco;
|
||||
RAS_IRasterizer::TexCoGen* m_attrib;
|
||||
|
||||
RAS_IRasterizer::TexCoGen m_last_texco[RAS_MAX_TEXCO];
|
||||
RAS_IRasterizer::TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
|
||||
|
||||
virtual void EnableTextures(bool enable);
|
||||
//virtual bool QueryArrays() {return true;}
|
||||
//virtual bool QueryLists() {return m_Lock;}
|
||||
virtual void TexCoordPtr(const RAS_TexVert *tv);
|
||||
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_VAOpenGLRasterizer")
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __RAS_VAOPENGLRASTERIZER_H__ */
|
||||
#endif //__KX_VERTEXARRAYSTORAGE
|
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "RAS_StorageVBO.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
VBO::VBO(RAS_DisplayArray *data, unsigned int indices)
|
||||
{
|
||||
this->data = data;
|
||||
this->size = data->m_vertex.size();
|
||||
this->indices = indices;
|
||||
this->stride = 32*sizeof(GLfloat); // ATI cards really like 32byte aligned VBOs, so we add a little padding
|
||||
|
||||
// Determine drawmode
|
||||
if (data->m_type == data->QUAD)
|
||||
this->mode = GL_QUADS;
|
||||
else if (data->m_type == data->TRIANGLE)
|
||||
this->mode = GL_TRIANGLES;
|
||||
else
|
||||
this->mode = GL_LINE;
|
||||
|
||||
// Generate Buffers
|
||||
glGenBuffersARB(1, &this->ibo);
|
||||
glGenBuffersARB(1, &this->vbo_id);
|
||||
|
||||
// Fill the buffers with initial data
|
||||
UpdateIndices();
|
||||
UpdateData();
|
||||
|
||||
// Establish offsets
|
||||
this->vertex_offset = 0;
|
||||
this->normal_offset = (void*)(3*sizeof(GLfloat));
|
||||
this->tangent_offset = (void*)(6*sizeof(GLfloat));
|
||||
this->color_offset = (void*)(10*sizeof(GLfloat));
|
||||
this->uv_offset = (void*)(11*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
VBO::~VBO()
|
||||
{
|
||||
glDeleteBuffersARB(1, &this->ibo);
|
||||
glDeleteBuffersARB(1, &this->vbo_id);
|
||||
}
|
||||
|
||||
void VBO::UpdateData()
|
||||
{
|
||||
unsigned int i, j, k;
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, NULL, GL_STATIC_DRAW);
|
||||
|
||||
// Map the buffer
|
||||
GLfloat *vbo_map = (GLfloat*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
|
||||
// Gather data
|
||||
for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat))
|
||||
{
|
||||
memcpy(&vbo_map[j], data->m_vertex[i].getXYZ(), sizeof(float)*3);
|
||||
memcpy(&vbo_map[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3);
|
||||
memcpy(&vbo_map[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4);
|
||||
memcpy(&vbo_map[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4);
|
||||
|
||||
for (k = 0; k < RAS_TexVert::MAX_UNIT; k++)
|
||||
memcpy(&vbo_map[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2);
|
||||
}
|
||||
|
||||
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
|
||||
}
|
||||
|
||||
void VBO::UpdateIndices()
|
||||
{
|
||||
int space = data->m_index.size() * sizeof(GLushort);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
|
||||
|
||||
// Upload Data to VBO
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi)
|
||||
{
|
||||
int unit;
|
||||
|
||||
// Bind buffers
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
|
||||
|
||||
// Vertexes
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
|
||||
|
||||
// Normals
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, this->stride, this->normal_offset);
|
||||
|
||||
// Colors
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset);
|
||||
|
||||
if (multi)
|
||||
{
|
||||
for (unit = 0; unit < texco_num; ++unit)
|
||||
{
|
||||
glClientActiveTexture(GL_TEXTURE0_ARB + unit);
|
||||
switch (texco[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit)));
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset);
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
else //TexFace
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset);
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_program)
|
||||
{
|
||||
int uv = 0;
|
||||
for (unit = 0; unit < attrib_num; ++unit)
|
||||
{
|
||||
switch (attrib[unit]) {
|
||||
case RAS_IRasterizer::RAS_TEXCO_ORCO:
|
||||
case RAS_IRasterizer::RAS_TEXCO_GLOB:
|
||||
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset);
|
||||
glEnableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_UV:
|
||||
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv));
|
||||
uv += sizeof(GLfloat)*2;
|
||||
glEnableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXCO_NORM:
|
||||
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset);
|
||||
glEnableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
case RAS_IRasterizer::RAS_TEXTANGENT:
|
||||
glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset);
|
||||
glEnableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (GLEW_ARB_vertex_program)
|
||||
{
|
||||
for (int i = 0; i < attrib_num; ++i)
|
||||
glDisableVertexAttribArrayARB(i);
|
||||
}
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
}
|
||||
|
||||
RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib):
|
||||
m_texco_num(texco_num),
|
||||
m_texco(texco),
|
||||
m_attrib_num(attrib_num),
|
||||
m_attrib(attrib)
|
||||
{
|
||||
}
|
||||
|
||||
RAS_StorageVBO::~RAS_StorageVBO()
|
||||
{
|
||||
}
|
||||
|
||||
bool RAS_StorageVBO::Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void RAS_StorageVBO::Exit()
|
||||
{
|
||||
m_vbo_lookup.clear();
|
||||
}
|
||||
|
||||
void RAS_StorageVBO::IndexPrimitives(RAS_MeshSlot& ms)
|
||||
{
|
||||
IndexPrimitivesInternal(ms, false);
|
||||
}
|
||||
|
||||
void RAS_StorageVBO::IndexPrimitivesMulti(RAS_MeshSlot& ms)
|
||||
{
|
||||
IndexPrimitivesInternal(ms, true);
|
||||
}
|
||||
|
||||
void RAS_StorageVBO::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
|
||||
{
|
||||
RAS_MeshSlot::iterator it;
|
||||
VBO *vbo;
|
||||
|
||||
for (ms.begin(it); !ms.end(it); ms.next(it))
|
||||
{
|
||||
vbo = m_vbo_lookup[it.array];
|
||||
|
||||
if (vbo == 0)
|
||||
m_vbo_lookup[it.array] = vbo = new VBO(it.array, it.totindex);
|
||||
|
||||
// Update the vbo
|
||||
if (ms.m_mesh->MeshModified())
|
||||
{
|
||||
vbo->UpdateData();
|
||||
}
|
||||
|
||||
vbo->Draw(*m_texco_num, m_texco, *m_attrib_num, m_attrib, multi);
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __KX_VERTEXBUFFEROBJECTSTORAGE
|
||||
#define __KX_VERTEXBUFFEROBJECTSTORAGE
|
||||
|
||||
#include <map>
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "RAS_IStorage.h"
|
||||
#include "RAS_IRasterizer.h"
|
||||
|
||||
#include "RAS_OpenGLRasterizer.h"
|
||||
|
||||
class VBO
|
||||
{
|
||||
public:
|
||||
VBO(RAS_DisplayArray *data, unsigned int indices);
|
||||
~VBO();
|
||||
|
||||
void Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi);
|
||||
|
||||
void UpdateData();
|
||||
void UpdateIndices();
|
||||
private:
|
||||
RAS_DisplayArray* data;
|
||||
GLuint size;
|
||||
GLuint stride;
|
||||
GLuint indices;
|
||||
GLenum mode;
|
||||
GLuint ibo;
|
||||
GLuint vbo_id;
|
||||
|
||||
void* vertex_offset;
|
||||
void* normal_offset;
|
||||
void* color_offset;
|
||||
void* tangent_offset;
|
||||
void* uv_offset;
|
||||
};
|
||||
|
||||
class RAS_StorageVBO : public RAS_IStorage
|
||||
{
|
||||
|
||||
public:
|
||||
RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
|
||||
virtual ~RAS_StorageVBO();
|
||||
|
||||
virtual bool Init();
|
||||
virtual void Exit();
|
||||
|
||||
virtual void IndexPrimitives(RAS_MeshSlot& ms);
|
||||
virtual void IndexPrimitivesMulti(RAS_MeshSlot& ms);
|
||||
|
||||
virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
|
||||
|
||||
protected:
|
||||
int m_drawingmode;
|
||||
|
||||
int* m_texco_num;
|
||||
int* m_attrib_num;
|
||||
|
||||
RAS_IRasterizer::TexCoGen* m_texco;
|
||||
RAS_IRasterizer::TexCoGen* m_attrib;
|
||||
|
||||
std::map<RAS_DisplayArray*, class VBO*> m_vbo_lookup;
|
||||
|
||||
virtual void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
public:
|
||||
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
|
||||
void operator delete( void *mem ) { MEM_freeN(mem); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //__KX_VERTEXBUFFEROBJECTSTORAGE
|
@ -1,382 +0,0 @@
|
||||
/*
|
||||
* ***** BEGIN GPL 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.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
|
||||
* \ingroup bgerastogl
|
||||
*/
|
||||
|
||||
#include "RAS_VAOpenGLRasterizer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "GPU_extensions.h"
|
||||
|
||||
#include "STR_String.h"
|
||||
#include "RAS_TexVert.h"
|
||||
#include "MT_CmMatrix4x4.h"
|
||||
#include "RAS_IRenderTools.h" // rendering text
|
||||
|
||||
RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock)
|
||||
: RAS_OpenGLRasterizer(canvas),
|
||||
/* m_Lock(lock && GLEW_EXT_compiled_vertex_array), */ /* UNUSED */
|
||||
m_last_texco_num(0),
|
||||
m_last_attrib_num(0)
|
||||
{
|
||||
}
|
||||
|
||||
RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
|
||||
{
|
||||
}
|
||||
|
||||
bool RAS_VAOpenGLRasterizer::Init(void)
|
||||
{
|
||||
|
||||
bool result = RAS_OpenGLRasterizer::Init();
|
||||
|
||||
if (result)
|
||||
{
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
|
||||
{
|
||||
m_drawingmode = drawingmode;
|
||||
|
||||
switch (m_drawingmode)
|
||||
{
|
||||
case KX_BOUNDINGBOX:
|
||||
case KX_WIREFRAME:
|
||||
//glDisableClientState(GL_COLOR_ARRAY);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
break;
|
||||
case KX_SOLID:
|
||||
//glDisableClientState(GL_COLOR_ARRAY);
|
||||
break;
|
||||
case KX_TEXTURED:
|
||||
case KX_SHADED:
|
||||
case KX_SHADOW:
|
||||
//glEnableClientState(GL_COLOR_ARRAY);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RAS_VAOpenGLRasterizer::Exit()
|
||||
{
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
RAS_OpenGLRasterizer::Exit();
|
||||
}
|
||||
|
||||
void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
|
||||
{
|
||||
static const GLsizei stride = sizeof(RAS_TexVert);
|
||||
bool wireframe = m_drawingmode <= KX_WIREFRAME;
|
||||
RAS_MeshSlot::iterator it;
|
||||
GLenum drawmode;
|
||||
|
||||
if (ms.m_pDerivedMesh) {
|
||||
// cannot be handled here, pass to RAS_OpenGLRasterizer
|
||||
RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wireframe)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// use glDrawElements to draw each vertexarray
|
||||
for (ms.begin(it); !ms.end(it); ms.next(it)) {
|
||||
if (it.totindex == 0)
|
||||
continue;
|
||||
|
||||
// drawing mode
|
||||
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
|
||||
drawmode = GL_TRIANGLES;
|
||||
else if (it.array->m_type == RAS_DisplayArray::QUAD)
|
||||
drawmode = GL_QUADS;
|
||||
else
|
||||
drawmode = GL_LINES;
|
||||
|
||||
// colors
|
||||
if (drawmode != GL_LINES && !wireframe) {
|
||||
if (ms.m_bObjectColor) {
|
||||
const MT_Vector4& rgba = ms.m_RGBAcolor;
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
}
|
||||
else {
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
else
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
|
||||
glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
|
||||
if (!wireframe) {
|
||||
glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1());
|
||||
if (glIsEnabled(GL_COLOR_ARRAY))
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
|
||||
}
|
||||
|
||||
// here the actual drawing takes places
|
||||
glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
|
||||
}
|
||||
|
||||
if (!wireframe) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
|
||||
{
|
||||
static const GLsizei stride = sizeof(RAS_TexVert);
|
||||
bool wireframe = m_drawingmode <= KX_WIREFRAME;
|
||||
RAS_MeshSlot::iterator it;
|
||||
GLenum drawmode;
|
||||
|
||||
if (ms.m_pDerivedMesh) {
|
||||
// cannot be handled here, pass to RAS_OpenGLRasterizer
|
||||
RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wireframe)
|
||||
EnableTextures(true);
|
||||
|
||||
// use glDrawElements to draw each vertexarray
|
||||
for (ms.begin(it); !ms.end(it); ms.next(it)) {
|
||||
if (it.totindex == 0)
|
||||
continue;
|
||||
|
||||
// drawing mode
|
||||
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
|
||||
drawmode = GL_TRIANGLES;
|
||||
else if (it.array->m_type == RAS_DisplayArray::QUAD)
|
||||
drawmode = GL_QUADS;
|
||||
else
|
||||
drawmode = GL_LINES;
|
||||
|
||||
// colors
|
||||
if (drawmode != GL_LINES && !wireframe) {
|
||||
if (ms.m_bObjectColor) {
|
||||
const MT_Vector4& rgba = ms.m_RGBAcolor;
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
}
|
||||
else {
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
else
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
|
||||
glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
|
||||
if (!wireframe) {
|
||||
TexCoordPtr(it.vertex);
|
||||
if (glIsEnabled(GL_COLOR_ARRAY))
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
|
||||
}
|
||||
|
||||
// here the actual drawing takes places
|
||||
glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
|
||||
}
|
||||
|
||||
if (!wireframe) {
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
EnableTextures(false);
|
||||
}
|
||||
}
|
||||
|
||||
void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
|
||||
{
|
||||
/* note: this function must closely match EnableTextures to enable/disable
|
||||
* the right arrays, otherwise coordinate and attribute pointers from other
|
||||
* materials can still be used and cause crashes */
|
||||
int unit;
|
||||
|
||||
if (GLEW_ARB_multitexture)
|
||||
{
|
||||
for (unit=0; unit<m_texco_num; unit++)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
|
||||
if (tv->getFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2());
|
||||
continue;
|
||||
}
|
||||
switch (m_texco[unit]) {
|
||||
case RAS_TEXCO_ORCO:
|
||||
case RAS_TEXCO_GLOB:
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
|
||||
break;
|
||||
case RAS_TEXCO_UV1:
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1());
|
||||
break;
|
||||
case RAS_TEXCO_NORM:
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
|
||||
break;
|
||||
case RAS_TEXTANGENT:
|
||||
glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
|
||||
break;
|
||||
case RAS_TEXCO_UV2:
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_program) {
|
||||
for (unit=0; unit<m_attrib_num; unit++) {
|
||||
switch (m_attrib[unit]) {
|
||||
case RAS_TEXCO_ORCO:
|
||||
case RAS_TEXCO_GLOB:
|
||||
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
|
||||
break;
|
||||
case RAS_TEXCO_UV1:
|
||||
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1());
|
||||
break;
|
||||
case RAS_TEXCO_NORM:
|
||||
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
|
||||
break;
|
||||
case RAS_TEXTANGENT:
|
||||
glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
|
||||
break;
|
||||
case RAS_TEXCO_UV2:
|
||||
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2());
|
||||
break;
|
||||
case RAS_TEXCO_VCOL:
|
||||
glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
|
||||
{
|
||||
TexCoGen *texco, *attrib;
|
||||
int unit, texco_num, attrib_num;
|
||||
|
||||
/* we cache last texcoords and attribs to ensure we disable the ones that
|
||||
* were actually last set */
|
||||
if (enable) {
|
||||
texco = m_texco;
|
||||
texco_num = m_texco_num;
|
||||
attrib = m_attrib;
|
||||
attrib_num = m_attrib_num;
|
||||
|
||||
memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num);
|
||||
m_last_texco_num = m_texco_num;
|
||||
memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num);
|
||||
m_last_attrib_num = m_attrib_num;
|
||||
}
|
||||
else {
|
||||
texco = m_last_texco;
|
||||
texco_num = m_last_texco_num;
|
||||
attrib = m_last_attrib;
|
||||
attrib_num = m_last_attrib_num;
|
||||
}
|
||||
|
||||
if (GLEW_ARB_multitexture) {
|
||||
for (unit=0; unit<texco_num; unit++) {
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
|
||||
|
||||
switch (texco[unit]) {
|
||||
case RAS_TEXCO_ORCO:
|
||||
case RAS_TEXCO_GLOB:
|
||||
case RAS_TEXCO_UV1:
|
||||
case RAS_TEXCO_NORM:
|
||||
case RAS_TEXTANGENT:
|
||||
case RAS_TEXCO_UV2:
|
||||
if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
break;
|
||||
default:
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
else {
|
||||
if (texco_num) {
|
||||
if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (GLEW_ARB_vertex_program) {
|
||||
for (unit=0; unit<attrib_num; unit++) {
|
||||
switch (attrib[unit]) {
|
||||
case RAS_TEXCO_ORCO:
|
||||
case RAS_TEXCO_GLOB:
|
||||
case RAS_TEXCO_UV1:
|
||||
case RAS_TEXCO_NORM:
|
||||
case RAS_TEXTANGENT:
|
||||
case RAS_TEXCO_UV2:
|
||||
case RAS_TEXCO_VCOL:
|
||||
if (enable) glEnableVertexAttribArrayARB(unit);
|
||||
else glDisableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
default:
|
||||
glDisableVertexAttribArrayARB(unit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
m_last_texco_num = 0;
|
||||
m_last_attrib_num = 0;
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,7 @@
|
||||
#include "MT_Matrix4x4.h"
|
||||
|
||||
RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
|
||||
const MT_Point2& uv,
|
||||
const MT_Point2& uv2,
|
||||
const MT_Point2 uvs[MAX_UNIT],
|
||||
const MT_Vector4& tangent,
|
||||
const unsigned int rgba,
|
||||
const MT_Vector3& normal,
|
||||
@ -43,8 +42,6 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
|
||||
const unsigned int origindex)
|
||||
{
|
||||
xyz.getValue(m_localxyz);
|
||||
uv.getValue(m_uv1);
|
||||
uv2.getValue(m_uv2);
|
||||
SetRGBA(rgba);
|
||||
SetNormal(normal);
|
||||
tangent.getValue(m_tangent);
|
||||
@ -52,6 +49,11 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
|
||||
m_origindex = origindex;
|
||||
m_unit = 2;
|
||||
m_softBodyIndex = -1;
|
||||
|
||||
for (int i = 0; i < MAX_UNIT; ++i)
|
||||
{
|
||||
uvs[i].getValue(m_uvs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const MT_Point3& RAS_TexVert::xyz()
|
||||
@ -80,26 +82,15 @@ void RAS_TexVert::SetXYZ(const float xyz[3])
|
||||
m_localxyz[0] = xyz[0]; m_localxyz[1] = xyz[1]; m_localxyz[2] = xyz[2];
|
||||
}
|
||||
|
||||
void RAS_TexVert::SetUV1(const MT_Point2& uv)
|
||||
void RAS_TexVert::SetUV(int index, const MT_Point2& uv)
|
||||
{
|
||||
uv.getValue(m_uv1);
|
||||
uv.getValue(m_uvs[index]);
|
||||
}
|
||||
|
||||
void RAS_TexVert::SetUV1(const float uv[3])
|
||||
void RAS_TexVert::SetUV(int index, const float uv[2])
|
||||
{
|
||||
m_uv1[0] = uv[0];
|
||||
m_uv1[1] = uv[1];
|
||||
}
|
||||
|
||||
void RAS_TexVert::SetUV2(const MT_Point2& uv)
|
||||
{
|
||||
uv.getValue(m_uv2);
|
||||
}
|
||||
|
||||
void RAS_TexVert::SetUV2(const float uv[3])
|
||||
{
|
||||
m_uv2[0] = uv[0];
|
||||
m_uv2[1] = uv[1];
|
||||
m_uvs[index][0] = uv[0];
|
||||
m_uvs[index][1] = uv[1];
|
||||
}
|
||||
|
||||
void RAS_TexVert::SetRGBA(const unsigned int rgba)
|
||||
@ -132,14 +123,17 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
|
||||
// compare two vertices, and return TRUE if both are almost identical (they can be shared)
|
||||
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
|
||||
{
|
||||
bool uv_match = true;
|
||||
for (int i=0; i<MAX_UNIT; i++)
|
||||
uv_match = uv_match && MT_fuzzyEqual(MT_Vector2(m_uvs[i]), MT_Vector2(other->m_uvs[i]));
|
||||
|
||||
return (
|
||||
/* m_flag == other->m_flag && */
|
||||
/* at the moment the face only stores the smooth/flat setting so don't bother comparing it */
|
||||
m_rgba == other->m_rgba &&
|
||||
MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) &&
|
||||
MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) &&
|
||||
MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) &&
|
||||
MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* &&
|
||||
uv_match /* &&
|
||||
MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/);
|
||||
/* don't bother comparing m_localxyz since we know there from the same vert */
|
||||
}
|
||||
@ -162,12 +156,7 @@ void RAS_TexVert::Transform(const MT_Matrix4x4& mat, const MT_Matrix4x4& nmat)
|
||||
SetTangent((nmat*MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue());
|
||||
}
|
||||
|
||||
void RAS_TexVert::TransformUV1(const MT_Matrix4x4& mat)
|
||||
void RAS_TexVert::TransformUV(int index, const MT_Matrix4x4& mat)
|
||||
{
|
||||
SetUV1((mat * MT_Vector4(m_uv1[0], m_uv1[1], 0.0, 1.0)).getValue());
|
||||
}
|
||||
|
||||
void RAS_TexVert::TransformUV2(const MT_Matrix4x4& mat)
|
||||
{
|
||||
SetUV2((mat * MT_Vector4(m_uv2[0], m_uv2[1], 0.0, 1.0)).getValue());
|
||||
SetUV(index, (mat * MT_Vector4(m_uvs[index][0], m_uvs[index][1], 0.0, 1.0)).getValue());
|
||||
}
|
||||
|
@ -48,23 +48,21 @@ class RAS_TexVert
|
||||
{
|
||||
|
||||
float m_localxyz[3]; // 3*4 = 12
|
||||
float m_uv1[2]; // 2*4 = 8
|
||||
float m_uv2[2]; // 2*4 = 8
|
||||
float m_uvs[8][2]; // 8*2*4=64 //8 = MAX_UNIT
|
||||
unsigned int m_rgba; // 4
|
||||
float m_tangent[4]; // 4*4 = 16
|
||||
float m_normal[3]; // 3*4 = 12
|
||||
float m_tangent[4]; // 4*4 = 16
|
||||
float m_normal[3]; // 3*4 = 12
|
||||
short m_flag; // 2
|
||||
short m_softBodyIndex; //2
|
||||
unsigned int m_unit; // 4
|
||||
unsigned int m_origindex; // 4
|
||||
//---------
|
||||
// 56+6+8+2=72
|
||||
// 32 bytes total size, fits nice = 56 = not fit nice.
|
||||
// 120
|
||||
// 32 bytes total size, fits nice = 120 = not fit nice.
|
||||
|
||||
public:
|
||||
enum {
|
||||
FLAT = 1,
|
||||
SECOND_UV = 2,
|
||||
MAX_UNIT = 8
|
||||
};
|
||||
|
||||
@ -74,8 +72,7 @@ public:
|
||||
RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0)
|
||||
{}
|
||||
RAS_TexVert(const MT_Point3& xyz,
|
||||
const MT_Point2& uv,
|
||||
const MT_Point2& uv2,
|
||||
const MT_Point2 uvs[MAX_UNIT],
|
||||
const MT_Vector4& tangent,
|
||||
const unsigned int rgba,
|
||||
const MT_Vector3& normal,
|
||||
@ -83,12 +80,8 @@ public:
|
||||
const unsigned int origindex);
|
||||
~RAS_TexVert() {};
|
||||
|
||||
const float* getUV1 () const {
|
||||
return m_uv1;
|
||||
};
|
||||
|
||||
const float* getUV2 () const {
|
||||
return m_uv2;
|
||||
const float* getUV (int unit) const {
|
||||
return m_uvs[unit];
|
||||
};
|
||||
|
||||
const float* getXYZ() const {
|
||||
@ -123,10 +116,8 @@ public:
|
||||
|
||||
void SetXYZ(const MT_Point3& xyz);
|
||||
void SetXYZ(const float xyz[3]);
|
||||
void SetUV1(const MT_Point2& uv);
|
||||
void SetUV2(const MT_Point2& uv);
|
||||
void SetUV1(const float uv[2]);
|
||||
void SetUV2(const float uv[2]);
|
||||
void SetUV(int index, const MT_Point2& uv);
|
||||
void SetUV(int index, const float uv[2]);
|
||||
|
||||
void SetRGBA(const unsigned int rgba);
|
||||
void SetNormal(const MT_Vector3& normal);
|
||||
@ -139,8 +130,7 @@ public:
|
||||
|
||||
void Transform(const class MT_Matrix4x4& mat,
|
||||
const class MT_Matrix4x4& nmat);
|
||||
void TransformUV1(const MT_Matrix4x4& mat);
|
||||
void TransformUV2(const MT_Matrix4x4& mat);
|
||||
void TransformUV(int index, const MT_Matrix4x4& mat);
|
||||
|
||||
// compare two vertices, to test if they can be shared, used for
|
||||
// splitting up based on uv's, colors, etc
|
||||
|
@ -52,9 +52,9 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Ve
|
||||
MT_Scalar d = -p[0].xyz().dot(normal);
|
||||
|
||||
|
||||
MT_Matrix3x3 mat3( p[0].getUV1()[0],p[0].getUV1()[1], 1,
|
||||
p[1].getUV1()[0],p[1].getUV1()[1], 1,
|
||||
p[2].getUV1()[0],p[2].getUV1()[1], 1);
|
||||
MT_Matrix3x3 mat3( p[0].getUV(0)[0],p[0].getUV(0)[1], 1,
|
||||
p[1].getUV(0)[0],p[1].getUV(0)[1], 1,
|
||||
p[2].getUV(0)[0],p[2].getUV(0)[1], 1);
|
||||
|
||||
|
||||
MT_Matrix3x3 mat3inv = mat3.inverse();
|
||||
|
Loading…
Reference in New Issue
Block a user