Files
glest-source/source/shared_lib/include/graphics/model.h
2018-05-06 00:01:36 +02:00

406 lines
10 KiB
C++

// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code 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
// ==============================================================
#ifndef _SHARED_GRAPHICS_MODEL_H_
#define _SHARED_GRAPHICS_MODEL_H_
#include <string>
#include <map>
#include "data_types.h"
#include "pixmap.h"
#include "texture_manager.h"
#include "texture.h"
#include "model_header.h"
#include <memory>
#include "common_scoped_ptr.h"
#include "byte_order.h"
#include "leak_dumper.h"
using std::string;
using std::map;
using std::pair;
namespace Shared {
namespace Graphics {
class Model;
class Mesh;
class ShadowVolumeData;
class InterpolationData;
class TextureManager;
// =====================================================
// class Mesh
//
// Part of a 3D model
// =====================================================
class Mesh {
private:
//mesh data
Texture2D *textures[meshTextureCount];
bool texturesOwned[meshTextureCount];
string texturePaths[meshTextureCount];
string name;
//vertex data counts
uint32 frameCount;
uint32 vertexCount;
uint32 indexCount;
uint32 texCoordFrameCount;
//vertex data
Vec3f *vertices;
Vec3f *normals;
Vec2f *texCoords;
Vec3f *tangents;
uint32 *indices;
//material data
Vec3f diffuseColor;
Vec3f specularColor;
float specularPower;
float opacity;
//properties
bool twoSided;
bool customColor;
bool noSelect;
bool glow;
uint32 textureFlags;
InterpolationData *interpolationData;
TextureManager *textureManager;
// Vertex Buffer Object Names
bool hasBuiltVBOs;
uint32 m_nVBOVertices; // Vertex VBO Name
uint32 m_nVBOTexCoords; // Texture Coordinate VBO Name
uint32 m_nVBONormals; // Normal VBO Name
uint32 m_nVBOIndexes; // Indexes VBO Name
public:
//init & end
Mesh();
~Mesh();
void init();
void end();
void copyInto(Mesh *dest, bool ignoreInterpolationData, bool destinationOwnsTextures);
//maps
const Texture2D *getTexture(int i) const {
return textures[i];
}
//counts
uint32 getFrameCount() const {
return frameCount;
}
uint32 getVertexCount() const {
return vertexCount;
}
uint32 getIndexCount() const {
return indexCount;
}
uint32 getTriangleCount() const;
uint32 getVBOVertices() const {
return m_nVBOVertices;
}
uint32 getVBOTexCoords() const {
return m_nVBOTexCoords;
}
uint32 getVBONormals() const {
return m_nVBONormals;
}
uint32 getVBOIndexes() const {
return m_nVBOIndexes;
}
bool hasBuiltVBOEntities() const {
return hasBuiltVBOs;
}
void BuildVBOs();
void ReleaseVBOs();
//data
const Vec3f *getVertices() const {
return vertices;
}
const Vec3f *getNormals() const {
return normals;
}
const Vec2f *getTexCoords() const {
return texCoords;
}
const Vec3f *getTangents() const {
return tangents;
}
const uint32 *getIndices() const {
return indices;
}
void setVertices(Vec3f *data, uint32 count);
void setNormals(Vec3f *data, uint32 count);
void setTexCoords(Vec2f *data, uint32 count);
void setIndices(uint32 *data, uint32 count);
//material
const Vec3f &getDiffuseColor() const {
return diffuseColor;
}
const Vec3f &getSpecularColor() const {
return specularColor;
}
float getSpecularPower() const {
return specularPower;
}
float getOpacity() const {
return opacity;
}
//properties
bool getTwoSided() const {
return twoSided;
}
bool getCustomTexture() const {
return customColor;
}
bool getNoSelect() const {
return noSelect;
}
bool getGlow() const {
return glow;
}
string getName() const {
return name;
}
uint32 getTextureFlags() const {
return textureFlags;
}
//external data
const InterpolationData *getInterpolationData() const {
return interpolationData;
}
//interpolation
void buildInterpolationData();
void cleanupInterpolationData();
void updateInterpolationData(float t, bool cycle);
void updateInterpolationVertices(float t, bool cycle);
Texture2D *loadMeshTexture(int meshIndex, int textureIndex, TextureManager *textureManager, string textureFile,
int textureChannelCount, bool &textureOwned,
bool deletePixMapAfterLoad, std::map<string, vector<pair<string, string> > > *loadedFileList = NULL,
string sourceLoader = "", string modelFile = "");
//load
void loadV2(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager,
bool deletePixMapAfterLoad, std::map<string, vector<pair<string, string> > > *loadedFileList = NULL, string sourceLoader = "", string modelFile = "");
void loadV3(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager,
bool deletePixMapAfterLoad, std::map<string, vector<pair<string, string> > > *loadedFileList = NULL, string sourceLoader = "", string modelFile = "");
void load(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, bool deletePixMapAfterLoad, std::map<string, vector<pair<string, string> > > *loadedFileList = NULL, string sourceLoader = "", string modelFile = "");
void save(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager,
string convertTextureToFormat, std::map<string, int> &textureDeleteList,
bool keepsmallest, string modelFile);
void deletePixels();
void toEndian();
void fromEndian();
private:
string findAlternateTexture(vector<string> conversionList, string textureFile);
void computeTangents();
};
// =====================================================
// class Model
//
// 3D Model, than can be loaded from a g3d file
// =====================================================
class Model {
private:
TextureManager *textureManager;
private:
uint8 fileVersion;
uint32 meshCount;
Mesh *meshes;
float lastTData;
bool lastCycleData;
float lastTVertex;
bool lastCycleVertex;
string fileName;
string sourceLoader;
//static bool masterserverMode;
public:
//constructor & destructor
Model();
virtual ~Model();
virtual void init() = 0;
virtual void end() = 0;
//static void setMasterserverMode(bool value) { masterserverMode=value; }
//data
void updateInterpolationData(float t, bool cycle);
void updateInterpolationVertices(float t, bool cycle);
void buildShadowVolumeData() const;
//get
uint8 getFileVersion() const {
return fileVersion;
}
uint32 getMeshCount() const {
return meshCount;
}
const Mesh *getMesh(int i) const {
return &meshes[i];
}
Mesh *getMeshPtr(int i) const {
return &meshes[i];
}
uint32 getTriangleCount() const;
uint32 getVertexCount() const;
//io
void save(const string &path, string convertTextureToFormat, bool keepsmallest);
void saveG3d(const string &path, string convertTextureToFormat, bool keepsmallest);
void setTextureManager(TextureManager *textureManager) {
this->textureManager = textureManager;
}
void deletePixels();
string getFileName() const {
return fileName;
}
void toEndian();
void fromEndian();
protected:
void load(const string &path, bool deletePixMapAfterLoad = false, std::map<string, vector<pair<string, string> > > *loadedFileList = NULL, string *sourceLoader = NULL);
void loadG3d(const string &path, bool deletePixMapAfterLoad = false, std::map<string, vector<pair<string, string> > > *loadedFileList = NULL, string sourceLoader = "");
private:
void buildInterpolationData() const;
void autoJoinMeshFrames();
};
class PixelBufferWrapper {
public:
PixelBufferWrapper(int pboCount, int bufferSize);
~PixelBufferWrapper();
Pixmap2D *getPixelBufferFor(int x, int y, int w, int h, int colorComponents);
static void begin();
static void end();
static bool getIsPBOEnable() {
return isPBOEnabled;
}
private:
static bool isPBOEnabled;
static int index;
static vector<uint32> pboIds;
int bufferSize;
void cleanup();
void addBuffersToPixelBuf(int pboCount);
};
class BaseColorPickEntity {
public:
BaseColorPickEntity();
virtual ~BaseColorPickEntity() {
recycleUniqueColor();
}
//static const int COLOR_COMPONENTS = 3;
static const int COLOR_COMPONENTS = 4;
static void init(int bufferSize);
static void beginPicking();
static void endPicking();
static vector<int> getPickedList(int x, int y, int w, int h, const vector<BaseColorPickEntity *> &rendererModels);
void setUniquePickingColor() const;
bool isUniquePickingColor(unsigned char *pixel) const;
string getColorDescription() const;
virtual string getUniquePickName() const = 0;
static void resetUniqueColors();
static void setUsingLoopMethod(bool value) {
using_loop_method = value;
}
static void setTrackColorUse(bool value) {
trackColorUse = value;
}
unsigned char * getUniqueColorID() {
return &uniqueColorID[0];
}
bool get_next_assign_color(unsigned char *assign_to);
static int getUsedColorIDListSize() {
return (int) usedColorIDList.size();
}
static void cleanupPBO();
private:
static int bufferSizeRequired;
unsigned char uniqueColorID[COLOR_COMPONENTS];
static unsigned char nextColorID[COLOR_COMPONENTS];
static unsigned int nextColorRGB;
static const unsigned int k, p;
static bool using_loop_method;
static bool trackColorUse;
static map<string, bool> usedColorIDList;
static vector<vector<unsigned char> > nextColorIDReuseList;
static auto_ptr<PixelBufferWrapper> pbo;
//static auto_ptr<Pixmap2D> cachedPixels;
void assign_color();
void assign_color_using_prime(unsigned char *assign_to);
void assign_color_using_loop(unsigned char *assign_to);
void recycleUniqueColor();
};
}
}//end namespace
#endif