Initial commit
This commit is contained in:
299
engines/watchmaker/3d/material.cpp
Normal file
299
engines/watchmaker/3d/material.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "watchmaker/3d/material.h"
|
||||
#include "common/util.h"
|
||||
#include "watchmaker/3d/render/opengl_2d.h"
|
||||
#include "watchmaker/render.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
MaterialPtr rAddMaterial(gMaterial &Material, const Common::String &TextName, int NumFaces, unsigned int LoaderFlags) {
|
||||
// TODO: This is duplicated in opengl_3d.cpp
|
||||
warning("TODO: Fix rAddMaterial");
|
||||
#if 0
|
||||
bool AlreadyLoaded = FALSE;
|
||||
int len = strlen(TextName);
|
||||
|
||||
if (((TextName[len - 1 - 0] == 'i') || (TextName[len - 1 - 0] == 'I')) &&
|
||||
((TextName[len - 1 - 1] == 'v') || (TextName[len - 1 - 1] == 'V')) &&
|
||||
((TextName[len - 1 - 2] == 'a') || (TextName[len - 1 - 2] == 'A'))) {
|
||||
if ((Material.Movie = gLoadMovie(TextName)) == NULL)
|
||||
return NULL;
|
||||
if ((Material.Texture = gUserTexture(64,
|
||||
128)) == NULL)
|
||||
// if( (Material->Texture=gUserTexture( Material->Movie->g_psiStreamInfo.rcFrame.right,
|
||||
// Material->Movie->g_psiStreamInfo.rcFrame.bottom)) == NULL )
|
||||
return NULL;
|
||||
Material.Flags |= T3D_MATERIAL_MOVIE;
|
||||
} else {
|
||||
if ((Material.Texture = gLoadTexture(TextName, LoaderFlags)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//f
|
||||
//f Material->FacesList=(WORD *)t3dRealloc(Material->FacesList,sizeof(WORD)*3*NumFaces+1);
|
||||
//f Material->NumAllocatedFaces+=3*NumFaces+1;
|
||||
Material.FacesList.resize(Material.FacesList.size() + NumFaces * 3);
|
||||
Material.NumAllocatedFaces += NumFaces * 3;
|
||||
//f
|
||||
Material.Flags |= T3D_MATERIAL_NOLIGHTMAP;
|
||||
return Material;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void gMaterial::addProperty(int flag) {
|
||||
this->Flags |= flag;
|
||||
}
|
||||
|
||||
void gMaterial::clearFlag(int flag) {
|
||||
this->Flags &= ~flag;
|
||||
}
|
||||
|
||||
bool gMaterial::hasFlag(int flag) {
|
||||
return this->Flags & flag;
|
||||
}
|
||||
|
||||
void gMaterial::addColor(unsigned char r_add, unsigned char g_add, unsigned char b_add) {
|
||||
int rr, gg, bb;
|
||||
|
||||
rr = this->r;
|
||||
gg = this->g;
|
||||
bb = this->b;
|
||||
|
||||
rr += r;
|
||||
gg += g;
|
||||
bb += b;
|
||||
|
||||
rr = MIN(MAX(rr, 0), 255);
|
||||
gg = MIN(MAX(gg, 0), 255);
|
||||
bb = MIN(MAX(bb, 0), 255);
|
||||
|
||||
this->r = (unsigned char)rr;
|
||||
this->g = (unsigned char)gg;
|
||||
this->b = (unsigned char)bb;
|
||||
}
|
||||
|
||||
bool gMaterial::addNumFacesAdditionalMaterial(MaterialPtr am, unsigned int num) {
|
||||
if (!num || !am)
|
||||
return false;
|
||||
|
||||
Common::SharedPtr<gMaterial> cm;
|
||||
int i;
|
||||
for (i = 0; i < this->NumAddictionalMaterial; i++) {
|
||||
cm = this->AddictionalMaterial[i];
|
||||
if (cm->Texture->ID == am->Texture->ID)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == this->NumAddictionalMaterial) {
|
||||
this->AddictionalMaterial.push_back(Common::SharedPtr<gMaterial>(new gMaterial(*am)));
|
||||
cm = this->AddictionalMaterial.back();
|
||||
cm->FacesList.resize(0);
|
||||
this->NumAddictionalMaterial++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gMaterial::addNumFaces(unsigned int num) {
|
||||
// TODO: Remove, as this is not necessary with a Common::Array
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
MaterialPtr rMergeMaterial(MaterialPtr Mat1, MaterialPtr Mat2) {
|
||||
if (!Mat1 || !Mat2)
|
||||
return nullptr;
|
||||
|
||||
for (int i = 0; i < Mat2->NumAddictionalMaterial; i++) {
|
||||
Mat1->addNumFacesAdditionalMaterial(Mat2->AddictionalMaterial[i],
|
||||
/*Mat2->AddictionalMaterial[i]->NumAllocatedFaces*/ Mat2->AddictionalMaterial[i]->NumFaces());
|
||||
}
|
||||
//reset mat2
|
||||
rRemoveMaterial(Mat2);
|
||||
*Mat2 = gMaterial();
|
||||
|
||||
return Mat1;
|
||||
}
|
||||
|
||||
void rRemoveMaterials(Common::Array<Common::SharedPtr<gMaterial>> &m) {
|
||||
for (auto &material : m) {
|
||||
material->clear();
|
||||
}
|
||||
m.clear();
|
||||
}
|
||||
|
||||
Common::SharedPtr<gMaterial> rCopyMaterial(Common::SharedPtr<gMaterial> Mat1, Common::SharedPtr<gMaterial> Mat2) {
|
||||
if (!Mat1 || !Mat2)
|
||||
return nullptr;
|
||||
|
||||
Mat1->clearFaceList();
|
||||
Mat1->AddictionalMaterial.clear();
|
||||
Mat1->clearFaceList();
|
||||
Mat1->VertsList.clear();
|
||||
//t3dFree(Mat1->FlagsList);
|
||||
*Mat1 = gMaterial();
|
||||
|
||||
if (Mat2->NumFaces()) {
|
||||
for (int i = 0; i < Mat2->NumFaces(); i++) {
|
||||
Mat1->addFace(Mat2->getFace(i));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < Mat2->NumFaces(); i++) {
|
||||
if (Mat2->getFace(i) >= Mat2->VertsList.size()) {
|
||||
warning("TODO");
|
||||
}
|
||||
}
|
||||
if (Mat2->NumAllocatedVerts()) {
|
||||
Mat1->VertsList = Mat2->VertsList;
|
||||
}
|
||||
if (Mat2->NumAllocatedMesh) {
|
||||
Mat1->FlagsList = Mat2->FlagsList;
|
||||
}
|
||||
|
||||
Mat1->Texture = Mat2->Texture;
|
||||
Mat1->Movie = Mat2->Movie;
|
||||
Mat1->Flags = Mat2->Flags;
|
||||
Mat1->VBO = Mat2->VBO;
|
||||
Mat1->NumAllocatedMesh = Mat2->NumAllocatedMesh;
|
||||
Mat1->r = Mat2->r;
|
||||
Mat1->g = Mat2->g;
|
||||
Mat1->b = Mat2->b;
|
||||
Mat1->NumAddictionalMaterial = Mat2->NumAddictionalMaterial;
|
||||
|
||||
rCopyMaterialList(Mat1->AddictionalMaterial, Mat2->AddictionalMaterial, Mat2->NumAddictionalMaterial); // TODO: Does this mean that we don't copy any extras?
|
||||
|
||||
return Mat1;
|
||||
}
|
||||
|
||||
void rCopyMaterialList(MaterialTable &dst, MaterialTable &src, uint count) {
|
||||
dst.resize(count);
|
||||
if (count > src.size()) {
|
||||
error("Copying more materials than there are in the src");
|
||||
}
|
||||
for (uint i = 0; i < count; i++) {
|
||||
if (!dst[i]) {
|
||||
dst[i] = Common::SharedPtr<gMaterial>(new gMaterial());
|
||||
}
|
||||
rCopyMaterial(dst[i], src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void gMaterial::clear() {
|
||||
// TODO: This flag clearing doesn't happen in the original, but shouldn't matter as the class is instantiated again when used in Particles.
|
||||
Flags = 0;
|
||||
|
||||
if (Movie) {
|
||||
Movie = nullptr;
|
||||
}
|
||||
FacesList.clear();
|
||||
VertsList.clear();
|
||||
FlagsList.clear();
|
||||
// rDeleteVertexBuffer(m->VB);
|
||||
VBO = 0;
|
||||
|
||||
for (int j = 0; j < NumAddictionalMaterial; j++) {
|
||||
Common::SharedPtr<gMaterial> cm = AddictionalMaterial[j];
|
||||
cm->FacesList.clear();
|
||||
cm->VertsList.clear();
|
||||
cm->FlagsList.clear();
|
||||
// rDeleteVertexBuffer(cm->VB);
|
||||
cm->VBO = 0;
|
||||
}
|
||||
AddictionalMaterial.clear();
|
||||
}
|
||||
|
||||
|
||||
void rRemoveMaterial(Common::SharedPtr<gMaterial> &m) {
|
||||
m->clear();
|
||||
}
|
||||
|
||||
|
||||
/* -----------------29/07/99 15.53-------------------
|
||||
* Aggiunge un materiale alla MaterialList
|
||||
* --------------------------------------------------*/
|
||||
void rAddToMaterialList(gMaterial &mat, signed short int ViewMatrixNum) {
|
||||
gBatchBlock *bb = nullptr;
|
||||
|
||||
if ((mat.Flags & T3D_MATERIAL_MOVIE)) {
|
||||
warning("Movie: %s %d", mat.Movie->_name.c_str(), mat.Texture->ID);
|
||||
mat.Movie->updateMovie();
|
||||
}
|
||||
|
||||
if ((mat.NumFaces() >= 3) && (mat.VBO)) {
|
||||
if (mat.Texture) {
|
||||
// if (mat.Texture->name == "./TMaps/bianco.tga")
|
||||
// return;
|
||||
}
|
||||
bb = rNewBatchBlock(mat.Texture->ID, mat.Flags, 0, 0);
|
||||
bb->ViewMatrixNum = ViewMatrixNum;
|
||||
bb->FacesList = mat.getFacesList();
|
||||
bb->VBO = mat.VBO;
|
||||
for (uint f = 0; f < bb->FacesList.size(); f++) {
|
||||
if (bb->FacesList[f] >= bb->VBO->_buffer.size()) {
|
||||
for (uint o = 0; o < bb->FacesList.size(); o++) {
|
||||
warning("%d", bb->FacesList[o]);
|
||||
}
|
||||
warning("%d > %d (%d)", bb->FacesList[f], bb->VBO->_buffer.size(), bb->NumVerts());
|
||||
}
|
||||
}
|
||||
mat.emptyFacesList(); // We may want to keep the reservation to avoid the extra reallocs here.
|
||||
}
|
||||
|
||||
for (auto &cm : mat.AddictionalMaterial) {
|
||||
if (cm->NumFaces() < 3) continue;
|
||||
if (cm->VBO == NULL) continue;
|
||||
bb = rNewBatchBlock(mat.Texture->ID, mat.Flags, cm->Texture->ID, cm->Flags);
|
||||
bb->ViewMatrixNum = ViewMatrixNum;
|
||||
bb->FacesList = cm->getFacesList();
|
||||
bb->VBO = cm->VBO;
|
||||
cm->emptyFacesList();
|
||||
}
|
||||
}
|
||||
|
||||
void rAddToMaterialList(MaterialPtr mat, signed short int ViewMatrixNum) {
|
||||
if (mat) {
|
||||
rAddToMaterialList(*mat, ViewMatrixNum);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------31/05/99 10.07-------------------
|
||||
* Costruisce la lista dei materiali ordinata
|
||||
* --------------------------------------------------*/
|
||||
void rBuildMaterialList(MaterialTable &MatList, unsigned int NumMat, signed short int ViewMatrixNum) {
|
||||
if (NumMat == 0)
|
||||
return;
|
||||
|
||||
for (auto &mat : MatList) {
|
||||
rAddToMaterialList(mat, ViewMatrixNum);
|
||||
}
|
||||
}
|
||||
|
||||
MaterialTable rCreateMaterialList(int num) {
|
||||
MaterialTable list;
|
||||
// We avoid actually allocating the gMaterial-objects, as we want the size() to
|
||||
// represent the actually loaded elements.
|
||||
list.reserve(num);
|
||||
return list;
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
Reference in New Issue
Block a user