Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/CGProgram.h"
#ifdef HPL1_USE_OPENGL
#include "hpl1/engine/impl/SDLTexture.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/String.h"
#include "common/array.h"
#include "common/str.h"
#include "hpl1/debug.h"
#include "math/matrix4.h"
namespace hpl {
static OpenGL::Shader *createShader(const char *vertex, const char *fragment) {
const char *attributes[] = {nullptr};
return OpenGL::Shader::fromFiles(vertex, fragment, attributes);
}
static void setSamplers(OpenGL::Shader *shader) {
shader->use();
shader->setUniform("tex0", 0);
shader->setUniform("tex1", 1);
shader->setUniform("tex2", 2);
shader->setUniform("tex3", 3);
shader->setUniform("tex4", 4);
shader->setUniform("tex5", 5);
shader->setUniform("tex6", 6);
shader->unbind();
}
cCGProgram::cCGProgram(const tString &vertex, const tString &fragment)
: iGpuProgram(vertex + " " + fragment), _shader(createShader(vertex.c_str(), fragment.c_str())) {
setSamplers(_shader);
}
cCGProgram::~cCGProgram() {
delete _shader;
}
//-----------------------------------------------------------------------
bool cCGProgram::reload() {
return false;
}
//-----------------------------------------------------------------------
void cCGProgram::unload() {
}
//-----------------------------------------------------------------------
void cCGProgram::destroy() {
delete _shader;
}
//-----------------------------------------------------------------------
void cCGProgram::Bind() {
Hpl1::logInfo(Hpl1::kDebugShaders, "binding shader %s\n", GetName().c_str());
_shader->use();
}
//-----------------------------------------------------------------------
void cCGProgram::UnBind() {
Hpl1::logInfo(Hpl1::kDebugShaders, "unbinding shader %s\n", GetName().c_str());
_shader->unbind();
}
//-----------------------------------------------------------------------
bool cCGProgram::SetFloat(const tString &asName, float afX) {
_shader->setUniform1f(asName.c_str(), afX);
return true;
}
//-----------------------------------------------------------------------
bool cCGProgram::SetVec2f(const tString &asName, float afX, float afY) {
_shader->setUniform(asName.c_str(), {afX, afY});
return true;
}
//-----------------------------------------------------------------------
bool cCGProgram::SetVec3f(const tString &asName, float afX, float afY, float afZ) {
_shader->setUniform(asName.c_str(), {afX, afY, afZ});
return true;
}
//-----------------------------------------------------------------------
bool cCGProgram::SetVec4f(const tString &asName, float afX, float afY, float afZ, float afW) {
_shader->setUniform(asName.c_str(), {afX, afY, afZ, afW});
return true;
}
//-----------------------------------------------------------------------
bool cCGProgram::SetMatrixf(const tString &asName, const cMatrixf &mMtx) {
Math::Matrix4 mat4;
mat4.setData(mMtx.v);
mat4.transpose();
_shader->setUniform(asName.c_str(), mat4);
return true;
}
//-----------------------------------------------------------------------
bool cCGProgram::SetMatrixf(const tString &asName, eGpuProgramMatrix mType,
eGpuProgramMatrixOp mOp) {
if (mType != eGpuProgramMatrix_ViewProjection)
error("unsupported shader matrix %d", mOp);
Math::Matrix4 modelView, projection;
glGetFloatv(GL_PROJECTION_MATRIX, projection.getData());
glGetFloatv(GL_MODELVIEW_MATRIX, modelView.getData());
_shader->setUniform(asName.c_str(), modelView * projection);
return true;
}
} // namespace hpl
#endif // HPL1_USE_OPENGL

View File

@@ -0,0 +1,77 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_CGPROGRAM_H
#define HPL_CGPROGRAM_H
#include "common/scummsys.h"
#include "hpl1/engine/graphics/GPUProgram.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/opengl.h"
#ifdef HPL1_USE_OPENGL
#include "graphics/opengl/shader.h"
namespace hpl {
class cCGProgram : public iGpuProgram {
public:
cCGProgram(const tString &vertex, const tString &fragment);
~cCGProgram();
bool reload();
void unload();
void destroy();
tString GetProgramName() { return msName; }
void Bind();
void UnBind();
bool SetFloat(const tString &asName, float afX);
bool SetVec2f(const tString &asName, float afX, float afY);
bool SetVec3f(const tString &asName, float afX, float afY, float afZ);
bool SetVec4f(const tString &asName, float afX, float afY, float afZ, float afW);
bool SetMatrixf(const tString &asName, const cMatrixf &mMtx);
bool SetMatrixf(const tString &asName, eGpuProgramMatrix mType,
eGpuProgramMatrixOp mOp);
private:
OpenGL::Shader *_shader;
tString msName;
tString msFile;
tString msEntry;
};
} // namespace hpl
#endif // HPL1_USE_OPENGL
#endif // HPL_CGPROGRAM_H

View File

@@ -0,0 +1,61 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/CharacterBodyNewton.h"
#include "hpl1/engine/physics/CollideShape.h"
#include "hpl1/engine/physics/PhysicsWorld.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cCharacterBodyNewton::cCharacterBodyNewton(const tString &asName, iPhysicsWorld *apWorld, const cVector3f avSize)
: iCharacterBody(asName, apWorld, avSize) {
}
//-----------------------------------------------------------------------
cCharacterBodyNewton::~cCharacterBodyNewton() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,48 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_CHARACTER_BODY_NEWTON_H
#define HPL_CHARACTER_BODY_NEWTON_H
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/physics/CharacterBody.h"
namespace hpl {
class iPhysicsWorld;
class cCharacterBodyNewton : public iCharacterBody {
public:
cCharacterBodyNewton(const tString &asName, iPhysicsWorld *apWorld, const cVector3f avSize);
~cCharacterBodyNewton();
private:
};
} // namespace hpl
#endif // HPL_CHARACTER_BODY_NEWTON_H

View File

@@ -0,0 +1,296 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/CollideShapeNewton.h"
#include "hpl1/engine/physics/PhysicsWorld.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cCollideShapeNewton::cCollideShapeNewton(eCollideShapeType aType, const cVector3f &avSize,
cMatrixf *apOffsetMtx, NewtonWorld *apNewtonWorld,
iPhysicsWorld *apWorld)
: iCollideShape(apWorld) {
mpNewtonCollision = NULL;
mpNewtonWorld = apNewtonWorld;
mvSize = avSize;
mType = aType;
mfVolume = 0;
float *pMtx = NULL;
cMatrixf mtxTranspose;
if (apOffsetMtx) {
m_mtxOffset = *apOffsetMtx;
mtxTranspose = m_mtxOffset.GetTranspose();
pMtx = &(mtxTranspose.m[0][0]);
} else {
m_mtxOffset = cMatrixf::Identity;
}
////////////////////////////////////////////
// Create Newton collision
switch (aType) {
case eCollideShapeType_Null:
mpNewtonCollision = NewtonCreateNull(apNewtonWorld);
break;
case eCollideShapeType_Box:
mpNewtonCollision = NewtonCreateBox(apNewtonWorld,
mvSize.x, mvSize.y, mvSize.z,
0, pMtx);
break;
case eCollideShapeType_Sphere:
mpNewtonCollision = NewtonCreateSphere(apNewtonWorld,
mvSize.x, mvSize.y, mvSize.z,
0, pMtx);
break;
case eCollideShapeType_Cylinder:
mpNewtonCollision = NewtonCreateCylinder(apNewtonWorld,
mvSize.x, mvSize.y,
0, pMtx);
break;
case eCollideShapeType_Capsule:
mpNewtonCollision = NewtonCreateCapsule(apNewtonWorld,
mvSize.x, mvSize.y,
0, pMtx);
break;
default:
break;
}
////////////////////////////////////////////
// Calculate Bounding volume and volume.
if (mType == eCollideShapeType_Box) {
mBoundingVolume.SetSize(mvSize);
mfVolume = mvSize.x * mvSize.y * mvSize.z;
} else if (mType == eCollideShapeType_Sphere) {
mBoundingVolume.SetSize(mvSize * 2);
mfVolume = (4.0f / 3.0f) * kPif * (mvSize.x * mvSize.x * mvSize.x);
} else if (mType == eCollideShapeType_Cylinder ||
mType == eCollideShapeType_Capsule) {
mBoundingVolume.SetSize(cVector3f(mvSize.y, mvSize.x * 2, mvSize.x * 2));
// Not gonna be correct for capsule...
if (mType == eCollideShapeType_Cylinder)
mfVolume = kPif * (mvSize.x * mvSize.x) * mvSize.y;
else {
// Height of the cylinder part.
float fCylHeight = mvSize.y - (mvSize.x * 2);
mfVolume = 0;
// The volume of the cylinder part.
if (fCylHeight > 0)
mfVolume += kPif * (mvSize.x * mvSize.x) * fCylHeight;
// The volume of the sphere part.
mfVolume += (4.0f / 3.0f) * kPif * (mvSize.x * mvSize.x * mvSize.x);
}
}
mBoundingVolume.SetTransform(m_mtxOffset);
}
//-----------------------------------------------------------------------
cCollideShapeNewton::~cCollideShapeNewton() {
// Release Newton Collision
if (mpNewtonCollision)
NewtonReleaseCollision(mpNewtonWorld, mpNewtonCollision);
// Release all subshapes (for compound objects)
for (int i = 0; i < (int)mvSubShapes.size(); i++) {
mpWorld->DestroyShape(mvSubShapes[i]);
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iCollideShape *cCollideShapeNewton::GetSubShape(int alIdx) {
if (mType == eCollideShapeType_Compound)
return mvSubShapes[alIdx];
else
return this;
}
int cCollideShapeNewton::GetSubShapeNum() {
if (mType == eCollideShapeType_Compound)
return (int)mvSubShapes.size();
else
return 1;
}
//-----------------------------------------------------------------------
cVector3f cCollideShapeNewton::GetInertia(float afMass) {
cVector3f vInertia(1, 1, 1);
// Box
if (mType == eCollideShapeType_Box) {
float fInv = 1.0f / 12.0f;
vInertia = cVector3f(
afMass * (mvSize.y * mvSize.y + mvSize.z * mvSize.z) * fInv,
afMass * (mvSize.x * mvSize.x + mvSize.z * mvSize.z) * fInv,
afMass * (mvSize.x * mvSize.x + mvSize.y * mvSize.y) * fInv);
}
// Sphere
else if (mType == eCollideShapeType_Sphere) {
float fI = 0.4f * afMass * mvSize.x * mvSize.x;
vInertia = cVector3f(fI, fI, fI);
}
// Cylinder
else if (mType == eCollideShapeType_Cylinder) {
float fRadius = mvSize.x;
vInertia.x = afMass * (fRadius * fRadius) * (1.0f / 4.0f) + afMass * (mvSize.y * mvSize.y) * (1.0f / 12.0f);
vInertia.y = vInertia.x;
vInertia.z = afMass * (fRadius * fRadius) * (1.0f / 2.0f);
}
// Capsule
else if (mType == eCollideShapeType_Capsule) {
float fRadius = mvSize.x;
vInertia.x = afMass * (fRadius * fRadius) * (1.0f / 4.0f) + afMass * (mvSize.y * mvSize.y) * (1.0f / 12.0f);
vInertia.y = vInertia.x;
vInertia.z = afMass * (fRadius * fRadius) * (1.0f / 2.0f);
}
// Compound
// This is only a very bad approximation.
else if (mType == eCollideShapeType_Compound) {
cVector3f vBoxSize = mBoundingVolume.GetSize();
float fBoxVolume = vBoxSize.x * vBoxSize.y * vBoxSize.z;
float fInv = 1.0f / 12.0f;
vInertia = cVector3f(
afMass * (vBoxSize.y * vBoxSize.y + vBoxSize.z * vBoxSize.z) * fInv,
afMass * (vBoxSize.x * vBoxSize.x + vBoxSize.z * vBoxSize.z) * fInv,
afMass * (vBoxSize.x * vBoxSize.x + vBoxSize.y * vBoxSize.y) * fInv);
// Scale of a bit of the inertia since the compound is not a 100% solid box
vInertia = vInertia * (1.0f - ((fBoxVolume / mfVolume) * 0.3f));
}
return vInertia;
}
//-----------------------------------------------------------------------
void cCollideShapeNewton::CreateFromShapeVec(tCollideShapeVec &avShapes) {
Common::Array<NewtonCollision *> vNewtonColliders;
vNewtonColliders.reserve(avShapes.size());
mvSubShapes.reserve(avShapes.size());
mfVolume = 0;
for (size_t i = 0; i < avShapes.size(); i++) {
mvSubShapes.push_back(avShapes[i]);
cCollideShapeNewton *pNewtonShape = static_cast<cCollideShapeNewton *>(avShapes[i]);
vNewtonColliders.push_back(pNewtonShape->GetNewtonCollision());
mfVolume += pNewtonShape->GetVolume();
}
mpNewtonCollision = NewtonCreateCompoundCollision(mpNewtonWorld, (int)vNewtonColliders.size(),
&vNewtonColliders[0], 0);
// Create bounding volume
cVector3f vFinalMax = avShapes[0]->GetBoundingVolume().GetMax();
cVector3f vFinalMin = avShapes[0]->GetBoundingVolume().GetMin();
for (size_t i = 1; i < avShapes.size(); i++) {
cVector3f vMax = avShapes[i]->GetBoundingVolume().GetMax();
cVector3f vMin = avShapes[i]->GetBoundingVolume().GetMin();
if (vFinalMax.x < vMax.x)
vFinalMax.x = vMax.x;
if (vFinalMin.x > vMin.x)
vFinalMin.x = vMin.x;
if (vFinalMax.y < vMax.y)
vFinalMax.y = vMax.y;
if (vFinalMin.y > vMin.y)
vFinalMin.y = vMin.y;
if (vFinalMax.z < vMax.z)
vFinalMax.z = vMax.z;
if (vFinalMin.z > vMin.z)
vFinalMin.z = vMin.z;
}
mBoundingVolume.SetLocalMinMax(vFinalMin, vFinalMax);
}
//-----------------------------------------------------------------------
void cCollideShapeNewton::CreateFromVertices(const unsigned int *apIndexArray, int alIndexNum,
const float *apVertexArray, int alVtxStride, int alVtxNum) {
float vTriVec[9];
mpNewtonCollision = NewtonCreateTreeCollision(mpNewtonWorld, 0);
// Log("-- Creating mesh collision.:\n");
NewtonTreeCollisionBeginBuild(mpNewtonCollision);
for (int tri = 0; tri < alIndexNum; tri += 3) {
// Log("tri: %d:\n", tri/3);
for (int idx = 0; idx < 3; idx++) {
int lVtx = apIndexArray[tri + 2 - idx] * alVtxStride;
vTriVec[idx * 3 + 0] = apVertexArray[lVtx + 0];
vTriVec[idx * 3 + 1] = apVertexArray[lVtx + 1];
vTriVec[idx * 3 + 2] = apVertexArray[lVtx + 2];
}
NewtonTreeCollisionAddFace(mpNewtonCollision, 3, vTriVec, sizeof(float) * 3, 1);
}
NewtonTreeCollisionEndBuild(mpNewtonCollision, false);
// Set bounding box size
mBoundingVolume.AddArrayPoints(apVertexArray, alVtxNum);
mBoundingVolume.CreateFromPoints(alVtxStride);
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,71 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_COLLIDE_SHAPE_NEWTON_H
#define HPL_COLLIDE_SHAPE_NEWTON_H
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/physics/CollideShape.h"
#include "hpl1/engine/math/MathTypes.h"
namespace hpl {
class iVertexBuffer;
class iCollideShape;
typedef Common::Array<iCollideShape *> tCollideShapeVec;
typedef tCollideShapeVec::iterator tCollideShapeVecIt;
class cCollideShapeNewton : public iCollideShape {
public:
cCollideShapeNewton(eCollideShapeType aType, const cVector3f &avSize,
cMatrixf *apOffsetMtx, NewtonWorld *apNewtonWorld,
iPhysicsWorld *apWorld);
~cCollideShapeNewton();
iCollideShape *GetSubShape(int alIdx);
int GetSubShapeNum();
cVector3f GetInertia(float afMass);
void CreateFromShapeVec(tCollideShapeVec &avShapes);
void CreateFromVertices(const unsigned int *apIndexArray, int alIndexNum,
const float *apVertexArray, int alVtxStride, int alVtxNum);
NewtonCollision *GetNewtonCollision() { return mpNewtonCollision; }
private:
NewtonCollision *mpNewtonCollision;
NewtonWorld *mpNewtonWorld;
tCollideShapeVec mvSubShapes;
};
} // namespace hpl
#endif // HPL_COLLIDE_SHAPE_NEWTON_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,317 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_LOWLEVELGRAPHICS_SDL_H
#define HPL_LOWLEVELGRAPHICS_SDL_H
#include "common/ptr.h"
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/opengl.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
//-------------------------------------------------
GLenum ColorFormatToGL(eColorDataFormat format);
GLenum TextureTargetToGL(eTextureTarget target);
//-------------------------------------------------
class cLowLevelGraphicsSDL : public iLowLevelGraphics {
public:
cLowLevelGraphicsSDL();
~cLowLevelGraphicsSDL();
bool Init(int alWidth, int alHeight, int alBpp, int abFullscreen, int alMultisampling,
const tString &asWindowCaption);
int GetCaps(eGraphicCaps aType) const;
void ShowCursor(bool abX);
void SetMultisamplingActive(bool abX);
void SetGammaCorrection(float afX);
float GetGammaCorrection();
int GetMultisampling() { return mlMultisampling; }
void SetClipPlane(int alIdx, const cPlanef &aPlane);
cPlanef GetClipPlane(int alIdx, const cPlanef &aPlane);
void SetClipPlaneActive(int alIdx, bool abX);
cVector2f GetScreenSize();
cVector2f GetVirtualSize();
void SetVirtualSize(cVector2f avSize);
Bitmap2D *CreateBitmap2D(const cVector2l &avSize);
FontData *CreateFontData(const tString &asName);
iTexture *CreateTexture(bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
iTexture *CreateTexture(const tString &asName, bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
iTexture *CreateTexture(Bitmap2D *apBmp, bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
iTexture *CreateTexture(const cVector2l &avSize, int alBpp, cColor aFillCol,
bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
Graphics::PixelFormat *GetPixelFormat();
iGpuProgram *CreateGpuProgram(const tString &vertex, const tString &fragment);
void SaveScreenToBMP(const tString &asFile);
/////////// MATRIX METHODS /////////////////////////
void PushMatrix(eMatrix aMtxType);
void PopMatrix(eMatrix aMtxType);
void SetIdentityMatrix(eMatrix aMtxType);
void SetMatrix(eMatrix aMtxType, const cMatrixf &a_mtxA);
void TranslateMatrix(eMatrix aMtxType, const cVector3f &avPos);
void RotateMatrix(eMatrix aMtxType, const cVector3f &avRot);
void ScaleMatrix(eMatrix aMtxType, const cVector3f &avScale);
void SetOrthoProjection(const cVector2f &avSize, float afMin, float afMax);
/////////// DRAWING METHODS /////////////////////////
// OCCLUSION
iOcclusionQuery *CreateOcclusionQuery();
void DestroyOcclusionQuery(iOcclusionQuery *apQuery);
// CLEARING THE FRAMEBUFFER
void ClearScreen();
void SetClearColor(const cColor &aCol);
void SetClearDepth(float afDepth);
void SetClearStencil(int alVal);
void SetClearColorActive(bool abX);
void SetClearDepthActive(bool abX);
void SetClearStencilActive(bool abX);
void SetColorWriteActive(bool abR, bool abG, bool abB, bool abA);
void SetDepthWriteActive(bool abX);
void SetCullActive(bool abX);
void SetCullMode(eCullMode aMode);
// DEPTH
void SetDepthTestActive(bool abX);
void SetDepthTestFunc(eDepthTestFunc aFunc);
// ALPHA
void SetAlphaTestActive(bool abX);
void SetAlphaTestFunc(eAlphaTestFunc aFunc, float afRef);
// STENCIL
void SetStencilActive(bool abX);
/*void SetStencilTwoSideActive(bool abX);
void SetStencilFace(eStencilFace aFace);
void SetStencilFunc(eStencilFunc aFunc,int alRef, unsigned int aMask);
void SetStencilOp(eStencilOp aFailOp,eStencilOp aZFailOp,eStencilOp aZPassOp);*/
void SetStencil(eStencilFunc aFunc, int alRef, unsigned int aMask,
eStencilOp aFailOp, eStencilOp aZFailOp, eStencilOp aZPassOp);
void SetStencilTwoSide(eStencilFunc aFrontFunc, eStencilFunc aBackFunc,
int alRef, unsigned int aMask,
eStencilOp aFrontFailOp, eStencilOp aFrontZFailOp, eStencilOp aFrontZPassOp,
eStencilOp aBackFailOp, eStencilOp aBackZFailOp, eStencilOp aBackZPassOp);
void SetStencilTwoSide(bool abX);
// SCISSOR
void SetScissorActive(bool abX);
void SetScissorRect(const cRect2l &aRect);
// BLENDING
void SetBlendActive(bool abX);
void SetBlendFunc(eBlendFunc aSrcFactor, eBlendFunc aDestFactor);
void SetBlendFuncSeparate(eBlendFunc aSrcFactorColor, eBlendFunc aDestFactorColor,
eBlendFunc aSrcFactorAlpha, eBlendFunc aDestFactorAlpha);
// TEXTURE
void SetTexture(unsigned int alUnit, iTexture *apTex);
void SetActiveTextureUnit(unsigned int alUnit);
void SetTextureEnv(eTextureParam aParam, int alVal);
void SetTextureConstantColor(const cColor &color);
void SetColor(const cColor &aColor);
// POLYGONS
iVertexBuffer *CreateVertexBuffer(tVertexFlag aFlags, eVertexBufferDrawType aDrawType,
eVertexBufferUsageType aUsageType,
int alReserveVtxSize = 0, int alReserveIdxSize = 0);
void DrawRect(const cVector2f &avPos, const cVector2f &avSize, float afZ);
void DrawTri(const tVertexVec &avVtx);
void DrawTri(const cVertex *avVtx);
void DrawQuad(const tVertexVec &avVtx);
void DrawQuad(const tVertexVec &avVtx, const cColor aCol);
void DrawQuad(const tVertexVec &avVtx, const float afZ);
void DrawQuad(const tVertexVec &avVtx, const float afZ, const cColor &aCol);
void DrawQuadMultiTex(const tVertexVec &avVtx, const tVector3fVec &avExtraUvs);
void AddVertexToBatch(const cVertex &apVtx);
void AddVertexToBatch(const cVertex *apVtx, const cVector3f *avTransform);
void AddVertexToBatch(const cVertex *apVtx, const cMatrixf *aMtx);
void AddVertexToBatch_Size2D(const cVertex *apVtx, const cVector3f *avTransform,
const cColor *apCol, const float &mfW, const float &mfH);
void AddVertexToBatch_Raw(const cVector3f &avPos, const cColor &aColor,
const cVector3f &avTex);
void AddTexCoordToBatch(unsigned int alUnit, const cVector3f *apCoord);
void SetBatchTextureUnitActive(unsigned int alUnit, bool abActive);
void AddIndexToBatch(int alIndex);
void FlushTriBatch(tVtxBatchFlag aTypeFlags, bool abAutoClear = true);
void FlushQuadBatch(tVtxBatchFlag aTypeFlags, bool abAutoClear = true);
void ClearBatch();
// PRIMITIVES
void DrawLine(const cVector3f &avBegin, const cVector3f &avEnd, cColor aCol);
void DrawBoxMaxMin(const cVector3f &avMax, const cVector3f &avMin, cColor aCol);
void DrawSphere(const cVector3f &avPos, float afRadius, cColor aCol);
void DrawLine2D(const cVector2f &avBegin, const cVector2f &avEnd, float afZ, cColor aCol);
void DrawLineRect2D(const cRect2f &aRect, float afZ, cColor aCol);
void DrawLineCircle2D(const cVector2f &avCenter, float afRadius, float afZ, cColor aCol);
void DrawFilledRect2D(const cRect2f &aRect, float afZ, cColor aCol);
// FRAMEBUFFER
void CopyContextToTexure(iTexture *apTex, const cVector2l &avPos,
const cVector2l &avSize, const cVector2l &avTexOffset = 0);
void SetRenderTarget(iTexture *pTex);
bool RenderTargetHasZBuffer();
void FlushRenderTarget();
void FlushRendering();
void SwapBuffers();
///// SDL Specific ////////////////////////////
void SetupGL();
GLenum GetGLTextureTargetEnum(eTextureTarget aType);
private:
cVector2l mvScreenSize;
cVector2f mvVirtualSize;
int mlMultisampling;
int mlBpp;
// Gamma
// uint16 mvStartGammaArray[3][256];
float mfGammaCorrection;
// Clipping
cPlanef mvClipPlanes[kMaxClipPlanes];
// SDL Variables
// SDL_Surface *mpScreen;
Graphics::PixelFormat mpPixelFormat;
// Vertex Array variables
// The vertex arrays used:
float *mpVertexArray;
unsigned int mlVertexCount;
unsigned int *mpIndexArray;
unsigned int mlIndexCount;
unsigned int mlBatchStride;
float *mpTexCoordArray[MAX_TEXTUREUNITS];
bool mbTexCoordArrayActive[MAX_TEXTUREUNITS];
unsigned int mlTexCoordArrayCount[MAX_TEXTUREUNITS];
unsigned int mlBatchArraySize;
// Clearing
bool mbClearColor;
bool mbClearDepth;
bool mbClearStencil;
// Rendertarget variables
iTexture *mpRenderTarget;
// Texture
iTexture *mpCurrentTexture[MAX_TEXTUREUNITS];
iTexture *_screenBuffer;
iGpuProgram *_gammaCorrectionProgram;
// CG Compiler Variables
// CGcontext mCG_Context;
// Multisample
void CheckMultisampleCaps();
void applyGammaCorrection();
// Batch helper
void SetUpBatchArrays();
// Depth helper
GLenum GetGLDepthTestFuncEnum(eDepthTestFunc aType);
// Alpha Helper
GLenum GetGLAlphaTestFuncEnum(eAlphaTestFunc aType);
// Stencil helper
GLenum GetGLStencilFuncEnum(eStencilFunc aType);
GLenum GetGLStencilOpEnum(eStencilOp aType);
// Matrix Helper
void SetMatrixMode(eMatrix mType);
// Texture helper
GLenum GetGLTextureParamEnum(eTextureParam aType);
GLenum GetGLTextureOpEnum(eTextureOp aType);
GLenum GetGLTextureFuncEnum(eTextureFunc aType);
GLenum GetGLTextureSourceEnum(eTextureSource aType);
// Blend helper
GLenum GetGLBlendEnum(eBlendFunc aType);
// Vtx helper
void SetVtxBatchStates(tVtxBatchFlag flags);
};
} // namespace hpl
#endif // HPL1_USE_OPENGL
#endif // HPL_LOWLEVELGRAPHICS_SDL_H

View File

@@ -0,0 +1,66 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/LowLevelPhysicsNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cLowLevelPhysicsNewton::cLowLevelPhysicsNewton() {
NewtonInitGlobals();
}
//-----------------------------------------------------------------------
cLowLevelPhysicsNewton::~cLowLevelPhysicsNewton() {
NewtonDestroyGlobals();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHOD
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iPhysicsWorld *cLowLevelPhysicsNewton::CreateWorld() {
cPhysicsWorldNewton *pWorld = hplNew(cPhysicsWorldNewton, ());
return pWorld;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,46 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_LOWLEVELPHYSICS_NEWTON_H
#define HPL_LOWLEVELPHYSICS_NEWTON_H
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/physics/LowLevelPhysics.h"
namespace hpl {
class cLowLevelPhysicsNewton : public iLowLevelPhysics {
public:
cLowLevelPhysicsNewton();
~cLowLevelPhysicsNewton();
iPhysicsWorld *CreateWorld();
};
} // namespace hpl
#endif // HPL_LOWLEVELPHYSICS_NEWTON_H

View File

@@ -0,0 +1,226 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/LowLevelSoundOpenAL.h"
#include "hpl1/engine/impl/OpenALSoundChannel.h"
#include "hpl1/engine/impl/OpenALSoundData.h"
#include "hpl1/engine/impl/OpenALSoundEnvironment.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
#include "audio/mixer.h"
#include "common/system.h"
#include "hpl1/debug.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cLowLevelSoundOpenAL::cLowLevelSoundOpenAL() : _activeChannels(MAX_ACTIVE_CHANNELS, nullptr) {
mvFormats[0] = "OGG";
mvFormats[1] = "WAV";
mvFormats[2] = "";
mbInitialized = false;
mbEnvAudioEnabled = false;
mbNullEffectAttached = false;
_mixer = g_system->getMixer();
}
//-----------------------------------------------------------------------
cLowLevelSoundOpenAL::~cLowLevelSoundOpenAL() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHOD
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iSoundData *cLowLevelSoundOpenAL::LoadSoundData(const tString &asName, const tString &asFilePath,
const tString &asType, bool abStream, bool abLoopStream) {
cOpenALSoundData *pSoundData = hplNew(cOpenALSoundData, (asName, abStream, this));
pSoundData->SetLoopStream(abLoopStream);
if (pSoundData->CreateFromFile(asFilePath) == false) {
hplDelete(pSoundData);
return NULL;
}
return pSoundData;
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::GetSupportedFormats(tStringList &alstFormats) {
int lPos = 0;
while (mvFormats[lPos] != "") {
alstFormats.push_back(mvFormats[lPos]);
lPos++;
}
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::UpdateSound(float afTimeStep) {
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::SetListenerAttributes(const cVector3f &avPos, const cVector3f &avVel,
const cVector3f &avForward, const cVector3f &avUp) {
mvListenerPosition = avPos;
mvListenerVelocity = avVel;
mvListenerForward = avForward;
mvListenerUp = avUp;
mvListenerRight = cMath::Vector3Cross(mvListenerForward, mvListenerUp);
// m_mtxListener = cMatrixf(
// -mvListenerRight.x, -mvListenerRight.y,-mvListenerRight.z, avPos.x,
// -mvListenerUp.x, -mvListenerUp.y,-mvListenerUp.z, avPos.y,
// -mvListenerForward.x, -mvListenerForward.y,-mvListenerForward.z, avPos.z,
// 0, 0,0, 1
// );
m_mtxListener = cMatrixf::Identity;
m_mtxListener.SetRight(mvListenerRight);
m_mtxListener.SetUp(mvListenerUp);
m_mtxListener.SetForward(mvListenerForward * -1);
m_mtxListener = cMath::MatrixInverse(m_mtxListener);
m_mtxListener.SetTranslation(mvListenerPosition);
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::SetListenerPosition(const cVector3f &avPos) {
mvListenerPosition = avPos;
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::SetListenerAttenuation(bool abEnabled) {
mbListenerAttenuation = abEnabled;
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::SetSetRolloffFactor(float afFactor) {
HPL1_UNIMPLEMENTED(cLowLevelSoundOpenAL::SetSetRolloffFactor);
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::SetVolume(float volume) {
g_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, static_cast<byte>(volume * 255.f));
mfVolume = volume;
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::Init(bool abUseHardware, bool abForceGeneric, bool abUseEnvAudio, int alMaxChannels,
int alStreamUpdateFreq, bool abUseThreading, bool abUseVoiceManagement,
int alMaxMonoSourceHint, int alMaxStereoSourceHint,
int alStreamingBufferSize, int alStreamingBufferCount, bool abEnableLowLevelLog, tString asDeviceName) {
// Default listener settings.
mvListenerForward = cVector3f(0, 0, 1);
mvListenerUp = cVector3f(0, 1, 0);
SetVolume(1.0f);
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::SetEnvVolume(float afEnvVolume) {
HPL1_UNIMPLEMENTED(cLowLevelSoundOpenAL::SetEnvVolume);
}
//-----------------------------------------------------------------------
iSoundEnvironment *cLowLevelSoundOpenAL::LoadSoundEnvironment(const tString &asFilePath) {
HPL1_UNIMPLEMENTED(cLowLevelSoundOpenAL::LoadSoundEnvironment);
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::SetSoundEnvironment(iSoundEnvironment *apSoundEnv) {
HPL1_UNIMPLEMENTED(cLowLevelSoundOpenAL::SetSoundEnvironment);
}
//-----------------------------------------------------------------------
void cLowLevelSoundOpenAL::FadeSoundEnvironment(iSoundEnvironment *apSourceSoundEnv, iSoundEnvironment *apDestSoundEnv, float afT) {
HPL1_UNIMPLEMENTED(cLowLevelSoundOpenAL::FadeSoundEnvironment);
}
static cOpenALSoundChannel **findBestSlot(Common::Array<cOpenALSoundChannel *> &slots, int priority) {
cOpenALSoundChannel **best = slots.end();
for (auto it = slots.begin(); it != slots.end(); ++it) {
if (*it == nullptr || !(*it)->IsPlaying())
return it;
if ((*it)->GetPriority() < priority)
best = it;
}
return best;
}
bool cLowLevelSoundOpenAL::playChannel(cOpenALSoundChannel *channel) {
auto slot = findBestSlot(_activeChannels, channel->GetPriority());
if (slot != _activeChannels.end()) {
if (*slot != nullptr) {
if ((*slot)->IsPlaying()) {
Hpl1::logInfo(Hpl1::kDebugAudio, "evicting sound from data %s from mixer slot\n",
(*slot)->mpData->GetName().c_str());
}
(*slot)->Stop();
}
*slot = channel;
_mixer->stopHandle(channel->_handle);
channel->_audioStream->rewind();
_mixer->playStream(Audio::Mixer::SoundType::kPlainSoundType, &channel->_handle, channel->_audioStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
return true;
}
return false;
}
void cLowLevelSoundOpenAL::closeChannel(cOpenALSoundChannel *channel) {
auto slot = Common::find(_activeChannels.begin(), _activeChannels.end(), channel);
if (slot != _activeChannels.end()) {
(*slot)->Stop();
*slot = nullptr;
}
}
} // namespace hpl

View File

@@ -0,0 +1,91 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_LOWLEVELSOUND_OPENAL_H
#define HPL_LOWLEVELSOUND_OPENAL_H
#include "common/array.h"
#include "hpl1/engine/sound/LowLevelSound.h"
namespace Audio {
class Mixer;
}
namespace hpl {
class cOpenALSoundChannel;
class cLowLevelSoundOpenAL : public iLowLevelSound {
public:
cLowLevelSoundOpenAL();
~cLowLevelSoundOpenAL();
void GetSupportedFormats(tStringList &alstFormats);
iSoundData *LoadSoundData(const tString &asName, const tString &asFilePath,
const tString &asType, bool abStream, bool abLoopStream);
void UpdateSound(float afTimeStep);
void SetListenerAttributes(const cVector3f &avPos, const cVector3f &avVel,
const cVector3f &avForward, const cVector3f &avUp);
void SetListenerPosition(const cVector3f &avPos);
void SetSetRolloffFactor(float afFactor);
void SetListenerAttenuation(bool abEnabled);
void Init(bool abUseHardware, bool abForceGeneric, bool abUseEnvAudio, int alMaxChannels,
int alStreamUpdateFreq, bool abUseThreading, bool abUseVoiceManagement,
int alMaxMonoSourceHint, int alMaxStereoSourceHint,
int alStreamingBufferSize, int alStreamingBufferCount, bool abEnableLowLevelLog,
tString asDeviceName);
void SetVolume(float afVolume);
void SetEnvVolume(float afEnvVolume);
iSoundEnvironment *LoadSoundEnvironment(const tString &asFilePath);
void SetSoundEnvironment(iSoundEnvironment *apSoundEnv);
void FadeSoundEnvironment(iSoundEnvironment *apSourceSoundEnv, iSoundEnvironment *apDestSoundEnv, float afT);
bool playChannel(cOpenALSoundChannel *channel);
void closeChannel(cOpenALSoundChannel *channel);
private:
static const int MAX_ACTIVE_CHANNELS = 32;
Common::Array<cOpenALSoundChannel *> _activeChannels;
Audio::Mixer *_mixer;
tString mvFormats[30];
bool mbInitialized;
bool mbNullEffectAttached;
};
} // namespace hpl
#endif // HPL_LOWLEVELSOUND_OPENAL_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,558 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_MESH_LOADER_COLLADA_H
#define HPL_MESH_LOADER_COLLADA_H
#include "common/list.h"
#include "hpl1/engine/graphics/VertexBuffer.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/physics/PhysicsJoint.h"
#include "hpl1/engine/resources/MeshLoader.h"
#include "hpl1/engine/system/MemoryManager.h"
class TiXmlElement;
namespace hpl {
class cMesh;
class cNode3D;
class iVertexBuffer;
class cBone;
class cAnimation;
class cAnimationTrack;
class cSkeleton;
class cWorld3D;
class cSector;
class cMeshEntity;
class iPhysicsBody;
class cColliderEntity;
class cMeshJoint;
class cSystem;
//////////////////////////////////////////////
// HELP CLASSES
class cColladaImage {
public:
tString msId;
tString msName;
tString msSource;
};
typedef Common::Array<cColladaImage> tColladaImageVec;
//------------------------------------------------
class cColladaTexture {
public:
tString msId;
tString msName;
tString msImage;
};
typedef Common::Array<cColladaTexture> tColladaTextureVec;
//------------------------------------------------
class cColladaMaterial {
public:
tString msId;
tString msName;
tString msTexture;
cColor mDiffuseColor;
};
typedef Common::Array<cColladaMaterial> tColladaMaterialVec;
//------------------------------------------------
class cColladaLight {
public:
tString msId;
tString msName;
tString msType;
cColor mDiffuseColor;
float mfAngle;
};
typedef Common::Array<cColladaLight> tColladaLightVec;
//------------------------------------------------
class cColladaVtxArray {
public:
cColladaVtxArray() : mbIsInVertex(false) {}
tString msId;
tString msType;
bool mbIsInVertex;
tVector3fVec mvArray;
};
typedef Common::Array<cColladaVtxArray> tColladaVtxArrayVec;
class cColladaVtxIndex {
public:
int mlVtx;
int mlNorm;
int mlTex;
};
typedef Common::Array<cColladaVtxIndex> tColladaVtxIndexVec;
//------------------------------------------------
class cColladaExtraVtx {
public:
cColladaExtraVtx(int alVtx, int alNorm, int alTex, int alNewVtx) {
mlVtx = alVtx;
mlNorm = alNorm;
mlTex = alTex;
mlNewVtx = alNewVtx;
}
cColladaExtraVtx() {}
int mlVtx;
int mlNorm;
int mlTex;
int mlNewVtx;
bool Equals(const cColladaVtxIndex &aData) {
if (mlVtx == aData.mlVtx && mlNorm == aData.mlNorm && mlTex == aData.mlTex) {
return true;
}
return false;
}
};
typedef Common::List<cColladaExtraVtx> tColladaExtraVtxList;
typedef tColladaExtraVtxList::iterator tColladaExtraVtxListIt;
typedef Common::Array<tColladaExtraVtxList> tColladaExtraVtxListVec;
//------------------------------------------------
class cColladaGeometry {
public:
cColladaGeometry() : mlPosArrayIdx(-1), mlNormArrayIdx(-1), mlTexArrayIdx(-1),
mlPosIdxNum(-1), mlNormIdxNum(-1), mlTexIdxNum(-1) {}
void Clear() {
mvIndices.clear();
for (int i = 0; i < (int)mvArrayVec.size(); i++) {
mvArrayVec[i].mvArray.clear();
}
/*mvVertexVec.clear();
mvIndexVec.clear();
mvExtraVtxVec.clear();*/
}
tString msId;
tString msName;
tVertexVec mvVertexVec;
tUIntVec mvIndexVec;
tColladaExtraVtxListVec mvExtraVtxVec;
tFloatVec mvTangents;
tString msMaterial;
// THe following are ONLY used when loading from a geometry element.!!
tColladaVtxArrayVec mvArrayVec;
tColladaVtxIndexVec mvIndices;
int mlPosIdxNum; // The position in the triangle element
int mlNormIdxNum; // for eternal use only
int mlTexIdxNum;
int mlPosArrayIdx; // The index for array containing positions
int mlNormArrayIdx; // The index for array containing normals
int mlTexArrayIdx; // The index for array containing texcoords
};
typedef Common::Array<cColladaGeometry> tColladaGeometryVec;
//------------------------------------------------
class cColladaJointPair {
public:
cColladaJointPair() {}
cColladaJointPair(int alJoint, int alWeight) {
mlJoint = alJoint;
mlWeight = alWeight;
}
int mlJoint;
int mlWeight;
};
typedef Common::List<cColladaJointPair> tColladaJointPairList;
typedef tColladaJointPairList::iterator tColladaJointPairListIt;
typedef Common::Array<tColladaJointPairList> tColladaJointPairListVec;
class cColladaController {
public:
cColladaController() : mlJointPairIdx(-1), mlWeightPairIdx(-1) {}
tString msTarget;
tString msId;
cMatrixf m_mtxBindShapeMatrix;
int mlJointPairIdx;
int mlWeightPairIdx;
tStringVec mvJoints;
tFloatVec mvWeights;
tMatrixfVec mvMatrices;
tColladaJointPairListVec mvPairs;
};
typedef Common::Array<cColladaController> tColladaControllerVec;
//------------------------------------------------
class cColladaChannel {
public:
tString msId;
tString msTarget;
tString msSource;
};
typedef Common::Array<cColladaChannel> tColladaChannelVec;
class cColladaSampler {
public:
tString msId;
tString msTimeArray;
tString msValueArray;
tString msTarget;
};
typedef Common::Array<cColladaSampler> tColladaSamplerVec;
class cColladaAnimSource {
public:
tString msId;
tFloatVec mvValues;
};
typedef Common::Array<cColladaAnimSource> tColladaAnimSourceVec;
class cColladaAnimation {
public:
tString msId;
// tString msName;
tString msTargetNode;
tColladaChannelVec mvChannels;
tColladaSamplerVec mvSamplers;
tColladaAnimSourceVec mvSources;
tFloatVec *GetSourceVec(const tString &asId) {
for (size_t i = 0; i < mvSources.size(); i++) {
if (mvSources[i].msId == asId) {
return &mvSources[i].mvValues;
}
}
return NULL;
}
};
typedef Common::Array<cColladaAnimation> tColladaAnimationVec;
//------------------------------------------------
class cColladaTransform {
public:
tString msSid;
tString msType;
tFloatVec mvValues;
};
typedef Common::List<cColladaTransform> tColladaTransformList;
typedef tColladaTransformList::iterator tColladaTransformListIt;
class cColladaNode;
typedef Common::List<cColladaNode *> tColladaNodeList;
typedef tColladaNodeList::iterator tColladaNodeListIt;
class cColladaNode {
public:
cColladaNode() : mlCount(0), pParent(NULL), mvScale(1, 1, 1), mbSourceIsFile(false) {}
tString msId;
tString msName;
tString msType;
tString msSource;
bool mbSourceIsFile;
cMatrixf m_mtxTransform;
cMatrixf m_mtxWorldTransform;
cColladaNode *pParent;
cVector3f mvScale;
int mlCount;
tColladaNodeList mlstChildren;
tColladaTransformList mlstTransforms;
/*void DeleteChildren()
{
STLDeleteAll(mlstChildren);
}*/
cColladaNode *CreateChild() {
cColladaNode *pNode = hplNew(cColladaNode, ());
mlstChildren.push_back(pNode);
pNode->pParent = this;
return pNode;
}
cColladaTransform *GetTransform(const tString &asSid) {
tColladaTransformListIt it = mlstTransforms.begin();
for (; it != mlstTransforms.end(); it++) {
cColladaTransform &Trans = *it;
if (Trans.msSid == asSid) {
return &Trans;
}
}
return NULL;
}
};
class cColladaScene {
public:
cColladaScene() {
mRoot.m_mtxTransform = cMatrixf::Identity;
mRoot.m_mtxWorldTransform = cMatrixf::Identity;
mfDeltaTime = 0;
}
~cColladaScene() {
// mRoot.DeleteChildren();
STLDeleteAll(mlstNodes);
}
void ResetNodes() {
STLDeleteAll(mlstNodes);
mRoot.mlstChildren.clear();
}
cColladaNode *GetNode(const tString asId) {
tColladaNodeListIt it = mlstNodes.begin();
for (; it != mlstNodes.end(); ++it) {
cColladaNode *pNode = *it;
if (pNode->msId == asId || pNode->msName == asId) {
return pNode;
}
}
return NULL;
}
cColladaNode *GetNodeFromSource(const tString asSource) {
tColladaNodeListIt it = mlstNodes.begin();
for (; it != mlstNodes.end(); ++it) {
cColladaNode *pNode = *it;
if (pNode->msSource == asSource) {
return pNode;
}
}
return NULL;
}
float mfStartTime;
float mfEndTime;
float mfDeltaTime;
cColladaNode mRoot;
tColladaNodeList mlstNodes;
};
//------------------------------------------------
class cMeshLoaderCollada : public iMeshLoader {
public:
cMeshLoaderCollada(iLowLevelGraphics *apLowLevelGraphics);
virtual ~cMeshLoaderCollada();
cMesh *LoadMesh(const tString &asFile, tMeshLoadFlag aFlags);
bool SaveMesh(cMesh *apMesh, const tString &asFile) { return false; }
cWorld3D *LoadWorld(const tString &asFile, cScene *apScene, tWorldLoadFlag aFlags);
cAnimation *LoadAnimation(const tString &asFile);
bool IsSupported(const tString asFileType);
void AddSupportedTypes(tStringVec *avFileTypes);
private:
bool mbZToY;
tWorldLoadFlag mFlags;
tString GetParentName(cColladaNode *apNode, tColladaGeometryVec *apColladaGeometries);
void CreateMeshJoint(cMeshJoint *apJoint, ePhysicsJointType aJointType, cBoundingVolume &aBV,
tStringVec &avStrings, cColladaNode *apNode, cColladaScene &aColladaScene,
tColladaGeometryVec &avColladaGeom);
void CreateHierarchyNodes(cMesh *apMesh, cNode3D *mpParentNode,
cColladaNode *apColladaNode,
tColladaGeometryVec &avColladaGeom);
cColladaGeometry *GetGeometry(const tString &asId, tColladaGeometryVec &avGeomVec);
cColladaLight *GetLight(const tString &asId, tColladaLightVec &avLightVec);
cMeshEntity *CreateStaticMeshEntity(cColladaNode *apNode, cWorld3D *apWorld,
cColladaGeometry *apGeom, bool abInRoomGroup,
tColladaMaterialVec &avColladaMaterials,
tColladaTextureVec &avColladaTextures,
tColladaImageVec &avColladaImages);
cColliderEntity *CreateStaticCollider(cColladaNode *apNode, cWorld3D *apWorld,
cColladaGeometry *apGeom,
tColladaMaterialVec &avColladaMaterials,
tColladaTextureVec &avColladaTextures,
tColladaImageVec &avColladaImages,
bool abCharacterCollider);
void AddSceneObjects(cColladaNode *apNode, cWorld3D *apWorld,
tColladaGeometryVec &avColladaGeometries, tColladaLightVec &avColladaLights,
tColladaMaterialVec &avColladaMaterials, tColladaTextureVec &avColladaTextures,
tColladaImageVec &avColladaImages, cColladaScene *apColladaScene);
void AddSectorChildren(cColladaNode *apNode, tString asSector, cWorld3D *apWorld,
tColladaGeometryVec &avColladaGeometries, tColladaLightVec &avColladaLights,
tColladaMaterialVec &avColladaMaterials, tColladaTextureVec &avColladaTextures,
tColladaImageVec &avColladaImages);
cAnimationTrack *CreateAnimTrack(cAnimation *apAnimation, cSkeleton *apSkeleton,
cColladaAnimation &aAnim, cColladaScene *apScene);
void CalcLocalMatrixRec(cBone *apBone, cMatrixf a_mtxParentGlobal, int alDepth);
void CreateSkeletonBone(cColladaNode *apColladaNode, cBone *apParentBone);
iVertexBuffer *CreateVertexBuffer(cColladaGeometry &aGeometry,
eVertexBufferUsageType aUsageType);
// tColladaExtraVtxListVec &vExtraVtxVec);
bool FillStructures(const tString &asFile,
tColladaImageVec *apColladaImageVec,
tColladaTextureVec *apColladaTextureVec,
tColladaMaterialVec *apColladaMaterialVec,
tColladaLightVec *apColladaLightVec,
tColladaGeometryVec *apColladaGeometryVec,
tColladaControllerVec *apColladaControllerVec,
tColladaAnimationVec *apColladaAnimVec,
cColladaScene *apColladaScene,
bool abCache);
bool SaveStructures(const tString &asFile,
tColladaImageVec *apColladaImageVec,
tColladaTextureVec *apColladaTextureVec,
tColladaMaterialVec *apColladaMaterialVec,
tColladaLightVec *apColladaLightVec,
tColladaGeometryVec *apColladaGeometryVec,
tColladaControllerVec *apColladaControllerVec,
tColladaAnimationVec *apColladaAnimVec,
cColladaScene *apColladaScene);
bool LoadStructures(const tString &asFile,
tColladaImageVec *apColladaImageVec,
tColladaTextureVec *apColladaTextureVec,
tColladaMaterialVec *apColladaMaterialVec,
tColladaLightVec *apColladaLightVec,
tColladaGeometryVec *apColladaGeometryVec,
tColladaControllerVec *apColladaControllerVec,
tColladaAnimationVec *apColladaAnimVec,
cColladaScene *apColladaScene);
void LoadColladaScene(TiXmlElement *apRootElem, cColladaNode *apParentNode, cColladaScene *apScene,
tColladaLightVec *apColladaLightVec);
void LoadAnimations(TiXmlElement *apRootElem, tColladaAnimationVec &avAnimations,
cColladaScene *apColladaScene);
void LoadImages(TiXmlElement *apRootElem, tColladaImageVec &avColladaImageVec);
void LoadTextures(TiXmlElement *apRootElem, tColladaTextureVec &avColladaTextureVec);
void LoadMaterials(TiXmlElement *apRootElem, tColladaMaterialVec &avColladaMaterialVec);
void LoadLights(TiXmlElement *apRootElem, tColladaLightVec &avColladaLightVec);
void LoadGeometry(TiXmlElement *apRootElem, tColladaGeometryVec &avColladaGeometryVec, cColladaScene *apColladaScene);
void LoadVertexData(TiXmlElement *apSourceElem, tVector3fVec &avVtxVec);
void LoadControllers(TiXmlElement *apRootElem, tColladaControllerVec &avColladaControllerVec,
tColladaGeometryVec *apColladaGeometryVec);
void LoadJointData(TiXmlElement *apSourceElem, cColladaController &aController);
// Helpers
void SplitVertices(cColladaGeometry &aGeometry, tColladaExtraVtxListVec &avExtraVtxVec,
tVertexVec &avVertexVec, tUIntVec &avIndexVec);
void FillVertexVec(const char *apChars, tVector3fVec &avVtxVec, int alElements, int alVtxCount);
tString GetTopString(const tString asPath);
tString GetMaterialTextureFile(const tString &asMaterial, tColladaMaterialVec &avColladaMaterialVec,
tColladaTextureVec &avColladaTextureVec,
tColladaImageVec &avColladaImageVec);
cVector3f GetVectorPos(const cVector3f &avVec);
cVector3f GetVectorPosFromPtr(float *apVec);
cVector3f GetVectorScaleFromPtr(float *apVec);
};
} // namespace hpl
#endif // HPL_MESH_LOADER_COLLADA_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,446 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/MeshLoaderMSH.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/graphics/VertexBuffer.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/graphics/Material.h"
#include "hpl1/engine/graphics/Mesh.h"
#include "hpl1/engine/graphics/SubMesh.h"
#include "hpl1/engine/resources/MaterialManager.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
#include "hpl1/engine/math/Math.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cMeshLoaderMSH::cMeshLoaderMSH(iLowLevelGraphics *apLowLevelGraphics) : iMeshLoader(apLowLevelGraphics) {
}
//-----------------------------------------------------------------------
cMeshLoaderMSH::~cMeshLoaderMSH() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
// Definition to make the error exit not so bloated.
#define ExitLoad() \
hplDelete(pMesh); \
hplDelete(pXmlDoc); \
return NULL;
cWorld3D *cMeshLoaderMSH::LoadWorld(const tString &asFile, cScene *apScene, tWorldLoadFlag aFlags) {
return NULL;
}
//-----------------------------------------------------------------------
cMesh *cMeshLoaderMSH::LoadMesh(const tString &asFile, tMeshLoadFlag aFlags) {
cMesh *pMesh = hplNew(cMesh, (cString::GetFileName(asFile), mpMaterialManager, mpAnimationManager));
// If the mesh is animated there are some property differences, the vertex buffer
// Must be Stream instead of static for example.
bool bIsAnimated = false;
/////////////////////////////////////////////////
// LOAD THE DOCUMENT
TiXmlDocument *pXmlDoc = hplNew(TiXmlDocument, (asFile.c_str()));
if (pXmlDoc->LoadFile() == false) {
Error("Couldn't load XML file '%s'!\n", asFile.c_str());
ExitLoad();
}
// Get the root.
TiXmlElement *pRootElem = pXmlDoc->RootElement();
/////////////////////////////////////////////////
// LOAD SUBMESHES
// Load the root
TiXmlElement *pSubMeshesRootElem = pRootElem->FirstChildElement("SubMeshes");
if (pSubMeshesRootElem == NULL) {
Error("No mesh data in XML file '%s'!\n", asFile.c_str());
ExitLoad();
}
// Iterate through the sub meshes
TiXmlElement *pSubMeshElem = pSubMeshesRootElem->FirstChildElement();
while (pSubMeshElem) {
//////////////////
// Create sub mesh
cSubMesh *pSubMesh = pMesh->CreateSubMesh(pSubMeshElem->Attribute("name"));
//////////////////
// Set material
const char *pMatName = pSubMeshElem->Attribute("material");
if (pMatName == NULL) {
Error("No material found for mesh '%s'\n", asFile.c_str());
ExitLoad();
}
iMaterial *pMaterial = mpMaterialManager->CreateMaterial(pMatName);
pSubMesh->SetMaterial(pMaterial);
////////////////////
// Get the vertices
TiXmlElement *pVtxElem = pSubMeshElem->FirstChildElement("Vertices");
int lVtxSize = cString::ToInt(pVtxElem->Attribute("size"), 0);
tVertexFlag vtxFlags = 0;
bool bTangents = false;
// Check what type of vertices are included.
if (pVtxElem->FirstChild("Normal"))
vtxFlags |= eVertexFlag_Normal;
if (pVtxElem->FirstChild("Position"))
vtxFlags |= eVertexFlag_Position;
if (pVtxElem->FirstChild("Texture"))
vtxFlags |= eVertexFlag_Texture0;
if (pVtxElem->FirstChild("Color"))
vtxFlags |= eVertexFlag_Color0;
if (pVtxElem->FirstChild("Tangent")) {
vtxFlags |= eVertexFlag_Texture1;
bTangents = true;
}
// Create the vertex buffer
eVertexBufferUsageType usageType = bIsAnimated ? eVertexBufferUsageType_Stream : eVertexBufferUsageType_Static;
iVertexBuffer *pVtxBuff = mpLowLevelGraphics->CreateVertexBuffer(vtxFlags,
eVertexBufferDrawType_Tri,
usageType,
0, 0);
pVtxBuff->SetTangents(bTangents);
// Fill the arrays
for (int i = 0; i < klNumOfVertexFlags; i++) {
if (kvVertexFlags[i] & vtxFlags) {
int lElemPerVtx = 3;
if (kvVertexFlags[i] & eVertexFlag_Texture1 || kvVertexFlags[i] & eVertexFlag_Color0) {
lElemPerVtx = 4;
}
TiXmlElement *pElem = pVtxElem->FirstChildElement(GetVertexName(kvVertexFlags[i]));
pVtxBuff->ResizeArray(kvVertexFlags[i], lVtxSize * lElemPerVtx);
float *pArray = pVtxBuff->GetArray(kvVertexFlags[i]);
// Log("TYPE: %s:\n",GetVertexName(kvVertexFlags[i]));
FillVtxArray(pArray, pElem->Attribute("data"), lVtxSize * lElemPerVtx);
}
}
////////////////////
// Get Indices
TiXmlElement *pIdxElem = pSubMeshElem->FirstChildElement("Indices");
int lIdxSize = cString::ToInt(pIdxElem->Attribute("size"), 0);
// Log("TYPE: Indices\n");
pVtxBuff->ResizeIndices(lIdxSize);
FillIdxArray(pVtxBuff->GetIndices(), pIdxElem->Attribute("data"), lIdxSize);
///////////////////
// Compile vertex buffer
pVtxBuff->Compile(0);
pSubMesh->SetVertexBuffer(pVtxBuff);
/////////////////
// Next element
pSubMeshElem = pSubMeshesRootElem->NextSiblingElement();
}
/////////////////////////////////////////////////
// LOAD SKELETON
hplDelete(pXmlDoc);
return pMesh;
}
//-----------------------------------------------------------------------
bool cMeshLoaderMSH::SaveMesh(cMesh *apMesh, const tString &asFile) {
TiXmlDocument *pXmlDoc = hplNew(TiXmlDocument, (asFile.c_str()));
// Root
TiXmlElement XmlRoot("HPL_Mesh");
TiXmlElement *pRootElem = static_cast<TiXmlElement *>(pXmlDoc->InsertEndChild(XmlRoot));
// SubMeshes
TiXmlElement XmlSubMeshes("SubMeshes");
TiXmlElement *pSubMeshesElem = static_cast<TiXmlElement *>(pRootElem->InsertEndChild(XmlSubMeshes));
// SubMesh
for (int i = 0; i < apMesh->GetSubMeshNum(); i++) {
cSubMesh *pSubMesh = apMesh->GetSubMesh(i);
iVertexBuffer *pVtxBuff = pSubMesh->GetVertexBuffer();
int lVtxSize = pVtxBuff->GetVertexNum();
int lIdxSize = pVtxBuff->GetIndexNum();
// Create element
TiXmlElement XmlSubMesh("SubMesh");
TiXmlElement *pSubMeshElem = static_cast<TiXmlElement *>(pSubMeshesElem->InsertEndChild(XmlSubMesh));
// Set data
pSubMeshElem->SetAttribute("name", pSubMesh->GetName().c_str());
iMaterial *pMat = pSubMesh->GetMaterial();
if (pMat)
pSubMeshElem->SetAttribute("material", pMat->GetName().c_str());
// Vertices
TiXmlElement XmlVtx("Vertices");
TiXmlElement *pVtxElem = static_cast<TiXmlElement *>(pSubMeshElem->InsertEndChild(XmlVtx));
pVtxElem->SetAttribute("size", lVtxSize);
for (int j = 0; j < klNumOfVertexFlags; j++) {
if (kvVertexFlags[j] & pVtxBuff->GetVertexFlags()) {
int lSizeMul = kvVertexElements[i];
// Only support texture1 coordinate as tangent for now.
if (kvVertexFlags[j] & eVertexFlag_Texture1)
lSizeMul = 4;
SaveFloatData(pVtxElem, lVtxSize * lSizeMul, GetVertexName(kvVertexFlags[j]),
pVtxBuff->GetArray(kvVertexFlags[j]));
}
}
// Indices
TiXmlElement XmlIdx("Indices");
TiXmlElement *pIdxElem = static_cast<TiXmlElement *>(pSubMeshElem->InsertEndChild(XmlIdx));
pIdxElem->SetAttribute("size", lIdxSize);
SaveIntData(pIdxElem, lIdxSize, pVtxBuff->GetIndices());
}
bool bRet = pXmlDoc->SaveFile();
if (bRet == false)
Error("Couldn't save mesh to '%s'", asFile.c_str());
hplDelete(pXmlDoc);
return bRet;
}
//-----------------------------------------------------------------------
bool cMeshLoaderMSH::IsSupported(const tString asFileType) {
if (asFileType == "msh")
return true;
return false;
}
//-----------------------------------------------------------------------
void cMeshLoaderMSH::AddSupportedTypes(tStringVec *avFileTypes) {
avFileTypes->push_back("msh");
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cMeshLoaderMSH::SaveFloatData(TiXmlElement *apRoot, int alSize, const char *asName, float *apData) {
// Pos
TiXmlElement XmlData(asName);
TiXmlElement *pElem = static_cast<TiXmlElement *>(apRoot->InsertEndChild(XmlData));
tString sData = "";
char sTemp[20];
for (int i = 0; i < alSize; i++) {
float fNum = apData[i];
int j;
// get the number of decimals needed
for (j = 6; j > 0; j--) {
if (((int)(fNum * 10 * (float)j)) % 10 != 0) {
break;
}
}
int lDecimals = j;
switch (lDecimals) {
case 0:
snprintf(sTemp, 20, "%.0f", apData[i]);
break;
case 1:
snprintf(sTemp, 20, "%.1f", apData[i]);
break;
case 2:
snprintf(sTemp, 20, "%.2f", apData[i]);
break;
case 3:
snprintf(sTemp, 20, "%.3f", apData[i]);
break;
case 4:
snprintf(sTemp, 20, "%.4f", apData[i]);
break;
case 5:
snprintf(sTemp, 20, "%.5f", apData[i]);
break;
case 6:
snprintf(sTemp, 20, "%.6f", apData[i]);
break;
default:
error("trying to serialize a floating point value with a precision that is not in the range 1-6");
}
sData += sTemp;
if (i != alSize - 1)
sData += " ";
}
pElem->SetAttribute("data", sData.c_str());
}
//-----------------------------------------------------------------------
const char *cMeshLoaderMSH::GetVertexName(tVertexFlag aFlag) {
switch (aFlag) {
case eVertexFlag_Normal:
return "Normal";
case eVertexFlag_Position:
return "Position";
case eVertexFlag_Color0:
return "Color";
case eVertexFlag_Texture0:
return "Texture";
case eVertexFlag_Texture1:
return "Tangent";
}
return "";
}
//-----------------------------------------------------------------------
void cMeshLoaderMSH::SaveIntData(TiXmlElement *apElem, int alSize, unsigned int *apData) {
tString sData = "";
char sTemp[10];
for (int i = 0; i < alSize; i++) {
snprintf(sTemp, 10, "%d", apData[i]);
sData += sTemp;
if (i != alSize - 1)
sData += " ";
}
apElem->SetAttribute("data", sData.c_str());
}
//-----------------------------------------------------------------------
void cMeshLoaderMSH::FillVtxArray(float *apArray, const char *apString, int alSize) {
if (apString == NULL) {
Error("Data is NULL!\n");
return;
}
char vTempChar[20];
int lTempCharCount = 0;
int lArrayCount = 0;
int lStringCount = 0;
while (lArrayCount < alSize) {
char c = apString[lStringCount];
// if a space is found, convert the previous characters to a float.
if (c == ' ' || c == 0) {
if (lTempCharCount > 0) {
vTempChar[lTempCharCount] = 0;
apArray[lArrayCount] = (float)atof(vTempChar);
lTempCharCount = 0;
lArrayCount++;
}
}
// If character is not a space, add to temp char.
else {
vTempChar[lTempCharCount] = apString[lStringCount];
lTempCharCount++;
}
lStringCount++;
}
}
//-----------------------------------------------------------------------
void cMeshLoaderMSH::FillIdxArray(unsigned int *apArray, const char *apString, int alSize) {
char vTempChar[20];
int lTempCharCount = 0;
int lArrayCount = 0;
int lStringCount = 0;
while (lArrayCount < alSize) {
char c = apString[lStringCount];
// if a space is found, convert the previous characters to a float.
if (c == ' ' || c == 0) {
if (lTempCharCount > 0) {
vTempChar[lTempCharCount] = 0;
apArray[lArrayCount] = (unsigned int)atoi(vTempChar);
// Log("Adding: %d\n",apArray[lArrayCount]);
lTempCharCount = 0;
lArrayCount++;
}
}
// If character is not a space, add to temp char.
else {
vTempChar[lTempCharCount] = c;
lTempCharCount++;
}
lStringCount++;
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,74 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_MESH_LOADER_MSH_H
#define HPL_MESH_LOADER_MSH_H
#include "hpl1/engine/graphics/VertexBuffer.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/resources/MeshLoader.h"
class TiXmlElement;
namespace hpl {
class cMesh;
class cNode3D;
class iVertexBuffer;
class cMeshLoaderMSH : public iMeshLoader {
public:
cMeshLoaderMSH(iLowLevelGraphics *apLowLevelGraphics);
~cMeshLoaderMSH();
cMesh *LoadMesh(const tString &asFile, tMeshLoadFlag aFlags);
bool SaveMesh(cMesh *apMesh, const tString &asFile);
cWorld3D *LoadWorld(const tString &asFile, cScene *apScene, tWorldLoadFlag aFlags);
cAnimation *LoadAnimation(const tString &asFile) { return NULL; }
bool IsSupported(const tString asFileType);
void AddSupportedTypes(tStringVec *avFileTypes);
private:
// Saving
void SaveFloatData(TiXmlElement *apRoot, int alSize, const char *asName, float *apData);
void SaveIntData(TiXmlElement *apRoot, int alSize, unsigned int *apData);
// Loading
void FillVtxArray(float *apArray, const char *apString, int alSize);
void FillIdxArray(unsigned int *apArray, const char *apString, int alSize);
// Common
const char *GetVertexName(tVertexFlag aFlag);
};
} // namespace hpl
#endif // HPL_MESH_LOADER_MSH_H

View File

@@ -0,0 +1,84 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/OcclusionQueryOGL.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cOcclusionQueryOGL::cOcclusionQueryOGL() {
glGenQueries(1, (GLuint *)&mlQueryId);
mlLastSampleCount = 0;
}
//-----------------------------------------------------------------------
cOcclusionQueryOGL::~cOcclusionQueryOGL() {
glDeleteQueries(1, (GLuint *)&mlQueryId);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cOcclusionQueryOGL::Begin() {
glBeginQuery(GL_SAMPLES_PASSED, mlQueryId);
}
void cOcclusionQueryOGL::End() {
glEndQuery(GL_SAMPLES_PASSED);
}
bool cOcclusionQueryOGL::FetchResults() {
int lAvailable = 0;
glGetQueryObjectiv(mlQueryId, GL_QUERY_RESULT_AVAILABLE, (GLint *)&lAvailable);
if (lAvailable == 0)
return false;
glGetQueryObjectiv(mlQueryId, GL_QUERY_RESULT, (GLint *)&mlLastSampleCount);
return true;
}
unsigned int cOcclusionQueryOGL::GetSampleCount() {
return mlLastSampleCount;
}
//-----------------------------------------------------------------------
} // namespace hpl
#endif // HL1_USE_OPENGL

View File

@@ -0,0 +1,57 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_OCCLUSION_QUERY_OGL_H
#define HPL_OCCLUSION_QUERY_OGL_H
#include "common/scummsys.h"
#include "hpl1/engine/graphics/OcclusionQuery.h"
#include "hpl1/opengl.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
class cOcclusionQueryOGL : public iOcclusionQuery {
public:
cOcclusionQueryOGL();
~cOcclusionQueryOGL();
void Begin();
void End();
bool FetchResults();
unsigned int GetSampleCount();
public:
int mlLastSampleCount;
unsigned int mlQueryId;
};
} // namespace hpl
#endif // HPL1_USE_OPENGL
#endif // HPL_OCCLUSION_QUERY_H

View File

@@ -0,0 +1,259 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/OpenALSoundChannel.h"
#include "hpl1/engine/impl/LowLevelSoundOpenAL.h"
#include "hpl1/engine/impl/OpenALSoundData.h"
#include "hpl1/engine/resources/SoundManager.h"
#include "audio/mixer.h"
#include "common/system.h"
#include "hpl1/debug.h"
#include "hpl1/engine/math/Math.h"
#define mixer g_system->getMixer()
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cOpenALSoundChannel::cOpenALSoundChannel(cOpenALSoundData *soundData, Audio::SeekableAudioStream *audioStream, cSoundManager *apSoundManger, cLowLevelSoundOpenAL *lowLevelSound, int priority)
: iSoundChannel(soundData, apSoundManger), _audioStream(audioStream), _lowLevelSound(lowLevelSound), _priority(priority) {
Hpl1::logInfo(Hpl1::kDebugAudio, "creating sound channel form file %s\n", mpData->GetName().c_str());
if (!_audioStream)
Hpl1::logError(Hpl1::kDebugAudio, "sound channel created with null audio stream%s", ".");
#if 0
mlChannel = alChannel;
for(int i=0;i<3;i++)
{
mfPosition[i] = 0;
mfVelocity[i] = 0;
}
OAL_Source_SetAttributes ( mlChannel, mfPosition, mfVelocity );
OAL_Source_SetFilterType(mlChannel, eOALFilterType_LowPass);
#endif
// SetAffectedByEnv(true);
// SetFilterGainHF(0.01f);
// SetFiltering(true,0x3);
// OAL_Source_SetMinMaxDistance ( mlChannel, 100000.0f, 200000.f );
}
//-----------------------------------------------------------------------
cOpenALSoundChannel::~cOpenALSoundChannel() {
_lowLevelSound->closeChannel(this);
if (_audioStream)
delete _audioStream;
if (mpSoundManger)
mpSoundManger->Destroy(mpData);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cOpenALSoundChannel::Play() {
if (!_audioStream) {
Hpl1::logWarning(Hpl1::kDebugAudio, "trying to play an empty audio stream%c", '\n');
return;
}
Hpl1::logInfo(Hpl1::kDebugAudio, "playing sound channel from data %s\n", mpData->GetName().c_str());
if (!_lowLevelSound->playChannel(this)) {
Hpl1::logWarning(Hpl1::kDebugAudio, "sound channel from data %s could not be played\n",
mpData->GetName().c_str());
}
SetVolume(mfVolume);
if (mbLooping)
mixer->loopChannel(_handle);
mbStopUsed = false;
mbPaused = false;
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::Stop() {
Hpl1::logInfo(Hpl1::kDebugAudio, "stopping audio channel from data %s\n", mpData->GetName().c_str());
mixer->stopHandle(_handle);
mbStopUsed = true;
mbLooping = false;
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetPaused(bool pause) {
Hpl1::logInfo(Hpl1::kDebugAudio, "%spausing sound channel from data %s\n", pause ? "" : "un",
mpData->GetName().c_str());
mixer->pauseHandle(_handle, pause);
mbPaused = pause;
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetSpeed(float afSpeed) {
mfSpeed = afSpeed;
#if 0
OAL_Source_SetPitch ( mlChannel, afSpeed );
#endif
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetVolume(float volume) {
mfVolume = cMath::Clamp(volume, 0.0, 1.0);
mixer->setChannelVolume(_handle, static_cast<byte>(mfVolume * 255.f));
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetLooping(bool loop) {
Hpl1::logInfo(Hpl1::kDebugAudio, "%slooping audio from source %s\n", loop ? "" : "un", mpData->GetName().c_str());
const bool previousState = mbLooping;
mbLooping = loop;
if (IsPlaying() && loop) // it has already started
mixer->loopChannel(_handle);
else if (previousState && !loop && IsPlaying()) { // unlooped while playing
_lowLevelSound->closeChannel(this);
Play();
}
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetPan(float afPan) {
// Log("Pan: %d\n", lPan);
// cVector3f vPosition = mvPosition;
// vPosition.x =
// OAL_Source_SetAttributes ( mlChannel, mvPosition.
// FSOUND_SetPan(mlChannel, lPan);
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::Set3D(bool ab3D) {
mb3D = ab3D;
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetPositionRelative(bool abRelative) {
mbPositionRelative = abRelative;
// OAL_Source_SetPositionRelative ( mlChannel, abRelative );
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetPosition(const cVector3f &avPos) {
mvPosition = avPos;
#if 0
OAL_Source_SetAttributes ( mlChannel, mvPosition.v, mvVelocity.v );
#endif
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetVelocity(const cVector3f &avVel) {
mvVelocity = avVel;
#if 0
OAL_Source_SetAttributes ( mlChannel, mvPosition.v, mvVelocity.v );
#endif
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetMinDistance(float afMin) {
mfMinDistance = afMin;
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetMaxDistance(float afMax) {
mfMaxDistance = afMax;
}
//-----------------------------------------------------------------------
bool cOpenALSoundChannel::IsPlaying() {
return mixer->isSoundHandleActive(_handle);
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetPriority(int alX) {
_priority = MAX(alX, 255);
}
//-----------------------------------------------------------------------
int cOpenALSoundChannel::GetPriority() {
return _priority;
}
//-----------------------------------------------------------------------
void cOpenALSoundChannel::SetAffectedByEnv(bool abAffected) {
// if (!(gpGame->GetSound()->GetLowLevel()->IsEnvAudioAvailable()))
// return;
#if 0
iSoundChannel::SetAffectedByEnv(abAffected);
if (mbAffectedByEnv)
OAL_Source_SetAuxSendSlot(mlChannel,0,0);
else
OAL_Source_SetAuxSendSlot(mlChannel,0,-1);
#endif
}
void cOpenALSoundChannel::SetFiltering(bool abEnabled, int alFlags) {
#if 0
// if (!(gpGame->GetSound()->GetLowLevel()->IsEnvAudioAvailable()))
// return;
OAL_Source_SetFiltering(mlChannel,abEnabled, alFlags);
#endif
}
void cOpenALSoundChannel::SetFilterGain(float afGain) {
HPL1_UNIMPLEMENTED(cOpenALSoundChannel::SetFilterGain);
}
void cOpenALSoundChannel::SetFilterGainHF(float afGainHF) {
HPL1_UNIMPLEMENTED(cOpenALSoundChannel::SetFilterGainHF);
}
} // namespace hpl

View File

@@ -0,0 +1,98 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_OPENAL_SOUND_CHANNEL_H
#define HPL_OPENAL_SOUND_CHANNEL_H
#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "common/file.h"
#include "common/str.h"
#include "hpl1/engine/impl/OpenALSoundData.h"
#include "hpl1/engine/sound/SoundChannel.h"
#include "hpl1/engine/sound/SoundData.h"
//#include "OALWrapper/OAL_Funcs.h"
namespace hpl {
class cLowLevelSoundOpenAL;
class cOpenALSoundChannel : public iSoundChannel {
friend class cLowLevelSoundOpenAL;
public:
cOpenALSoundChannel(cOpenALSoundData *soundData, Audio::SeekableAudioStream *audioStream, cSoundManager *apSoundManger, cLowLevelSoundOpenAL *lowLevelSound, int priority);
~cOpenALSoundChannel();
void Play();
void Stop();
void SetPaused(bool abX);
void SetSpeed(float afSpeed);
void SetVolume(float afVolume);
void SetLooping(bool abLoop);
void SetPan(float afPan);
void Set3D(bool ab3D);
void SetPriority(int alX);
int GetPriority();
void SetPositionRelative(bool abRelative);
void SetPosition(const cVector3f &avPos);
void SetVelocity(const cVector3f &avVel);
void SetMinDistance(float fMin);
void SetMaxDistance(float fMax);
bool IsPlaying();
bool IsBufferUnderrun() { return false; }
double GetElapsedTime() { return g_system->getMixer()->getElapsedTime(_handle).secs(); }
double GetTotalTime() { return _audioStream->getLength().secs(); }
void SetAffectedByEnv(bool abAffected);
void SetFiltering(bool abEnabled, int alFlags);
void SetFilterGain(float afGain);
void SetFilterGainHF(float afGainHF);
private:
void restart();
Audio::SoundHandle _handle;
Audio::SeekableAudioStream *_audioStream;
cLowLevelSoundOpenAL *_lowLevelSound;
int _priority;
// int mlDefaultFreq;
// float mfPosition[3];
// float mfVelocity[3];
};
} // namespace hpl
#endif // HPL_OPENAL_CHANNEL_H

View File

@@ -0,0 +1,120 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/OpenALSoundData.h"
#include "audio/audiostream.h"
#include "audio/decoders/vorbis.h"
#include "audio/decoders/wave.h"
#include "common/memstream.h"
#include "hpl1/debug.h"
#include "hpl1/engine/impl/OpenALSoundChannel.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
enum DataFormat {
kWav,
kOgg,
kNone,
};
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cOpenALSoundData::cOpenALSoundData(tString asName, bool abStream, cLowLevelSoundOpenAL *lowLevelSound)
: iSoundData(asName, abStream), _lowLevelSound(lowLevelSound) {
}
//-----------------------------------------------------------------------
cOpenALSoundData::~cOpenALSoundData() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
static uint audioDataFormat(const tString &filename) {
if (filename.hasSuffix("wav"))
return kWav;
else if (filename.hasSuffix("ogg"))
return kOgg;
return kNone;
}
bool cOpenALSoundData::CreateFromFile(const tString &filename) {
if (_audioData) {
Hpl1::logWarning(Hpl1::kDebugAudio, "overriding previous sound data with new audio at '%s'\n", filename.c_str());
}
Common::File file;
if (!file.open(Common::Path(filename))) {
Hpl1::logWarning(Hpl1::kDebugFilePath | Hpl1::kDebugResourceLoading | Hpl1::kDebugAudio, "Audio file '%s' could not be opened\n", filename.c_str());
return false;
}
if (file.err() || file.size() < 0) {
Hpl1::logError(Hpl1::kDebugResourceLoading | Hpl1::kDebugAudio, "error reading file '%s'\n", filename.c_str());
return false;
}
_format = audioDataFormat(filename);
_audioDataSize = file.size();
_audioData.reset(Common::SharedPtr<byte>((byte *)malloc(_audioDataSize), free));
file.read(_audioData.get(), _audioDataSize);
return true;
}
//-----------------------------------------------------------------------
static Audio::SeekableAudioStream *createAudioStream(Common::MemoryReadStream *data, uint format) {
switch (format) {
#ifdef USE_VORBIS
case kOgg:
return Audio::makeVorbisStream(data, DisposeAfterUse::YES);
#endif
case kWav:
return Audio::makeWAVStream(data, DisposeAfterUse::YES);
}
return nullptr;
}
iSoundChannel *cOpenALSoundData::CreateChannel(int priority) {
IncUserCount();
if (!_audioData)
return nullptr;
auto *dataStream = new Common::MemoryReadStream(_audioData, _audioDataSize);
auto *audioStream = createAudioStream(dataStream, _format);
return new cOpenALSoundChannel(this, audioStream, mpSoundManger, _lowLevelSound, priority);
}
} // namespace hpl

View File

@@ -0,0 +1,62 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_OPENAL_SOUND_DATA_H
#define HPL_OPENAL_SOUND_DATA_H
#include "hpl1/engine/sound/SoundData.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "audio/audiostream.h"
#include "common/ptr.h"
#include "common/str.h"
namespace hpl {
class cLowLevelSoundOpenAL;
class cOpenALSoundData : public iSoundData {
public:
cOpenALSoundData(tString asName, bool abStream, cLowLevelSoundOpenAL *lowLevelSound);
~cOpenALSoundData();
bool CreateFromFile(const tString &asFile);
iSoundChannel *CreateChannel(int alPriority);
bool IsStream() { return mbStream; }
private:
Common::SharedPtr<byte> _audioData = nullptr;
uint32 _audioDataSize = 0;
uint _format = 0;
cLowLevelSoundOpenAL *_lowLevelSound;
};
} // namespace hpl
#endif // HPL_OPENAL_SOUND_DATA_H

View File

@@ -0,0 +1,123 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/OpenALSoundEnvironment.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
namespace hpl {
cOpenALSoundEnvironment::cOpenALSoundEnvironment() /*:
mfDensity(1.0f),
mfDiffusion(1.0f),
mfGain(0.32f),
mfGainHF(0.89f),
mfGainLF(0.0f),
mfDecayTime(1.49f),
mfDecayHFRatio(0.83f),
mfDecayLFRatio(1.0f),
mfReflectionsGain(0.05f),
mfReflectionsDelay(0.007f),
mfLateReverbGain(1.25f),
mfLateReverbDelay(0.011f),
mfEchoTime(0.25f),
mfEchoDepth(0.0f),
mfModulationTime(0.25f),
mfModulationDepth(0.0f),
mfAirAbsorptionGainHF(0.994f),
mfHFReference(5000.0f),
mfLFReference(250.0f),
mfRoomRolloffFactor(0.0f),
mbDecayHFLimit(true)*/
{
}
cOpenALSoundEnvironment::~cOpenALSoundEnvironment() {
}
bool cOpenALSoundEnvironment::CreateFromFile(const tString &asFile) {
#if 0
tString strType;
TiXmlDocument doc;
if (!doc.LoadFile(asFile.c_str()))
return false;
TiXmlElement* pMain = doc.FirstChildElement("SoundEnvironment")->FirstChildElement("Main");
if (pMain)
{
strType = pMain->Attribute("Type");
mstrName = pMain->Attribute("Name");
}
float* pfTemp;
TiXmlElement* pParams = doc.FirstChildElement("SoundEnvironment")->FirstChildElement("Parameters");
if ( (pParams == NULL) || (strType.compare("OpenAL")!=0) )
{
doc.Clear();
return false;
}
mfDensity = cString::ToFloat(pParams->Attribute("Density"),0);
mfDiffusion = cString::ToFloat(pParams->Attribute("Diffusion"),0);
mfGain = cString::ToFloat(pParams->Attribute("Gain"),0);
mfGainHF = cString::ToFloat(pParams->Attribute("GainHF"),0);
mfGainLF = cString::ToFloat(pParams->Attribute("GainLF"),0);
mfDecayTime = cString::ToFloat(pParams->Attribute("DecayTime"),0);
mfDecayHFRatio = cString::ToFloat (pParams->Attribute("DecayHFRatio"),0);
mfDecayLFRatio = cString::ToFloat (pParams->Attribute("DecayLFRatio"),0);
mfReflectionsGain = cString::ToFloat(pParams->Attribute("ReflectionsGain"),0);
mfReflectionsDelay = cString::ToFloat(pParams->Attribute("ReflectionsDelay"),0);
pfTemp = cString::ToVector3f(pParams->Attribute("ReflectionsPan"),cVector3f(0)).v;
mfReflectionsPan[0] = pfTemp[0];
mfReflectionsPan[1] = pfTemp[1];
mfReflectionsPan[2] = pfTemp[2];
mfLateReverbGain = cString::ToFloat(pParams->Attribute("LateReverbGain"),0);
mfLateReverbDelay = cString::ToFloat(pParams->Attribute("LateReverbDelay"),0);
pfTemp = cString::ToVector3f(pParams->Attribute("LateReverbPan"),cVector3f(0)).v;
mfLateReverbPan[0] = pfTemp[0];
mfLateReverbPan[1] = pfTemp[1];
mfLateReverbPan[2] = pfTemp[2];
mfEchoTime = cString::ToFloat(pParams->Attribute("EchoTime"),0);
mfEchoDepth = cString::ToFloat(pParams->Attribute("EchoDepth"),0);
mfModulationTime = cString::ToFloat(pParams->Attribute("ModulationTime"),0);
mfModulationDepth = cString::ToFloat(pParams->Attribute("ModulationDepth"),0);
mfAirAbsorptionGainHF = cString::ToFloat(pParams->Attribute("AirAbsorptionGainHF"),0);
mfHFReference = cString::ToFloat(pParams->Attribute("HFReference"),0);
mfLFReference = cString::ToFloat(pParams->Attribute("LFReference"),0);
mfRoomRolloffFactor =cString::ToFloat(pParams->Attribute("RoomRolloffFactor"),0);
mbDecayHFLimit = cString::ToInt(pParams->Attribute("DecayHFLimit"),0);
doc.Clear();
pParams = NULL;
#endif
return true;
}
} // namespace hpl

View File

@@ -0,0 +1,128 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_OPENALSOUNDENVIRONMENT_H
#define HPL_OPENALSOUNDENVIRONMENT_H
#include "hpl1/engine/sound/SoundEnvironment.h"
namespace hpl {
class cSoundManager;
class cOpenALSoundEnvironment : public iSoundEnvironment {
public:
cOpenALSoundEnvironment();
~cOpenALSoundEnvironment();
bool CreateFromFile(const tString &asFile);
inline float GetDensity() { return mfDensity; }
inline float GetDiffusion() { return mfDiffusion; }
inline float GetGain() { return mfGain; }
inline float GetGainHF() { return mfGainHF; }
inline float GetGainLF() { return mfGainLF; }
inline float GetDecayTime() { return mfDecayTime; }
inline float GetDecayHFRatio() { return mfDecayHFRatio; }
inline float GetDecayLFRatio() { return mfDecayLFRatio; }
inline float GetReflectionsGain() { return mfReflectionsGain; }
inline float GetReflectionsDelay() { return mfReflectionsDelay; }
inline float *GetReflectionsPan() { return mfReflectionsPan; }
inline float GetLateReverbGain() { return mfLateReverbGain; }
inline float GetLateReverbDelay() { return mfLateReverbDelay; }
inline float *GetLateReverbPan() { return mfLateReverbPan; }
inline float GetEchoTime() { return mfEchoTime; }
inline float GetEchoDepth() { return mfEchoDepth; }
inline float GetModulationTime() { return mfModulationTime; }
inline float GetModulationDepth() { return mfModulationDepth; }
inline float GetAirAbsorptionGainHF() { return mfAirAbsorptionGainHF; }
inline float GetHFReference() { return mfHFReference; }
inline float GetLFReference() { return mfLFReference; }
inline float GetRoomRolloffFactor() { return mfRoomRolloffFactor; }
inline int GetDecayHFLimit() { return mbDecayHFLimit; }
inline void SetDensity(float afDensity) { mfDensity = afDensity; }
inline void SetDiffusion(float afDiffusion) { mfDiffusion = afDiffusion; }
inline void SetGain(float afGain) { mfGain = afGain; }
inline void SetGainHF(float afGainHF) { mfGainHF = afGainHF; }
inline void SetGainLF(float afGainLF) { mfGainLF = afGainLF; }
inline void SetDecayTime(float afDecayTime) { mfDecayTime = afDecayTime; }
inline void SetDecayHFRatio(float afDecayHFRatio) { mfDecayHFRatio = afDecayHFRatio; }
inline void SetDecayLFRatio(float afDecayLFRatio) { mfDecayLFRatio = afDecayLFRatio; }
inline void SetReflectionsGain(float afReflectionsGain) { mfReflectionsGain = afReflectionsGain; }
inline void SetReflectionsDelay(float afReflectionsDelay) { mfReflectionsDelay = afReflectionsDelay; }
inline void SetReflectionsPan(float afReflectionsPan[3]) {
mfReflectionsPan[0] = afReflectionsPan[0];
mfReflectionsPan[1] = afReflectionsPan[1];
mfReflectionsPan[2] = afReflectionsPan[2];
}
inline void SetLateReverbGain(float afLateReverbGain) { mfLateReverbGain = afLateReverbGain; }
inline void SetLateReverbDelay(float afLateReverbDelay) { mfLateReverbDelay = afLateReverbDelay; }
inline void SetLateReverbPan(float afLateReverbPan[3]) {
mfLateReverbPan[0] = afLateReverbPan[0];
mfLateReverbPan[1] = afLateReverbPan[1];
mfLateReverbPan[2] = afLateReverbPan[2];
}
inline void SetEchoTime(float afEchoTime) { mfEchoTime = afEchoTime; }
inline void SetEchoDepth(float afEchoDepth) { mfEchoDepth = afEchoDepth; }
inline void SetModulationTime(float afModulationTime) { mfModulationTime = afModulationTime; }
inline void SetModulationDepth(float afModulationDepth) { mfModulationDepth = afModulationDepth; }
inline void SetAirAbsorptionGainHF(float afAirAbsorptionGainHF) { mfAirAbsorptionGainHF = afAirAbsorptionGainHF; }
inline void SetHFReference(float afHFReference) { mfHFReference = afHFReference; }
inline void SetLFReference(float afLFReference) { mfLFReference = afLFReference; }
inline void SetRoomRolloffFactor(float afRoomRolloffFactor) { mfRoomRolloffFactor = afRoomRolloffFactor; }
inline void SetDecayHFLimit(int abDecayHFLimit) { mbDecayHFLimit = abDecayHFLimit; }
protected:
float mfDensity;
float mfDiffusion;
float mfGain;
float mfGainHF;
float mfGainLF;
float mfDecayTime;
float mfDecayHFRatio;
float mfDecayLFRatio;
float mfReflectionsGain;
float mfReflectionsDelay;
float mfReflectionsPan[3];
float mfLateReverbGain;
float mfLateReverbDelay;
float mfLateReverbPan[3];
float mfEchoTime;
float mfEchoDepth;
float mfModulationTime;
float mfModulationDepth;
float mfAirAbsorptionGainHF;
float mfHFReference;
float mfLFReference;
float mfRoomRolloffFactor;
int mbDecayHFLimit;
};
} // namespace hpl
#endif // HPL_OPENALSOUNDENVIRONMENT_H

View File

@@ -0,0 +1,507 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/impl/CollideShapeNewton.h"
#include "hpl1/engine/impl/PhysicsMaterialNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/libraries/angelscript/angelscript.h"
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/math/Vector3.h"
#include "hpl1/engine/scene/Node3D.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
bool cPhysicsBodyNewton::mbUseCallback = true;
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsBodyNewton::cPhysicsBodyNewton(const tString &asName, iPhysicsWorld *apWorld, iCollideShape *apShape)
: iPhysicsBody(asName, apWorld, apShape) {
cPhysicsWorldNewton *pWorldNewton = static_cast<cPhysicsWorldNewton *>(apWorld);
cCollideShapeNewton *pShapeNewton = static_cast<cCollideShapeNewton *>(apShape);
mpNewtonWorld = pWorldNewton->GetNewtonWorld();
mpNewtonBody = NewtonCreateBody(pWorldNewton->GetNewtonWorld(),
pShapeNewton->GetNewtonCollision(), cMatrixf::Identity.v);
mpCallback = hplNew(cPhysicsBodyNewtonCallback, ());
AddCallback(mpCallback);
// Setup the callbacks and set this body as user data
// This is so that the transform gets updated and
// to add gravity, forces and user sink.
NewtonBodySetForceAndTorqueCallback(mpNewtonBody, OnUpdateCallback);
NewtonBodySetTransformCallback(mpNewtonBody, OnTransformCallback);
NewtonBodySetUserData(mpNewtonBody, this);
// Set default property settings
mbGravity = true;
mfMaxLinearSpeed = 0;
mfMaxAngularSpeed = 0;
mfMass = 0;
mfAutoDisableLinearThreshold = 0.01f;
mfAutoDisableAngularThreshold = 0.01f;
mlAutoDisableNumSteps = 10;
// Log("Creating newton body '%s' %d\n",msName.c_str(),(size_t)this);
}
//-----------------------------------------------------------------------
cPhysicsBodyNewton::~cPhysicsBodyNewton() {
// Log(" Destroying newton body '%s' %d\n",msName.c_str(),(size_t)this);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::DeleteLowLevel() {
// Log(" Newton body %d\n", (size_t)mpNewtonBody);
NewtonDestroyBody(mpNewtonWorld, mpNewtonBody);
// Log(" Callback\n");
hplDelete(mpCallback);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// CALLBACK METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsBodyNewtonCallback::OnTransformUpdate(iEntity3D *apEntity) {
if (cPhysicsBodyNewton::mbUseCallback == false)
return;
cPhysicsBodyNewton *pRigidBody = static_cast<cPhysicsBodyNewton *>(apEntity);
cMatrixf mTemp = apEntity->GetLocalMatrix().GetTranspose();
NewtonBodySetMatrix(pRigidBody->mpNewtonBody, mTemp.v);
if (pRigidBody->mpNode)
pRigidBody->mpNode->SetMatrix(apEntity->GetLocalMatrix());
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetMaterial(iPhysicsMaterial *apMaterial) {
mpMaterial = apMaterial;
if (apMaterial == nullptr)
return;
cPhysicsMaterialNewton *pNewtonMat = static_cast<cPhysicsMaterialNewton *>(mpMaterial);
NewtonBodySetMaterialGroupID(mpNewtonBody, pNewtonMat->GetId());
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetLinearVelocity(const cVector3f &avVel) {
VEC3_CONST_ARRAY(vel, avVel);
NewtonBodySetVelocity(mpNewtonBody, vel);
}
cVector3f cPhysicsBodyNewton::GetLinearVelocity() const {
float vel[3];
NewtonBodyGetVelocity(mpNewtonBody, vel);
return cVector3f::fromArray(vel);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetAngularVelocity(const cVector3f &avVel) {
VEC3_CONST_ARRAY(vel, avVel);
NewtonBodySetOmega(mpNewtonBody, vel);
}
cVector3f cPhysicsBodyNewton::GetAngularVelocity() const {
float vel[3];
NewtonBodyGetOmega(mpNewtonBody, vel);
return cVector3f::fromArray(vel);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetLinearDamping(float afDamping) {
NewtonBodySetLinearDamping(mpNewtonBody, afDamping);
}
float cPhysicsBodyNewton::GetLinearDamping() const {
return NewtonBodyGetLinearDamping(mpNewtonBody);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetAngularDamping(float afDamping) {
float damp[3] = {afDamping, afDamping, afDamping};
NewtonBodySetAngularDamping(mpNewtonBody, damp);
}
float cPhysicsBodyNewton::GetAngularDamping() const {
float fDamp[3];
NewtonBodyGetAngularDamping(mpNewtonBody, fDamp);
return fDamp[0];
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetMaxLinearSpeed(float afSpeed) {
mfMaxLinearSpeed = afSpeed;
}
float cPhysicsBodyNewton::GetMaxLinearSpeed() const {
return mfMaxLinearSpeed;
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetMaxAngularSpeed(float afDamping) {
mfMaxAngularSpeed = afDamping;
}
float cPhysicsBodyNewton::GetMaxAngularSpeed() const {
return mfMaxAngularSpeed;
}
//-----------------------------------------------------------------------
cMatrixf cPhysicsBodyNewton::GetInertiaMatrix() {
float fIxx, fIyy, fIzz, fMass;
NewtonBodyGetMassMatrix(mpNewtonBody, &fMass, &fIxx, &fIyy, &fIzz);
cMatrixf mtxRot = GetLocalMatrix().GetRotation();
cMatrixf mtxTransRot = mtxRot.GetTranspose();
cMatrixf mtxI(fIxx, 0, 0, 0,
0, fIyy, 0, 0,
0, 0, fIzz, 0,
0, 0, 0, 1);
return cMath::MatrixMul(cMath::MatrixMul(mtxRot, mtxI), mtxTransRot);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetMass(float afMass) {
cCollideShapeNewton *pShapeNewton = static_cast<cCollideShapeNewton *>(mpShape);
float inertia[3];
float offset[3];
NewtonConvexCollisionCalculateInertialMatrix(pShapeNewton->GetNewtonCollision(),
inertia, offset);
cVector3f vInertia = cVector3f::fromArray(inertia) * afMass; // = pShapeNewton->GetInertia(afMass);
NewtonBodySetCentreOfMass(mpNewtonBody, offset);
NewtonBodySetMassMatrix(mpNewtonBody, afMass, vInertia.x, vInertia.y, vInertia.z);
mfMass = afMass;
}
float cPhysicsBodyNewton::GetMass() const {
return mfMass;
}
void cPhysicsBodyNewton::SetMassCentre(const cVector3f &avCentre) {
VEC3_CONST_ARRAY(ctr, avCentre);
NewtonBodySetCentreOfMass(mpNewtonBody, ctr);
}
cVector3f cPhysicsBodyNewton::GetMassCentre() const {
float center[3];
NewtonBodyGetCentreOfMass(mpNewtonBody, center);
return cVector3f::fromArray(center);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::AddForce(const cVector3f &avForce) {
mvTotalForce += avForce;
SetEnabled(true);
// Log("Added force %s\n",avForce.ToString().c_str());
}
void cPhysicsBodyNewton::AddForceAtPosition(const cVector3f &avForce, const cVector3f &avPos) {
mvTotalForce += avForce;
cVector3f vLocalPos = avPos - GetLocalPosition();
cVector3f vMassCentre = GetMassCentre();
if (vMassCentre != cVector3f(0, 0, 0)) {
vMassCentre = cMath::MatrixMul(GetLocalMatrix().GetRotation(), vMassCentre);
vLocalPos -= vMassCentre;
}
cVector3f vTorque = cMath::Vector3Cross(vLocalPos, avForce);
mvTotalTorque += vTorque;
SetEnabled(true);
// Log("Added force %s\n",avForce.ToString().c_str());
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::AddTorque(const cVector3f &avTorque) {
mvTotalTorque += avTorque;
SetEnabled(true);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::AddImpulse(const cVector3f &avImpulse) {
cVector3f vMassCentre = GetMassCentre();
VEC3_CONST_ARRAY(impulse, avImpulse);
if (vMassCentre != cVector3f(0, 0, 0)) {
cVector3f vCentreOffset = cMath::MatrixMul(GetWorldMatrix().GetRotation(),
vMassCentre);
VEC3_CONST_ARRAY(worldPosition, (GetWorldPosition() + vCentreOffset));
NewtonBodyAddImpulse(mpNewtonBody, impulse, worldPosition);
} else {
VEC3_CONST_ARRAY(worldPosition, GetWorldPosition());
NewtonBodyAddImpulse(mpNewtonBody, impulse, worldPosition);
}
}
void cPhysicsBodyNewton::AddImpulseAtPosition(const cVector3f &avImpulse, const cVector3f &avPos) {
VEC3_CONST_ARRAY(impulse, avImpulse);
VEC3_CONST_ARRAY(pos, avPos);
NewtonBodyAddImpulse(mpNewtonBody, impulse, pos);
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetEnabled(bool abEnabled) {
NewtonBodySetFreezeState(mpNewtonBody, !abEnabled);
}
bool cPhysicsBodyNewton::GetEnabled() const {
return NewtonBodyGetSleepState(mpNewtonBody) == 0 ? false : true;
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetAutoDisable(bool abEnabled) {
NewtonBodySetAutoSleep(mpNewtonBody, abEnabled);
}
bool cPhysicsBodyNewton::GetAutoDisable() const {
return NewtonBodyGetAutoSleep(mpNewtonBody) == 0 ? false : true;
}
//-----------------------------------------------------------------------
#if 0
void cPhysicsBodyNewton::SetAutoDisableLinearThreshold(float afThresold) {
mfAutoDisableLinearThreshold = afThresold;
NewtonBodySetFreezeTreshold(mpNewtonBody, mfAutoDisableLinearThreshold,
mfAutoDisableAngularThreshold, mlAutoDisableNumSteps);
}
float cPhysicsBodyNewton::GetAutoDisableLinearThreshold() const {
return mfAutoDisableLinearThreshold;
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetAutoDisableAngularThreshold(float afThresold) {
mfAutoDisableAngularThreshold = afThresold;
NewtonBodySetFreezeTreshold(mpNewtonBody, mfAutoDisableLinearThreshold,
mfAutoDisableAngularThreshold, mlAutoDisableNumSteps);
}
float cPhysicsBodyNewton::GetAutoDisableAngularThreshold() const {
return mfAutoDisableAngularThreshold;
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetAutoDisableNumSteps(int anNum) {
mlAutoDisableNumSteps = anNum;
NewtonBodySetFreezeTreshold(mpNewtonBody, mfAutoDisableLinearThreshold,
mfAutoDisableAngularThreshold, mlAutoDisableNumSteps);
}
int cPhysicsBodyNewton::GetAutoDisableNumSteps() const {
return mlAutoDisableNumSteps;
}
#endif
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetContinuousCollision(bool abOn) {
NewtonBodySetContinuousCollisionMode(mpNewtonBody, abOn ? 1 : 0);
}
bool cPhysicsBodyNewton::GetContinuousCollision() {
return NewtonBodyGetContinuousCollisionMode(mpNewtonBody) == 1 ? true : false;
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::SetGravity(bool abEnabled) {
mbGravity = abEnabled;
}
bool cPhysicsBodyNewton::GetGravity() const {
return mbGravity;
}
//-----------------------------------------------------------------------
struct DrawParameters {
iLowLevelGraphics *lowLevelGraphics;
cColor drawColor;
};
///////////////////////////////////////////
static void RenderDebugPolygon(void *params, int alVertexCount, const dFloat *apFaceVertex, int alId) {
int i = alVertexCount - 1;
const DrawParameters *drawParams = static_cast<DrawParameters *>(params);
cVector3f vP0(apFaceVertex[i * 3 + 0], apFaceVertex[i * 3 + 1], apFaceVertex[i * 3 + 2]);
for (i = 0; i < alVertexCount; ++i) {
cVector3f vP1(apFaceVertex[i * 3 + 0], apFaceVertex[i * 3 + 1], apFaceVertex[i * 3 + 2]);
drawParams->lowLevelGraphics->DrawLine(vP0, vP1, drawParams->drawColor);
vP0 = vP1;
}
}
////////////////////////////////////////////
void cPhysicsBodyNewton::RenderDebugGeometry(iLowLevelGraphics *apLowLevel, const cColor &aColor) {
DrawParameters params{apLowLevel, aColor};
NewtonCollisionForEachPolygonDo(NewtonBodyGetCollision(mpNewtonBody), GetLocalMatrix().GetTranspose().v, RenderDebugPolygon, static_cast<void *>(&params));
}
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::ClearForces() {
mvTotalForce = cVector3f(0, 0, 0);
mvTotalTorque = cVector3f(0, 0, 0);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// STATIC NEWTON CALLBACKS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsBodyNewton::OnTransformCallback(const NewtonBody *apBody, const dFloat *apMatrix, int32) {
cPhysicsBodyNewton *pRigidBody = (cPhysicsBodyNewton *)NewtonBodyGetUserData(apBody);
pRigidBody->m_mtxLocalTransform.FromTranspose(apMatrix);
mbUseCallback = false;
pRigidBody->SetTransformUpdated(true);
mbUseCallback = true;
if (pRigidBody->mpNode)
pRigidBody->mpNode->SetMatrix(pRigidBody->m_mtxLocalTransform);
}
//-----------------------------------------------------------------------
int cPhysicsBodyNewton::BuoyancyPlaneCallback(const int32 alCollisionID, void *apContext,
const float *afGlobalSpaceMatrix, float *afGlobalSpacePlane) {
cPlanef surfacePlane = static_cast<cPhysicsBodyNewton *>(apContext)->mBuoyancy.mSurface;
afGlobalSpacePlane[0] = surfacePlane.a;
afGlobalSpacePlane[1] = surfacePlane.b;
afGlobalSpacePlane[2] = surfacePlane.c;
afGlobalSpacePlane[3] = surfacePlane.d;
return 1;
}
void cPhysicsBodyNewton::OnUpdateCallback(NewtonBody *apBody, float, int32) {
float fMass;
float fX, fY, fZ;
cPhysicsBodyNewton *pRigidBody = (cPhysicsBodyNewton *)NewtonBodyGetUserData(apBody);
if (pRigidBody->IsActive() == false)
return;
cVector3f vGravity = pRigidBody->mpWorld->GetGravity();
// Create some gravity
if (pRigidBody->mbGravity) {
NewtonBodyGetMassMatrix(apBody, &fMass, &fX, &fY, &fZ);
VEC3_CONST_ARRAY(force, (vGravity * fMass));
NewtonBodyAddForce(apBody, force);
}
// Create Buoyancy
if (pRigidBody->mBuoyancy.mbActive) {
VEC3_CONST_ARRAY(gravity, vGravity);
NewtonBodyAddBuoyancyForce(apBody,
pRigidBody->mBuoyancy.mfDensity,
pRigidBody->mBuoyancy.mfLinearViscosity,
pRigidBody->mBuoyancy.mfAngularViscosity,
gravity, BuoyancyPlaneCallback,
pRigidBody);
}
// Add forces from calls to Addforce(..), etc
VEC3_CONST_ARRAY(totForce, pRigidBody->mvTotalForce);
NewtonBodyAddForce(apBody, totForce);
VEC3_CONST_ARRAY(totTorque, pRigidBody->mvTotalTorque);
NewtonBodyAddTorque(apBody, totTorque);
// Check so that all speeds are within thresholds
// Linear
if (pRigidBody->mfMaxLinearSpeed > 0) {
cVector3f vVel = pRigidBody->GetLinearVelocity();
float fSpeed = vVel.Length();
if (fSpeed > pRigidBody->mfMaxLinearSpeed) {
vVel = cMath::Vector3Normalize(vVel) * pRigidBody->mfMaxLinearSpeed;
pRigidBody->SetLinearVelocity(vVel);
}
}
// Angular
if (pRigidBody->mfMaxAngularSpeed > 0) {
cVector3f vVel = pRigidBody->GetAngularVelocity();
float fSpeed = vVel.Length();
if (fSpeed > pRigidBody->mfMaxAngularSpeed) {
vVel = cMath::Vector3Normalize(vVel) * pRigidBody->mfMaxAngularSpeed;
pRigidBody->SetAngularVelocity(vVel);
}
}
// cVector3f vForce;
// NewtonBodyGetForce(apBody,vForce.v);
// Log("Engine force %s\n",pRigidBody->mvTotalForce.ToString().c_str());
// Log("Engine force %s, body force: %s \n",pRigidBody->mvTotalForce.ToString().c_str(),
// vForce.ToString().c_str());
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,134 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_BODY_NEWTON_H
#define HPL_PHYSICS_BODY_NEWTON_H
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/physics/PhysicsBody.h"
namespace hpl {
class cPhysicsBodyNewtonCallback : public iEntityCallback {
void OnTransformUpdate(iEntity3D *apEntity);
};
class cPhysicsBodyNewton : public iPhysicsBody {
friend class cPhysicsBodyNewtonCallback;
public:
cPhysicsBodyNewton(const tString &asName, iPhysicsWorld *apWorld, iCollideShape *apShape);
~cPhysicsBodyNewton();
void SetMaterial(iPhysicsMaterial *apMaterial);
void SetLinearVelocity(const cVector3f &avVel);
cVector3f GetLinearVelocity() const;
void SetAngularVelocity(const cVector3f &avVel);
cVector3f GetAngularVelocity() const;
void SetLinearDamping(float afDamping);
float GetLinearDamping() const;
void SetAngularDamping(float afDamping);
float GetAngularDamping() const;
void SetMaxLinearSpeed(float afSpeed);
float GetMaxLinearSpeed() const;
void SetMaxAngularSpeed(float afDamping);
float GetMaxAngularSpeed() const;
cMatrixf GetInertiaMatrix();
void SetMass(float afMass);
float GetMass() const;
void SetMassCentre(const cVector3f &avCentre);
cVector3f GetMassCentre() const;
void AddForce(const cVector3f &avForce);
void AddForceAtPosition(const cVector3f &avForce, const cVector3f &avPos);
void AddTorque(const cVector3f &avTorque);
void AddImpulse(const cVector3f &avImpulse);
void AddImpulseAtPosition(const cVector3f &avImpulse, const cVector3f &avPos);
void SetEnabled(bool abEnabled);
bool GetEnabled() const;
void SetAutoDisable(bool abEnabled);
bool GetAutoDisable() const;
#if 0
void SetAutoDisableLinearThreshold(float afThresold);
float GetAutoDisableLinearThreshold() const;
void SetAutoDisableAngularThreshold(float afThresold);
float GetAutoDisableAngularThreshold() const;
void SetAutoDisableNumSteps(int alNum);
int GetAutoDisableNumSteps() const;
#endif
void SetContinuousCollision(bool abOn);
bool GetContinuousCollision();
void SetGravity(bool abEnabled);
bool GetGravity() const;
void RenderDebugGeometry(iLowLevelGraphics *apLowLevel, const cColor &aColor);
NewtonBody *GetNewtonBody() { return mpNewtonBody; }
void ClearForces();
void DeleteLowLevel();
static void SetUseCallback(bool abX) { mbUseCallback = abX; }
private:
static int BuoyancyPlaneCallback(const int32 alCollisionID, void *apContext,
const float *afGlobalSpaceMatrix, float *afGlobalSpacePlane);
static void OnTransformCallback(const NewtonBody *apBody, const dFloat *apMatrix, int32);
static void OnUpdateCallback(NewtonBody *apBody, float, int32);
NewtonBody *mpNewtonBody;
NewtonWorld *mpNewtonWorld;
cPhysicsBodyNewtonCallback *mpCallback;
static bool mbUseCallback;
// Properties
bool mbGravity;
float mfMaxLinearSpeed;
float mfMaxAngularSpeed;
float mfMass;
float mfAutoDisableLinearThreshold;
float mfAutoDisableAngularThreshold;
int mlAutoDisableNumSteps;
// Forces that will be set and clear on update callback
cVector3f mvTotalForce;
cVector3f mvTotalTorque;
};
} // namespace hpl
#endif // HPL_PHYSICS_BODY_NEWTON_H

View File

@@ -0,0 +1,62 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsControllerNewton.h"
#include "hpl1/engine/physics/PhysicsBody.h"
#include "hpl1/engine/physics/PhysicsWorld.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsControllerNewton::cPhysicsControllerNewton(const tString &asName, iPhysicsWorld *apWorld)
: iPhysicsController(asName, apWorld) {
}
//-----------------------------------------------------------------------
cPhysicsControllerNewton::~cPhysicsControllerNewton() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,45 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_CONTROLLER_NEWTON_H
#define HPL_PHYSICS_CONTROLLER_NEWTON_H
#include "hpl1/engine/physics/PhysicsController.h"
namespace hpl {
class iPhysicsWorld;
class cPhysicsControllerNewton : public iPhysicsController {
public:
cPhysicsControllerNewton(const tString &asName, iPhysicsWorld *apWorld);
~cPhysicsControllerNewton();
};
} // namespace hpl
#endif // HPL_PHYSICS_CONTROLLER_NEWTON_H

View File

@@ -0,0 +1,114 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsJointBallNewton.h"
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/math/Vector3.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsJointBallNewton::cPhysicsJointBallNewton(const tString &asName,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint)
: iPhysicsJointNewton<iPhysicsJointBall>(asName, apParentBody, apChildBody, apWorld, avPivotPoint) {
VEC3_CONST_ARRAY(pivotPint, avPivotPoint);
mpNewtonJoint = NewtonConstraintCreateBall(mpNewtonWorld, pivotPint,
mpNewtonChildBody, mpNewtonParentBody);
mvPinDir = cVector3f(0, 0, 0);
mvPivotPoint = avPivotPoint;
mfMaxConeAngle = 0;
mfMaxTwistAngle = 0;
mvConePin = mvPinDir;
}
//-----------------------------------------------------------------------
cPhysicsJointBallNewton::~cPhysicsJointBallNewton() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsJointBallNewton::SetConeLimits(const cVector3f &avPin, float afMaxConeAngle, float afMaxTwistAngle) {
VEC3_CONST_ARRAY(pin, avPin);
NewtonBallSetConeLimits(mpNewtonJoint, pin, afMaxConeAngle, afMaxTwistAngle);
mvConePin = avPin;
mvPinDir = mvConePin;
mfMaxConeAngle = afMaxConeAngle;
mfMaxTwistAngle = afMaxTwistAngle;
}
cVector3f cPhysicsJointBallNewton::GetAngles() {
float angles[3];
NewtonBallGetJointAngle(mpNewtonJoint, angles);
return cVector3f::fromArray(angles);
}
//-----------------------------------------------------------------------
cVector3f cPhysicsJointBallNewton::GetVelocity() {
return cVector3f(0, 0, 0);
}
cVector3f cPhysicsJointBallNewton::GetAngularVelocity() {
float vel[3];
NewtonBallGetJointOmega(mpNewtonJoint, vel);
return cVector3f::fromArray(vel);
}
cVector3f cPhysicsJointBallNewton::GetForce() {
float force[3];
NewtonBallGetJointForce(mpNewtonJoint, force);
return cVector3f::fromArray(force);
}
//-----------------------------------------------------------------------
float cPhysicsJointBallNewton::GetDistance() {
return 0;
}
float cPhysicsJointBallNewton::GetAngle() {
return 0;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,57 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_JOINT_BALL_NEWTON_H
#define HPL_PHYSICS_JOINT_BALL_NEWTON_H
#include "hpl1/engine/impl/PhysicsJointNewton.h"
#include "hpl1/engine/physics/PhysicsJointBall.h"
namespace hpl {
class cPhysicsJointBallNewton : public iPhysicsJointNewton<iPhysicsJointBall> {
public:
cPhysicsJointBallNewton(const tString &asName, iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint);
~cPhysicsJointBallNewton();
void SetConeLimits(const cVector3f &avPin, float afMaxConeAngle, float afMaxTwistAngle);
cVector3f GetAngles();
cVector3f GetVelocity();
cVector3f GetAngularVelocity();
cVector3f GetForce();
float GetDistance();
float GetAngle();
private:
};
} // namespace hpl
#endif // HPL_PHYSICS_JOINT_BALL_NEWTON_H

View File

@@ -0,0 +1,181 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsJointHingeNewton.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/math/Math.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsJointHingeNewton::cPhysicsJointHingeNewton(const tString &asName,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint, const cVector3f avPinDir)
: iPhysicsJointNewton<iPhysicsJointHinge>(asName, apParentBody, apChildBody, apWorld, avPivotPoint) {
const float fPivotPoint[3] = {avPivotPoint.x, avPivotPoint.y, avPivotPoint.z};
const float fPinDir[3] = {avPinDir.x, avPinDir.y, avPinDir.z};
mpNewtonJoint = NewtonConstraintCreateHinge(mpNewtonWorld, fPivotPoint, fPinDir,
mpNewtonChildBody, mpNewtonParentBody);
// Add callback and user data.
NewtonJointSetUserData(mpNewtonJoint, (void *)this);
NewtonHingeSetUserCallback(mpNewtonJoint, LimitCallback);
mvPinDir = avPinDir;
mvPivotPoint = avPivotPoint;
mfMaxAngle = 0;
mfMinAngle = 0;
mfPreviousAngle = 0;
}
//-----------------------------------------------------------------------
cPhysicsJointHingeNewton::~cPhysicsJointHingeNewton() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsJointHingeNewton::SetMaxAngle(float afAngle) {
mfMaxAngle = afAngle;
}
void cPhysicsJointHingeNewton::SetMinAngle(float afAngle) {
mfMinAngle = afAngle;
}
float cPhysicsJointHingeNewton::GetMaxAngle() {
return mfMaxAngle;
}
float cPhysicsJointHingeNewton::GetMinAngle() {
return mfMinAngle;
}
//-----------------------------------------------------------------------
cVector3f cPhysicsJointHingeNewton::GetVelocity() {
return cVector3f(0, 0, 0);
}
cVector3f cPhysicsJointHingeNewton::GetAngularVelocity() {
float fSpeed = NewtonHingeGetJointOmega(mpNewtonJoint);
return mvPinDir * fSpeed;
}
cVector3f cPhysicsJointHingeNewton::GetForce() {
cVector3f vForce;
NewtonHingeGetJointForce(mpNewtonJoint, &vForce.x);
return vForce;
}
//-----------------------------------------------------------------------
float cPhysicsJointHingeNewton::GetDistance() {
return 0;
}
float cPhysicsJointHingeNewton::GetAngle() {
return NewtonHingeGetJointAngle(mpNewtonJoint);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// STATIC CALLBACKS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
unsigned cPhysicsJointHingeNewton::LimitCallback(const NewtonJoint *pHinge, NewtonHingeSliderUpdateDesc *pDesc) {
cPhysicsJointHingeNewton *pHingeJoint = (cPhysicsJointHingeNewton *)NewtonJointGetUserData(pHinge);
// pHingeJoint->OnPhysicsUpdate();
if (pHingeJoint->mfMaxAngle == 0 && pHingeJoint->mfMinAngle == 0)
return 0;
float fAngle = NewtonHingeGetJointAngle(pHinge);
// Avoid oscillation
CheckLimitAutoSleep(pHingeJoint, pHingeJoint->mfMinAngle, pHingeJoint->mfMaxAngle, fAngle);
bool bSkipLimitCheck = false;
if (fabs(pHingeJoint->mfPreviousAngle - fAngle) > cMath::ToRad(300))
bSkipLimitCheck = true;
// Max limit
if (fAngle > pHingeJoint->mfMaxAngle && bSkipLimitCheck == false) {
pHingeJoint->OnMaxLimit();
pDesc->m_accel = NewtonHingeCalculateStopAlpha(pHinge, pDesc, pHingeJoint->mfMaxAngle);
pDesc->m_maxFriction = 0;
pHingeJoint->mfPreviousAngle = fAngle;
return 1;
}
// Min limit
else if (fAngle < pHingeJoint->mfMinAngle && bSkipLimitCheck == false) {
pHingeJoint->OnMinLimit();
pDesc->m_accel = NewtonHingeCalculateStopAlpha(pHinge, pDesc, pHingeJoint->mfMinAngle);
pDesc->m_minFriction = 0;
pHingeJoint->mfPreviousAngle = fAngle;
return 1;
} else {
if (pHingeJoint->mpParentBody == NULL || pHingeJoint->mpParentBody->GetMass() == 0) {
if ((pHingeJoint->mfStickyMaxDistance != 0 &&
fabs(fAngle - pHingeJoint->mfMaxAngle) < pHingeJoint->mfStickyMaxDistance) ||
(pHingeJoint->mfStickyMinDistance != 0 &&
fabs(fAngle - pHingeJoint->mfMinAngle) < pHingeJoint->mfStickyMinDistance)) {
pHingeJoint->mpChildBody->SetAngularVelocity(0);
pHingeJoint->mpChildBody->SetLinearVelocity(0);
}
}
pHingeJoint->OnNoLimit();
}
pHingeJoint->mfPreviousAngle = fAngle;
return 0;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,61 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_JOINT_HINGE_NEWTON_H
#define HPL_PHYSICS_JOINT_HINGE_NEWTON_H
#include "hpl1/engine/impl/PhysicsJointNewton.h"
#include "hpl1/engine/physics/PhysicsJointHinge.h"
namespace hpl {
class cPhysicsJointHingeNewton : public iPhysicsJointNewton<iPhysicsJointHinge> {
public:
cPhysicsJointHingeNewton(const tString &asName, iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint, const cVector3f avPinDir);
~cPhysicsJointHingeNewton();
void SetMaxAngle(float afAngle);
void SetMinAngle(float afAngle);
float GetMaxAngle();
float GetMinAngle();
cVector3f GetVelocity();
cVector3f GetAngularVelocity();
cVector3f GetForce();
float GetDistance();
float GetAngle();
private:
float mfPreviousAngle;
static unsigned LimitCallback(const NewtonJoint *pHinge, NewtonHingeSliderUpdateDesc *pDesc);
};
} // namespace hpl
#endif // HPL_PHYSICS_JOINT_HINGE_NEWTON_H

View File

@@ -0,0 +1,97 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_JOINT_NEWTON_H
#define HPL_PHYSICS_JOINT_NEWTON_H
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
template<typename T>
class iPhysicsJointNewton : public T {
public:
iPhysicsJointNewton(const tString &asName, iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint)
: T(asName, apParentBody, apChildBody, apWorld, avPivotPoint) {
cPhysicsWorldNewton *pNWorld = static_cast<cPhysicsWorldNewton *>(apWorld);
mpNewtonWorld = pNWorld->GetNewtonWorld();
cPhysicsBodyNewton *pNParent = static_cast<cPhysicsBodyNewton *>(apParentBody);
cPhysicsBodyNewton *pNChild = static_cast<cPhysicsBodyNewton *>(apChildBody);
if (apParentBody == NULL)
mpNewtonParentBody = NULL;
else
mpNewtonParentBody = pNParent->GetNewtonBody();
mpNewtonChildBody = pNChild->GetNewtonBody();
}
virtual ~iPhysicsJointNewton() {
// Skip this for now and let newton handle it..
// Log("Destroying newton joint!\n");
if (this->mpChildBody || this->mpParentBody)
NewtonDestroyJoint(mpNewtonWorld, mpNewtonJoint);
}
///////////////////////
void SetCollideBodies(bool abX) {
NewtonJointSetCollisionState(mpNewtonJoint, abX ? 1 : 0);
}
bool GetCollideBodies() {
return NewtonJointGetCollisionState(mpNewtonJoint) == 0 ? false : true;
}
///////////////////////
void SetStiffness(float afX) {
NewtonJointSetStiffness(mpNewtonJoint, afX);
}
float GetStiffness() {
return NewtonJointGetStiffness(mpNewtonJoint);
}
///////////////////////
protected:
NewtonJoint *mpNewtonJoint;
NewtonWorld *mpNewtonWorld;
NewtonBody *mpNewtonParentBody;
NewtonBody *mpNewtonChildBody;
};
} // namespace hpl
#endif // HPL_PHYSICS_JOINT_NEWTON_H

View File

@@ -0,0 +1,165 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsJointScrewNewton.h"
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/math/Vector3.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsJointScrewNewton::cPhysicsJointScrewNewton(const tString &asName,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint, const cVector3f avPinDir)
: iPhysicsJointNewton<iPhysicsJointScrew>(asName, apParentBody, apChildBody, apWorld, avPivotPoint) {
mvPin = avPinDir;
mvPin.Normalise();
VEC3_CONST_ARRAY(pvPoint, avPivotPoint);
VEC3_CONST_ARRAY(pDir, avPinDir);
mpNewtonJoint = NewtonConstraintCreateCorkscrew(mpNewtonWorld, pvPoint, pDir, mpNewtonChildBody,
mpNewtonParentBody);
NewtonJointSetUserData(mpNewtonJoint, (void *)this);
NewtonCorkscrewSetUserCallback(mpNewtonJoint, LimitCallback);
mfMaxDistance = 0;
mfMinDistance = 0;
mvPinDir = avPinDir;
mvPivotPoint = avPivotPoint;
}
//-----------------------------------------------------------------------
cPhysicsJointScrewNewton::~cPhysicsJointScrewNewton() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsJointScrewNewton::SetMaxDistance(float afX) {
mfMaxDistance = afX;
}
void cPhysicsJointScrewNewton::SetMinDistance(float afX) {
mfMinDistance = afX;
}
float cPhysicsJointScrewNewton::GetMaxDistance() {
return mfMaxDistance;
}
float cPhysicsJointScrewNewton::GetMinDistance() {
return mfMinDistance;
}
//-----------------------------------------------------------------------
cVector3f cPhysicsJointScrewNewton::GetVelocity() {
float fSpeed = NewtonCorkscrewGetJointVeloc(mpNewtonJoint);
return mvPin * fSpeed;
}
cVector3f cPhysicsJointScrewNewton::GetAngularVelocity() {
return cVector3f(0, 0, 0);
}
cVector3f cPhysicsJointScrewNewton::GetForce() {
cVector3f vForce;
NewtonCorkscrewGetJointForce(mpNewtonJoint, &vForce.x);
return vForce;
}
//-----------------------------------------------------------------------
float cPhysicsJointScrewNewton::GetDistance() {
return NewtonCorkscrewGetJointPosit(mpNewtonJoint);
}
float cPhysicsJointScrewNewton::GetAngle() {
return NewtonCorkscrewGetJointAngle(mpNewtonJoint);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// STATIC CALLBACKS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
unsigned cPhysicsJointScrewNewton::LimitCallback(const NewtonJoint *pScrew, NewtonHingeSliderUpdateDesc *pDesc) {
cPhysicsJointScrewNewton *pScrewJoint = (cPhysicsJointScrewNewton *)NewtonJointGetUserData(pScrew);
// pScrewJoint->OnPhysicsUpdate();
float fDistance = NewtonCorkscrewGetJointPosit(pScrew);
// Log("Dist: %f\n",fDistance);
if (pScrewJoint->mfMinDistance == 0 && pScrewJoint->mfMaxDistance == 0)
return 0;
// Avoid oscillation
CheckLimitAutoSleep(pScrewJoint, pScrewJoint->mfMinDistance, pScrewJoint->mfMaxDistance, fDistance);
if (fDistance < pScrewJoint->mfMinDistance) {
pScrewJoint->OnMinLimit();
pDesc->m_accel = NewtonCorkscrewCalculateStopAccel(pScrew, pDesc, pScrewJoint->mfMinDistance);
pDesc->m_minFriction = 0;
return 1;
} else if (fDistance > pScrewJoint->mfMaxDistance) {
pScrewJoint->OnMaxLimit();
pDesc->m_accel = NewtonCorkscrewCalculateStopAccel(pScrew, pDesc, pScrewJoint->mfMaxDistance);
pDesc->m_maxFriction = 0;
return 1;
} else {
if (pScrewJoint->mpParentBody == NULL || pScrewJoint->mpParentBody->GetMass() == 0) {
if ((pScrewJoint->mfStickyMaxDistance != 0 &&
fabs(fDistance - pScrewJoint->mfMaxDistance) < pScrewJoint->mfStickyMaxDistance) ||
(pScrewJoint->mfStickyMinDistance != 0 &&
fabs(fDistance - pScrewJoint->mfMinDistance) < pScrewJoint->mfStickyMinDistance)) {
pScrewJoint->mpChildBody->SetAngularVelocity(0);
pScrewJoint->mpChildBody->SetLinearVelocity(0);
}
}
pScrewJoint->OnNoLimit();
}
return 0;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,60 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_JOINT_SCREW_NEWTON_H
#define HPL_PHYSICS_JOINT_SCREW_NEWTON_H
#include "hpl1/engine/impl/PhysicsJointNewton.h"
#include "hpl1/engine/physics/PhysicsJointScrew.h"
namespace hpl {
class cPhysicsJointScrewNewton : public iPhysicsJointNewton<iPhysicsJointScrew> {
public:
cPhysicsJointScrewNewton(const tString &asName, iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint, const cVector3f avPinDir);
~cPhysicsJointScrewNewton();
void SetMaxDistance(float afX);
void SetMinDistance(float afX);
float GetMaxDistance();
float GetMinDistance();
cVector3f GetVelocity();
cVector3f GetAngularVelocity();
cVector3f GetForce();
float GetDistance();
float GetAngle();
private:
static unsigned LimitCallback(const NewtonJoint *pSlider, NewtonHingeSliderUpdateDesc *pDesc);
};
} // namespace hpl
#endif // HPL_PHYSICS_JOINT_SCREW_NEWTON_H

View File

@@ -0,0 +1,178 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsJointSliderNewton.h"
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "common/str.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsJointSliderNewton::cPhysicsJointSliderNewton(const tString &asName,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint, const cVector3f avPinDir)
: iPhysicsJointNewton<iPhysicsJointSlider>(asName, apParentBody, apChildBody, apWorld, avPivotPoint) {
mvPin = avPinDir;
mvPin.Normalise();
const float fPivotPoint[3] = {avPivotPoint.x, avPivotPoint.y, avPivotPoint.z};
const float fPinDir[3] = {avPinDir.x, avPinDir.y, avPinDir.z};
mpNewtonJoint = NewtonConstraintCreateSlider(mpNewtonWorld, fPivotPoint, fPinDir, mpNewtonChildBody,
mpNewtonParentBody);
NewtonJointSetUserData(mpNewtonJoint, (void *)this);
NewtonSliderSetUserCallback(mpNewtonJoint, LimitCallback);
mfMaxDistance = 0;
mfMinDistance = 0;
mvPinDir = avPinDir;
mvPivotPoint = avPivotPoint;
}
//-----------------------------------------------------------------------
cPhysicsJointSliderNewton::~cPhysicsJointSliderNewton() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsJointSliderNewton::SetMaxDistance(float afX) {
mfMaxDistance = afX;
// fixes a problem with the crane in level 11 (new storage room) not updating
// after the the limits have been changed, preventing it from moving
if (mpChildBody && Common::String(msName.c_str()).contains("crane"))
mpChildBody->AddImpulse({0.001f, 0.001f, 0.001f});
}
void cPhysicsJointSliderNewton::SetMinDistance(float afX) {
mfMinDistance = afX;
}
float cPhysicsJointSliderNewton::GetMaxDistance() {
return mfMaxDistance;
}
float cPhysicsJointSliderNewton::GetMinDistance() {
return mfMinDistance;
}
//-----------------------------------------------------------------------
cVector3f cPhysicsJointSliderNewton::GetVelocity() {
float fSpeed = NewtonSliderGetJointVeloc(mpNewtonJoint);
return mvPin * fSpeed;
}
cVector3f cPhysicsJointSliderNewton::GetAngularVelocity() {
return cVector3f(0, 0, 0);
}
cVector3f cPhysicsJointSliderNewton::GetForce() {
cVector3f vForce;
NewtonSliderGetJointForce(mpNewtonJoint, &vForce.x);
return vForce;
}
//-----------------------------------------------------------------------
float cPhysicsJointSliderNewton::GetDistance() {
return NewtonSliderGetJointPosit(mpNewtonJoint);
}
float cPhysicsJointSliderNewton::GetAngle() {
return 0;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// STATIC CALLBACKS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
unsigned cPhysicsJointSliderNewton::LimitCallback(const NewtonJoint *pSlider, NewtonHingeSliderUpdateDesc *pDesc) {
cPhysicsJointSliderNewton *pSliderJoint = (cPhysicsJointSliderNewton *)NewtonJointGetUserData(pSlider);
// pSliderJoint->OnPhysicsUpdate();
float fDistance = NewtonSliderGetJointPosit(pSlider);
// Log("Dist: %f\n",fDistance);
if (pSliderJoint->mfMinDistance == 0 && pSliderJoint->mfMaxDistance == 0)
return 0;
// Avoid oscillation
CheckLimitAutoSleep(pSliderJoint, pSliderJoint->mfMinDistance, pSliderJoint->mfMaxDistance, fDistance);
if (fDistance < pSliderJoint->mfMinDistance) {
pSliderJoint->OnMinLimit();
pDesc->m_accel = NewtonSliderCalculateStopAccel(pSlider, pDesc, pSliderJoint->mfMinDistance);
pDesc->m_minFriction = 0;
// Log("Under Min. Acc: %f Dist %f\n",pDesc->m_accel,fDistance);
return 1;
} else if (fDistance > pSliderJoint->mfMaxDistance) {
pSliderJoint->OnMaxLimit();
pDesc->m_accel = NewtonSliderCalculateStopAccel(pSlider, pDesc, pSliderJoint->mfMaxDistance);
pDesc->m_maxFriction = 0;
// Log("Over Max. Acc: %f Dist %f\n",pDesc->m_accel,fDistance);
return 1;
} else {
if (pSliderJoint->mpParentBody == NULL || pSliderJoint->mpParentBody->GetMass() == 0) {
if ((pSliderJoint->mfStickyMaxDistance != 0 &&
fabs(fDistance - pSliderJoint->mfMaxDistance) < pSliderJoint->mfStickyMaxDistance) ||
(pSliderJoint->mfStickyMinDistance != 0 &&
fabs(fDistance - pSliderJoint->mfMinDistance) < pSliderJoint->mfStickyMinDistance)) {
pSliderJoint->mpChildBody->SetAngularVelocity(0);
pSliderJoint->mpChildBody->SetLinearVelocity(0);
}
}
pSliderJoint->OnNoLimit();
}
// Log("Nothing, Dist %f\n",fDistance);
return 0;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,60 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_JOINT_SLIDER_NEWTON_H
#define HPL_PHYSICS_JOINT_SLIDER_NEWTON_H
#include "hpl1/engine/impl/PhysicsJointNewton.h"
#include "hpl1/engine/physics/PhysicsJointSlider.h"
namespace hpl {
class cPhysicsJointSliderNewton : public iPhysicsJointNewton<iPhysicsJointSlider> {
public:
cPhysicsJointSliderNewton(const tString &asName, iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint, const cVector3f avPinDir);
~cPhysicsJointSliderNewton();
void SetMaxDistance(float afX);
void SetMinDistance(float afX);
float GetMaxDistance();
float GetMinDistance();
cVector3f GetVelocity();
cVector3f GetAngularVelocity();
cVector3f GetForce();
float GetDistance();
float GetAngle();
private:
static unsigned LimitCallback(const NewtonJoint *pSlider, NewtonHingeSliderUpdateDesc *pDesc);
};
} // namespace hpl
#endif // HPL_PHYSICS_JOINT_SLIDER_NEWTON_H

View File

@@ -0,0 +1,358 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsMaterialNewton.h"
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/physics/PhysicsMaterial.h"
#include "hpl1/engine/physics/SurfaceData.h"
#include "common/util.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsMaterialNewton::cPhysicsMaterialNewton(const tString &asName, iPhysicsWorld *apWorld, int alMatId)
: iPhysicsMaterial(asName, apWorld) {
cPhysicsWorldNewton *pNWorld = static_cast<cPhysicsWorldNewton *>(mpWorld);
mpNewtonWorld = pNWorld->GetNewtonWorld();
if (alMatId == -1) {
mlMaterialId = NewtonMaterialCreateGroupID(mpNewtonWorld);
} else {
mlMaterialId = alMatId;
}
// Setup default properties
mFrictionMode = ePhysicsMaterialCombMode_Average;
mElasticityMode = ePhysicsMaterialCombMode_Average;
mfElasticity = 0.5f;
mfStaticFriction = 0.3f;
mfKineticFriction = 0.3f;
// Log(" Created physics material '%s' with Newton id %d\n",asName.c_str(),mlMaterialId);
}
//-----------------------------------------------------------------------
cPhysicsMaterialNewton::~cPhysicsMaterialNewton() {
/*Might be just as well to let newton handle this*/
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsMaterialNewton::SetElasticity(float afElasticity) {
mfElasticity = afElasticity;
UpdateMaterials();
}
float cPhysicsMaterialNewton::GetElasticity() const {
return mfElasticity;
}
//-----------------------------------------------------------------------
void cPhysicsMaterialNewton::SetStaticFriction(float afElasticity) {
mfStaticFriction = afElasticity;
UpdateMaterials();
}
float cPhysicsMaterialNewton::GetStaticFriction() const {
return mfStaticFriction;
}
//-----------------------------------------------------------------------
void cPhysicsMaterialNewton::SetKineticFriction(float afElasticity) {
mfKineticFriction = afElasticity;
UpdateMaterials();
}
float cPhysicsMaterialNewton::GetKineticFriction() const {
return mfKineticFriction;
}
//-----------------------------------------------------------------------
void cPhysicsMaterialNewton::SetFrictionCombMode(ePhysicsMaterialCombMode aMode) {
mFrictionMode = aMode;
UpdateMaterials();
}
ePhysicsMaterialCombMode cPhysicsMaterialNewton::GetFrictionCombMode() const {
return mFrictionMode;
}
//-----------------------------------------------------------------------
void cPhysicsMaterialNewton::SetElasticityCombMode(ePhysicsMaterialCombMode aMode) {
mElasticityMode = aMode;
UpdateMaterials();
}
//-----------------------------------------------------------------------
ePhysicsMaterialCombMode cPhysicsMaterialNewton::GetElasticityCombMode() const {
return mElasticityMode;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsMaterialNewton::UpdateMaterials() {
cPhysicsMaterialIterator MatIt = mpWorld->GetMaterialIterator();
while (MatIt.HasNext()) {
cPhysicsMaterialNewton *pMat = static_cast<cPhysicsMaterialNewton *>(MatIt.Next());
ePhysicsMaterialCombMode frictionMode = (ePhysicsMaterialCombMode)MAX(mFrictionMode,
pMat->mFrictionMode);
ePhysicsMaterialCombMode elasticityMode = (ePhysicsMaterialCombMode)MAX(mElasticityMode,
pMat->mElasticityMode);
// If the material is the same do not blend.
if (pMat == this) {
frictionMode = ePhysicsMaterialCombMode_Average;
elasticityMode = ePhysicsMaterialCombMode_Average;
}
NewtonMaterialSetDefaultElasticity(mpNewtonWorld, mlMaterialId, pMat->mlMaterialId,
Combine(elasticityMode, mfElasticity, pMat->mfElasticity));
NewtonMaterialSetDefaultFriction(mpNewtonWorld, mlMaterialId, pMat->mlMaterialId,
Combine(frictionMode, mfStaticFriction, pMat->mfStaticFriction),
Combine(frictionMode, mfKineticFriction, pMat->mfKineticFriction));
NewtonMaterialSetContinuousCollisionMode(mpNewtonWorld, mlMaterialId, pMat->mlMaterialId,
1);
NewtonMaterialSetCollisionCallback(mpNewtonWorld, mlMaterialId, pMat->mlMaterialId,
nullptr, BeginContactCallback, ProcessContactCallback);
}
}
//-----------------------------------------------------------------------
float cPhysicsMaterialNewton::Combine(ePhysicsMaterialCombMode aMode, float afX, float afY) {
switch (aMode) {
case ePhysicsMaterialCombMode_Average:
return (afX + afY) / 2;
case ePhysicsMaterialCombMode_Min:
return MIN(afX, afY);
case ePhysicsMaterialCombMode_Max:
return MAX(afX, afY);
case ePhysicsMaterialCombMode_Multiply:
return afX * afY;
default:
break;
}
return (afX + afY) / 2;
}
//////////////////////////////////////////////////////////////////////////
// STATIC NEWTON CALLBACKS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
int cPhysicsMaterialNewton::BeginContactCallback(const NewtonMaterial *material,
const NewtonBody *body0, const NewtonBody *body1, int32) {
iPhysicsBody *contactBody0 = (cPhysicsBodyNewton *)NewtonBodyGetUserData(body0);
iPhysicsBody *contactBody1 = (cPhysicsBodyNewton *)NewtonBodyGetUserData(body1);
if (contactBody0->GetCollide() == false)
return 0;
if (contactBody1->GetCollide() == false)
return 0;
if (contactBody0->IsActive() == false)
return 0;
if (contactBody1->IsActive() == false)
return 0;
if (contactBody0->IsRagDoll() && contactBody1->GetCollideRagDoll() == false)
return 0;
if (contactBody1->IsRagDoll() && contactBody0->GetCollideRagDoll() == false)
return 0;
if (contactBody0->IsCharacter() && contactBody1->GetCollideCharacter() == false)
return 0;
if (contactBody1->IsCharacter() && contactBody0->GetCollideCharacter() == false)
return 0;
if (contactBody0->OnBeginCollision(contactBody1) == false)
return 0;
if (contactBody1->OnBeginCollision(contactBody0) == false)
return 0;
return 1;
}
//-----------------------------------------------------------------------
class ContactProcessor {
public:
ContactProcessor(const NewtonJoint *joint);
bool processNext();
void endProcessing();
private:
void *_contact;
int _contacts;
const NewtonJoint *_joint;
NewtonBody *_body0;
NewtonBody *_body1;
cPhysicsBodyNewton *_contactBody0;
cPhysicsBodyNewton *_contactBody1;
cPhysicsContactData _contactData;
};
ContactProcessor::ContactProcessor(const NewtonJoint *joint) : _joint(joint), _contacts(0), _contact(nullptr) {
_body0 = NewtonJointGetBody0(joint);
_body1 = NewtonJointGetBody1(joint);
_contactBody0 = (cPhysicsBodyNewton *)NewtonBodyGetUserData(_body0);
_contactBody1 = (cPhysicsBodyNewton *)NewtonBodyGetUserData(_body1);
_contact = NewtonContactJointGetFirstContact(_joint);
}
bool ContactProcessor::processNext() {
NewtonMaterial *_material = NewtonContactGetMaterial(_contact);
float fNormSpeed = NewtonMaterialGetContactNormalSpeed(_material);
if (_contactData.mfMaxContactNormalSpeed < fNormSpeed)
_contactData.mfMaxContactNormalSpeed = fNormSpeed;
// Tangent speed
float fTanSpeed0 = NewtonMaterialGetContactTangentSpeed(_material, 0);
float fTanSpeed1 = NewtonMaterialGetContactTangentSpeed(_material, 1);
if (ABS(_contactData.mfMaxContactTangentSpeed) < ABS(fTanSpeed0))
_contactData.mfMaxContactTangentSpeed = fTanSpeed0;
if (ABS(_contactData.mfMaxContactTangentSpeed) < ABS(fTanSpeed1))
_contactData.mfMaxContactTangentSpeed = fTanSpeed1;
// Force
float force[3];
NewtonMaterialGetContactForce(_material, _body0, force);
_contactData.mvForce += cVector3f::fromArray(force);
// Position and normal
float matPos[3], matNormal[3];
NewtonMaterialGetContactPositionAndNormal(_material, _body0, matPos, matNormal);
_contactData.mvContactNormal += cVector3f::fromArray(matNormal);
_contactData.mvContactPosition += cVector3f::fromArray(matPos);
if (_contactBody0->GetWorld()->GetSaveContactPoints()) {
NewtonMaterialGetContactPositionAndNormal(_material, _body0, matPos, matNormal);
cCollidePoint collidePoint;
collidePoint.mfDepth = 1;
collidePoint.mvPoint = cVector3f::fromArray(matPos);
collidePoint.mvNormal = cVector3f::fromArray(matNormal);
_contactBody0->GetWorld()->GetContactPoints()->push_back(collidePoint);
}
++_contacts;
return (_contact = NewtonContactJointGetNextContact(_joint, _contact));
}
void ContactProcessor::endProcessing() {
if (_contacts == 0)
return;
iPhysicsMaterial *pMaterial1 = _contactBody0->GetMaterial();
iPhysicsMaterial *pMaterial2 = _contactBody1->GetMaterial();
_contactData.mvContactNormal = _contactData.mvContactNormal / (float)_contacts;
_contactData.mvContactPosition = _contactData.mvContactPosition / (float)_contacts;
pMaterial1->GetSurfaceData()->CreateImpactEffect(_contactData.mfMaxContactNormalSpeed,
_contactData.mvContactPosition,
_contacts, pMaterial2->GetSurfaceData());
int lPrio1 = pMaterial1->GetSurfaceData()->GetPriority();
int lPrio2 = pMaterial2->GetSurfaceData()->GetPriority();
if (lPrio1 >= lPrio2) {
if (ABS(_contactData.mfMaxContactNormalSpeed) > 0)
pMaterial1->GetSurfaceData()->OnImpact(_contactData.mfMaxContactNormalSpeed,
_contactData.mvContactPosition,
_contacts, _contactBody0);
if (ABS(_contactData.mfMaxContactTangentSpeed) > 0)
pMaterial1->GetSurfaceData()->OnSlide(_contactData.mfMaxContactTangentSpeed,
_contactData.mvContactPosition,
_contacts, _contactBody0, _contactBody1);
}
if (lPrio2 >= lPrio1 && pMaterial2 != pMaterial1) {
if (ABS(_contactData.mfMaxContactNormalSpeed) > 0)
pMaterial2->GetSurfaceData()->OnImpact(_contactData.mfMaxContactNormalSpeed,
_contactData.mvContactPosition,
_contacts, _contactBody1);
if (ABS(_contactData.mfMaxContactTangentSpeed) > 0)
pMaterial2->GetSurfaceData()->OnSlide(_contactData.mfMaxContactTangentSpeed,
_contactData.mvContactPosition,
_contacts, _contactBody1, _contactBody0);
}
_contactBody0->OnCollide(_contactBody1, &_contactData);
_contactBody1->OnCollide(_contactBody0, &_contactData);
}
void cPhysicsMaterialNewton::ProcessContactCallback(const NewtonJoint *joint, float, int32) {
ContactProcessor processor(joint);
while (processor.processNext()) {
}
processor.endProcessing();
}
} // namespace hpl

View File

@@ -0,0 +1,82 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_MATERIAL_NEWTON_H
#define HPL_PHYSICS_MATERIAL_NEWTON_H
#include "hpl1/engine/libraries/newton/Newton.h"
#include "hpl1/engine/physics/PhysicsMaterial.h"
namespace hpl {
class iPhysicsBody;
class cPhysicsContactData;
class cPhysicsMaterialNewton : public iPhysicsMaterial {
public:
cPhysicsMaterialNewton(const tString &asName, iPhysicsWorld *apWorld, int alMatId = -1);
~cPhysicsMaterialNewton();
void SetElasticity(float afElasticity);
float GetElasticity() const;
void SetStaticFriction(float afElasticity);
float GetStaticFriction() const;
void SetKineticFriction(float afElasticity);
float GetKineticFriction() const;
void SetFrictionCombMode(ePhysicsMaterialCombMode aMode);
ePhysicsMaterialCombMode GetFrictionCombMode() const;
void SetElasticityCombMode(ePhysicsMaterialCombMode aMode);
ePhysicsMaterialCombMode GetElasticityCombMode() const;
void UpdateMaterials();
int GetId() { return mlMaterialId; }
private:
float Combine(ePhysicsMaterialCombMode aMode, float afX, float afY);
static int BeginContactCallback(const NewtonMaterial *material,
const NewtonBody *apBody1, const NewtonBody *apBody2, int32);
static void ProcessContactCallback(const NewtonJoint *joint, float, int32);
NewtonWorld *mpNewtonWorld;
int mlMaterialId;
ePhysicsMaterialCombMode mFrictionMode;
ePhysicsMaterialCombMode mElasticityMode;
float mfElasticity;
float mfStaticFriction;
float mfKineticFriction;
};
} // namespace hpl
#endif // HPL_PHYSICS_MATERIAL_NEWTON_H

View File

@@ -0,0 +1,577 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/PhysicsWorldNewton.h"
#include "hpl1/engine/impl/CharacterBodyNewton.h"
#include "hpl1/engine/impl/CollideShapeNewton.h"
#include "hpl1/engine/impl/PhysicsBodyNewton.h"
#include "hpl1/engine/impl/PhysicsMaterialNewton.h"
#include "hpl1/engine/impl/PhysicsJointBallNewton.h"
#include "hpl1/engine/impl/PhysicsJointHingeNewton.h"
#include "hpl1/engine/impl/PhysicsJointScrewNewton.h"
#include "hpl1/engine/impl/PhysicsJointSliderNewton.h"
#include "hpl1/engine/impl/PhysicsControllerNewton.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/math/Vector3.h"
#include "hpl1/engine/physics/CollideShape.h"
#include "hpl1/engine/scene/PortalContainer.h"
#include "hpl1/engine/scene/World3D.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/graphics/VertexBuffer.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cPhysicsWorldNewton::cPhysicsWorldNewton()
: iPhysicsWorld() {
mpNewtonWorld = NewtonCreate();
if (mpNewtonWorld == NULL) {
Warning("Couldn't create newton world!\n");
}
/////////////////////////////////
// Set default values to properties
mvWorldSizeMin = cVector3f(0, 0, 0);
mvWorldSizeMax = cVector3f(0, 0, 0);
mvGravity = cVector3f(0, -9.81f, 0);
mfMaxTimeStep = 1.0f / 60.0f;
/////////////////////////////////
// Create default material.
int lDefaultMatId = 0; // NewtonMaterialGetDefaultGroupID(mpNewtonWorld);
cPhysicsMaterialNewton *pMaterial = hplNew(cPhysicsMaterialNewton, ("Default", this, lDefaultMatId));
tPhysicsMaterialMap::value_type Val("Default", pMaterial);
m_mapMaterials.insert(Val);
pMaterial->UpdateMaterials();
mpTempDepths = hplNewArray(float, 500);
mpTempNormals = hplNewArray(float, 500 * 3);
mpTempPoints = hplNewArray(float, 500 * 3);
}
//-----------------------------------------------------------------------
cPhysicsWorldNewton::~cPhysicsWorldNewton() {
DestroyAll();
NewtonDestroy(mpNewtonWorld);
hplDeleteArray(mpTempDepths);
hplDeleteArray(mpTempNormals);
hplDeleteArray(mpTempPoints);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cPhysicsWorldNewton::Simulate(float afTimeStep) {
// cPhysicsBodyNewton::SetUseCallback(false);
// static lUpdate =0;
// if(lUpdate % 30==0)
{
while (afTimeStep > mfMaxTimeStep) {
NewtonUpdate(mpNewtonWorld, mfMaxTimeStep);
afTimeStep -= mfMaxTimeStep;
}
NewtonUpdate(mpNewtonWorld, afTimeStep);
}
// lUpdate++;
// cPhysicsBodyNewton::SetUseCallback(true);
tPhysicsBodyListIt it = mlstBodies.begin();
for (; it != mlstBodies.end(); ++it) {
cPhysicsBodyNewton *pBody = static_cast<cPhysicsBodyNewton *>(*it);
pBody->ClearForces();
}
}
//-----------------------------------------------------------------------
void cPhysicsWorldNewton::SetMaxTimeStep(float afTimeStep) {
mfMaxTimeStep = afTimeStep;
}
float cPhysicsWorldNewton::GetMaxTimeStep() {
return mfMaxTimeStep;
}
//-----------------------------------------------------------------------
void cPhysicsWorldNewton::SetWorldSize(const cVector3f &avMin, const cVector3f &avMax) {
mvWorldSizeMin = avMin;
mvWorldSizeMax = avMax;
VEC3_CONST_ARRAY(min, avMin);
VEC3_CONST_ARRAY(max, avMax);
NewtonSetWorldSize(mpNewtonWorld, min, max);
}
cVector3f cPhysicsWorldNewton::GetWorldSizeMin() {
return mvWorldSizeMin;
}
cVector3f cPhysicsWorldNewton::GetWorldSizeMax() {
return mvWorldSizeMax;
}
//-----------------------------------------------------------------------
void cPhysicsWorldNewton::SetGravity(const cVector3f &avGravity) {
mvGravity = avGravity;
}
//-----------------------------------------------------------------------
cVector3f cPhysicsWorldNewton::GetGravity() {
return mvGravity;
}
//-----------------------------------------------------------------------
void cPhysicsWorldNewton::SetAccuracyLevel(ePhysicsAccuracy aAccuracy) {
mAccuracy = aAccuracy;
switch (mAccuracy) {
case ePhysicsAccuracy_Low:
NewtonSetSolverModel(mpNewtonWorld, 8);
NewtonSetFrictionModel(mpNewtonWorld, 1);
Log("SETTING LOW!\n");
break;
case ePhysicsAccuracy_Medium:
NewtonSetSolverModel(mpNewtonWorld, 1);
NewtonSetFrictionModel(mpNewtonWorld, 1);
break;
case ePhysicsAccuracy_High:
NewtonSetSolverModel(mpNewtonWorld, 0);
NewtonSetFrictionModel(mpNewtonWorld, 0);
break;
default:
break;
}
}
//-----------------------------------------------------------------------
ePhysicsAccuracy cPhysicsWorldNewton::GetAccuracyLevel() {
return mAccuracy;
}
//-----------------------------------------------------------------------
iCollideShape *cPhysicsWorldNewton::CreateNullShape() {
iCollideShape *pShape = hplNew(cCollideShapeNewton, (eCollideShapeType_Null, 0, NULL,
mpNewtonWorld, this));
mlstShapes.push_back(pShape);
return pShape;
}
//-----------------------------------------------------------------------
iCollideShape *cPhysicsWorldNewton::CreateBoxShape(const cVector3f &avSize, cMatrixf *apOffsetMtx) {
iCollideShape *pShape = hplNew(cCollideShapeNewton, (eCollideShapeType_Box, avSize, apOffsetMtx,
mpNewtonWorld, this));
mlstShapes.push_back(pShape);
return pShape;
}
//-----------------------------------------------------------------------
iCollideShape *cPhysicsWorldNewton::CreateSphereShape(const cVector3f &avRadii, cMatrixf *apOffsetMtx) {
iCollideShape *pShape = hplNew(cCollideShapeNewton, (eCollideShapeType_Sphere, avRadii, apOffsetMtx,
mpNewtonWorld, this));
mlstShapes.push_back(pShape);
return pShape;
}
//-----------------------------------------------------------------------
iCollideShape *cPhysicsWorldNewton::CreateCylinderShape(float afRadius, float afHeight, cMatrixf *apOffsetMtx) {
iCollideShape *pShape = hplNew(cCollideShapeNewton, (eCollideShapeType_Cylinder,
cVector3f(afRadius, afHeight, afRadius),
apOffsetMtx,
mpNewtonWorld, this));
mlstShapes.push_back(pShape);
return pShape;
}
//-----------------------------------------------------------------------
iCollideShape *cPhysicsWorldNewton::CreateCapsuleShape(float afRadius, float afHeight, cMatrixf *apOffsetMtx) {
iCollideShape *pShape = hplNew(cCollideShapeNewton, (eCollideShapeType_Capsule,
cVector3f(afRadius, afHeight, afRadius),
apOffsetMtx,
mpNewtonWorld, this));
mlstShapes.push_back(pShape);
return pShape;
}
//-----------------------------------------------------------------------
iCollideShape *cPhysicsWorldNewton::CreateMeshShape(iVertexBuffer *apVtxBuffer) {
cCollideShapeNewton *pShape = hplNew(cCollideShapeNewton, (eCollideShapeType_Mesh,
0, NULL, mpNewtonWorld, this));
pShape->CreateFromVertices(apVtxBuffer->GetIndices(), apVtxBuffer->GetIndexNum(),
apVtxBuffer->GetArray(eVertexFlag_Position),
kvVertexElements[cMath::Log2ToInt(eVertexFlag_Position)],
apVtxBuffer->GetVertexNum());
mlstShapes.push_back(pShape);
return pShape;
}
//-----------------------------------------------------------------------
iCollideShape *cPhysicsWorldNewton::CreateCompundShape(tCollideShapeVec &avShapes) {
cCollideShapeNewton *pShape = hplNew(cCollideShapeNewton, (eCollideShapeType_Compound,
0, NULL, mpNewtonWorld, this));
pShape->CreateFromShapeVec(avShapes);
mlstShapes.push_back(pShape);
return pShape;
}
//-----------------------------------------------------------------------
iPhysicsJointBall *cPhysicsWorldNewton::CreateJointBall(const tString &asName,
const cVector3f &avPivotPoint,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody) {
iPhysicsJointBall *pJoint = hplNew(cPhysicsJointBallNewton, (asName, apParentBody, apChildBody, this,
avPivotPoint));
mlstJoints.push_back(pJoint);
return pJoint;
}
iPhysicsJointHinge *cPhysicsWorldNewton::CreateJointHinge(const tString &asName,
const cVector3f &avPivotPoint, const cVector3f &avPinDir,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody) {
iPhysicsJointHinge *pJoint = hplNew(cPhysicsJointHingeNewton, (asName, apParentBody, apChildBody, this,
avPivotPoint, avPinDir));
mlstJoints.push_back(pJoint);
return pJoint;
}
iPhysicsJointSlider *cPhysicsWorldNewton::CreateJointSlider(const tString &asName,
const cVector3f &avPivotPoint, const cVector3f &avPinDir,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody) {
iPhysicsJointSlider *pJoint = hplNew(cPhysicsJointSliderNewton, (asName, apParentBody, apChildBody, this,
avPivotPoint, avPinDir));
mlstJoints.push_back(pJoint);
return pJoint;
}
iPhysicsJointScrew *cPhysicsWorldNewton::CreateJointScrew(const tString &asName,
const cVector3f &avPivotPoint, const cVector3f &avPinDir,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody) {
iPhysicsJointScrew *pJoint = hplNew(cPhysicsJointScrewNewton, (asName, apParentBody, apChildBody, this,
avPivotPoint, avPinDir));
mlstJoints.push_back(pJoint);
return pJoint;
}
//-----------------------------------------------------------------------
iPhysicsBody *cPhysicsWorldNewton::CreateBody(const tString &asName, iCollideShape *apShape) {
cPhysicsBodyNewton *pBody = hplNew(cPhysicsBodyNewton, (asName, this, apShape));
mlstBodies.push_back(pBody);
if (mpWorld3D)
mpWorld3D->GetPortalContainer()->AddEntity(pBody);
return pBody;
}
//-----------------------------------------------------------------------
iCharacterBody *cPhysicsWorldNewton::CreateCharacterBody(const tString &asName, const cVector3f &avSize) {
cCharacterBodyNewton *pChar = hplNew(cCharacterBodyNewton, (asName, this, avSize));
mlstCharBodies.push_back(pChar);
return pChar;
}
//-----------------------------------------------------------------------
iPhysicsMaterial *cPhysicsWorldNewton::CreateMaterial(const tString &asName) {
cPhysicsMaterialNewton *pMaterial = hplNew(cPhysicsMaterialNewton, (asName, this));
tPhysicsMaterialMap::value_type Val(asName, pMaterial);
m_mapMaterials.insert(Val);
pMaterial->UpdateMaterials();
return pMaterial;
}
//-----------------------------------------------------------------------
iPhysicsController *cPhysicsWorldNewton::CreateController(const tString &asName) {
iPhysicsController *pController = hplNew(cPhysicsControllerNewton, (asName, this));
mlstControllers.push_back(pController);
return pController;
}
//-----------------------------------------------------------------------
static bool gbRayCalcDist;
static bool gbRayCalcNormal;
static bool gbRayCalcPoint;
static iPhysicsRayCallback *gpRayCallback;
static cVector3f gvRayOrigin;
static cVector3f gvRayEnd;
static cVector3f gvRayDelta;
static float gfRayLength;
static cPhysicsRayParams gRayParams;
//////////////////////////////////////
static unsigned RayCastPrefilterFunc(const NewtonBody *apNewtonBody, const NewtonCollision *collision, void *userData) {
cPhysicsBodyNewton *pRigidBody = (cPhysicsBodyNewton *)NewtonBodyGetUserData(apNewtonBody);
if (pRigidBody->IsActive() == false)
return 0;
bool bRet = gpRayCallback->BeforeIntersect(pRigidBody);
if (bRet)
return 1;
else
return 0;
}
static float RayCastFilterFunc(const NewtonBody *apNewtonBody, const float *apNormalVec,
int alCollisionID, void *apUserData, float afIntersetParam) {
cPhysicsBodyNewton *pRigidBody = (cPhysicsBodyNewton *)NewtonBodyGetUserData(apNewtonBody);
if (pRigidBody->IsActive() == false)
return 1;
gRayParams.mfT = afIntersetParam;
// Calculate stuff needed.
if (gbRayCalcDist) {
gRayParams.mfDist = gfRayLength * afIntersetParam;
}
if (gbRayCalcNormal) {
gRayParams.mvNormal.FromVec(apNormalVec);
}
if (gbRayCalcPoint) {
gRayParams.mvPoint = gvRayOrigin + gvRayDelta * afIntersetParam;
}
// Call the call back
bool bRet = gpRayCallback->OnIntersect(pRigidBody, &gRayParams);
// return correct value.
if (bRet)
return 1; // afIntersetParam;
else
return 0;
}
//////////////////////////////////////
void cPhysicsWorldNewton::CastRay(iPhysicsRayCallback *apCallback,
const cVector3f &avOrigin, const cVector3f &avEnd,
bool abCalcDist, bool abCalcNormal, bool abCalcPoint,
bool abUsePrefilter) {
gbRayCalcPoint = abCalcPoint;
gbRayCalcNormal = abCalcNormal;
gbRayCalcDist = abCalcDist;
gvRayOrigin = avOrigin;
gvRayEnd = avEnd;
gvRayDelta = avEnd - avOrigin;
gfRayLength = gvRayDelta.Length();
gpRayCallback = apCallback;
VEC3_CONST_ARRAY(origin, avOrigin);
VEC3_CONST_ARRAY(end, avEnd);
if (abUsePrefilter)
NewtonWorldRayCast(mpNewtonWorld, origin, end, RayCastFilterFunc, NULL, RayCastPrefilterFunc);
else
NewtonWorldRayCast(mpNewtonWorld, origin, end, RayCastFilterFunc, NULL, NULL);
}
//-----------------------------------------------------------------------
// Fix found in HPL2 (https://github.com/FrictionalGames/AmnesiaTheDarkDescent)
static void correctNormal(cVector3f &normal, const cVector3f &collidePoint, const cVector3f &shapeCenter) {
cVector3f vCenterToCollidePoint = collidePoint - shapeCenter;
// A check if the normal points in the wrong direction.
if (cMath::Vector3Dot(vCenterToCollidePoint, normal) > 0)
normal = normal * -1;
}
bool cPhysicsWorldNewton::CheckShapeCollision(iCollideShape *apShapeA, const cMatrixf &a_mtxA,
iCollideShape *apShapeB, const cMatrixf &a_mtxB,
cCollideData &aCollideData, int alMaxPoints,
bool correctNormalDirection) {
cCollideShapeNewton *pNewtonShapeA = static_cast<cCollideShapeNewton *>(apShapeA);
cCollideShapeNewton *pNewtonShapeB = static_cast<cCollideShapeNewton *>(apShapeB);
cMatrixf mtxTransposeA = a_mtxA.GetTranspose();
cMatrixf mtxTransposeB = a_mtxB.GetTranspose();
//////////////////////////////
// Check compound collision
if (pNewtonShapeA->GetType() == eCollideShapeType_Compound ||
pNewtonShapeB->GetType() == eCollideShapeType_Compound) {
int lACount = pNewtonShapeA->GetSubShapeNum();
int lBCount = pNewtonShapeB->GetSubShapeNum();
bool bCollision = false;
aCollideData.mlNumOfPoints = 0;
int lCollideDataStart = 0;
for (int a = 0; a < lACount; a++) {
for (int b = 0; b < lBCount; b++) {
cCollideShapeNewton *pSubShapeA = static_cast<cCollideShapeNewton *>(pNewtonShapeA->GetSubShape(a));
cCollideShapeNewton *pSubShapeB = static_cast<cCollideShapeNewton *>(pNewtonShapeB->GetSubShape(b));
int lNum = NewtonCollisionCollide(mpNewtonWorld, alMaxPoints,
pSubShapeA->GetNewtonCollision(), &(mtxTransposeA.m[0][0]),
pSubShapeB->GetNewtonCollision(), &(mtxTransposeB.m[0][0]),
mpTempPoints, mpTempNormals, mpTempDepths, 0);
if (lNum < 1)
continue;
if (lNum > alMaxPoints)
lNum = alMaxPoints;
bCollision = true;
// Log("Collided %d vs %d. Num: %d\n",a,b,lNum);
// Negate for each iteration.
alMaxPoints -= lNum;
for (int i = 0; i < lNum; i++) {
cCollidePoint &CollPoint = aCollideData.mvContactPoints[lCollideDataStart + i];
CollPoint.mfDepth = mpTempDepths[i];
int lVertex = i * 3;
CollPoint.mvNormal.x = mpTempNormals[lVertex + 0];
CollPoint.mvNormal.y = mpTempNormals[lVertex + 1];
CollPoint.mvNormal.z = mpTempNormals[lVertex + 2];
CollPoint.mvPoint.x = mpTempPoints[lVertex + 0];
CollPoint.mvPoint.y = mpTempPoints[lVertex + 1];
CollPoint.mvPoint.z = mpTempPoints[lVertex + 2];
if (correctNormalDirection && apShapeA->GetType() != eCollideShapeType_Mesh)
correctNormal(CollPoint.mvNormal, CollPoint.mvPoint, a_mtxA.GetTranslation());
}
lCollideDataStart += lNum;
aCollideData.mlNumOfPoints += lNum;
if (alMaxPoints <= 0)
break;
}
if (alMaxPoints <= 0)
break;
}
return bCollision;
}
//////////////////////////////
// Check NON compound collision
else {
int lNum = NewtonCollisionCollide(mpNewtonWorld, alMaxPoints,
pNewtonShapeA->GetNewtonCollision(), &(mtxTransposeA.m[0][0]),
pNewtonShapeB->GetNewtonCollision(), &(mtxTransposeB.m[0][0]),
mpTempPoints, mpTempNormals, mpTempDepths, 0);
if (lNum < 1)
return false;
if (lNum > alMaxPoints)
lNum = alMaxPoints;
for (int i = 0; i < lNum; i++) {
cCollidePoint &CollPoint = aCollideData.mvContactPoints[i];
CollPoint.mfDepth = mpTempDepths[i];
int lVertex = i * 3;
CollPoint.mvNormal.x = mpTempNormals[lVertex + 0];
CollPoint.mvNormal.y = mpTempNormals[lVertex + 1];
CollPoint.mvNormal.z = mpTempNormals[lVertex + 2];
CollPoint.mvPoint.x = mpTempPoints[lVertex + 0];
CollPoint.mvPoint.y = mpTempPoints[lVertex + 1];
CollPoint.mvPoint.z = mpTempPoints[lVertex + 2];
if (correctNormalDirection && apShapeA->GetType() != eCollideShapeType_Mesh)
correctNormal(CollPoint.mvNormal, CollPoint.mvPoint, a_mtxA.GetTranslation());
}
aCollideData.mlNumOfPoints = lNum;
}
return true;
}
//-----------------------------------------------------------------------
void cPhysicsWorldNewton::RenderDebugGeometry(iLowLevelGraphics *apLowLevel, const cColor &aColor) {
tPhysicsBodyListIt it = mlstBodies.begin();
for (; it != mlstBodies.end(); ++it) {
iPhysicsBody *pBody = *it;
pBody->RenderDebugGeometry(apLowLevel, aColor);
}
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,114 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_PHYSICS_WORLD_NEWTON_H
#define HPL_PHYSICS_WORLD_NEWTON_H
#include "hpl1/engine/physics/PhysicsWorld.h"
#include "hpl1/engine/libraries/newton/Newton.h"
namespace hpl {
class cPhysicsWorldNewton : public iPhysicsWorld {
public:
cPhysicsWorldNewton();
~cPhysicsWorldNewton();
void Simulate(float afTimeStep);
void SetMaxTimeStep(float afTimeStep);
float GetMaxTimeStep();
void SetWorldSize(const cVector3f &avMin, const cVector3f &avMax);
cVector3f GetWorldSizeMin();
cVector3f GetWorldSizeMax();
void SetGravity(const cVector3f &avGravity);
cVector3f GetGravity();
void SetAccuracyLevel(ePhysicsAccuracy aAccuracy);
ePhysicsAccuracy GetAccuracyLevel();
iCollideShape *CreateNullShape();
iCollideShape *CreateBoxShape(const cVector3f &avSize, cMatrixf *apOffsetMtx);
iCollideShape *CreateSphereShape(const cVector3f &avRadii, cMatrixf *apOffsetMtx);
iCollideShape *CreateCylinderShape(float afRadius, float afHeight, cMatrixf *apOffsetMtx);
iCollideShape *CreateCapsuleShape(float afRadius, float afHeight, cMatrixf *apOffsetMtx);
iCollideShape *CreateMeshShape(iVertexBuffer *apVtxBuffer);
iCollideShape *CreateCompundShape(tCollideShapeVec &avShapes);
iPhysicsJointBall *CreateJointBall(const tString &asName, const cVector3f &avPivotPoint,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody);
iPhysicsJointHinge *CreateJointHinge(const tString &asName, const cVector3f &avPivotPoint,
const cVector3f &avPinDir,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody);
iPhysicsJointSlider *CreateJointSlider(const tString &asName, const cVector3f &avPivotPoint,
const cVector3f &avPinDir,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody);
iPhysicsJointScrew *CreateJointScrew(const tString &asName, const cVector3f &avPivotPoint,
const cVector3f &avPinDir,
iPhysicsBody *apParentBody, iPhysicsBody *apChildBody);
iPhysicsBody *CreateBody(const tString &asName, iCollideShape *apShape);
iCharacterBody *CreateCharacterBody(const tString &asName, const cVector3f &avSize);
iPhysicsMaterial *CreateMaterial(const tString &asName);
iPhysicsController *CreateController(const tString &asName);
void CastRay(iPhysicsRayCallback *apCallback,
const cVector3f &avOrigin, const cVector3f &avEnd,
bool abCalcDist, bool abCalcNormal, bool abCalcPoint,
bool abUsePrefilter = false);
bool CheckShapeCollision(iCollideShape *apShapeA, const cMatrixf &a_mtxA,
iCollideShape *apShapeB, const cMatrixf &a_mtxB,
cCollideData &aCollideData, int alMaxPoints, bool correctNormalDirection = false);
void RenderDebugGeometry(iLowLevelGraphics *apLowLevel, const cColor &aColor);
NewtonWorld *GetNewtonWorld() { return mpNewtonWorld; }
private:
NewtonWorld *mpNewtonWorld;
float *mpTempPoints;
float *mpTempNormals;
float *mpTempDepths;
cVector3f mvWorldSizeMin;
cVector3f mvWorldSizeMax;
cVector3f mvGravity;
float mfMaxTimeStep;
ePhysicsAccuracy mAccuracy;
};
} // namespace hpl
#endif // HPL_PHYSICS_WORLD_NEWTON_H

View File

@@ -0,0 +1,656 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/SDLTexture.h"
#include "common/str.h"
#include "graphics/pixelformat.h"
#include "hpl1/engine/graphics/bitmap2D.h"
#include "hpl1/debug.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/low_level_system.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
static void getSettings(Bitmap2D *apSrc, int &alChannels, GLint &internalFormat, GLenum &format) {
alChannels = apSrc->getNumChannels();
tString sType = cString::ToLowerCase(apSrc->getType());
const Common::String bmpFormat = apSrc->format().toString();
if (alChannels == 4) {
internalFormat = GL_RGBA;
if (bmpFormat.contains("BGRA")) {
format = GL_BGRA;
} else {
format = GL_RGBA;
}
}
if (alChannels == 3) {
internalFormat = GL_RGB;
if (bmpFormat.contains("BGR")) {
format = GL_BGR;
} else {
format = GL_RGB;
}
}
if (alChannels == 1) {
format = GL_RED;
internalFormat = GL_RED;
}
}
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSDLTexture::cSDLTexture(const tString &asName, Graphics::PixelFormat *apPxlFmt, iLowLevelGraphics *apLowLevelGraphics,
eTextureType aType, bool abUseMipMaps, eTextureTarget aTarget,
bool abCompress)
: iTexture(asName, "OGL", apPxlFmt, apLowLevelGraphics, aType, abUseMipMaps, aTarget, abCompress) {
mbContainsData = false;
if (aType == eTextureType_RenderTarget) {
Hpl1::logError(Hpl1::kDebugTextures, "use of render target%s", ".");
// mpPBuffer = hplNew( cPBuffer, (mpLowLevelGraphics,true) );
}
// Cubemap does not like mipmaps
if (aTarget == eTextureTarget_CubeMap)
mbUseMipMaps = false;
mpGfxSDL = static_cast<cLowLevelGraphicsSDL *>(mpLowLevelGraphics);
mlTextureIndex = 0;
mfTimeCount = 0;
mfTimeDir = 1;
}
cSDLTexture::~cSDLTexture() {
for (unsigned int &mvTextureHandle : mvTextureHandles) {
GL_CHECK(glDeleteTextures(1, (GLuint *)&mvTextureHandle));
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cSDLTexture::CreateFromBitmap(Bitmap2D *pBmp) {
// Generate handles
if (mvTextureHandles.empty()) {
mvTextureHandles.resize(1);
GL_CHECK(glGenTextures(1, &mvTextureHandles[0]));
} else {
// Log("Delete + Generate!\n");
// glDeleteTextures(1,(GLuint *)&mvTextureHandles[0]);
// glGenTextures(1,(GLuint *)&mvTextureHandles[0]);
}
return CreateFromBitmapToHandle(pBmp, 0);
}
//-----------------------------------------------------------------------
bool cSDLTexture::CreateAnimFromBitmapVec(tBitmap2DVec *avBitmaps) {
mvTextureHandles.resize(avBitmaps->size());
for (size_t i = 0; i < mvTextureHandles.size(); ++i) {
glGenTextures(1, (GLuint *)&mvTextureHandles[i]);
if (CreateFromBitmapToHandle((*avBitmaps)[i], (int)i) == false) {
return false;
}
}
return true;
}
//-----------------------------------------------------------------------
bool cSDLTexture::CreateCubeFromBitmapVec(tBitmap2DVec *avBitmaps) {
// gl 1.3
if (mType == eTextureType_RenderTarget || mTarget != eTextureTarget_CubeMap) {
return false;
}
if (avBitmaps->size() < 6) {
Hpl1::logError(Hpl1::kDebugTextures, "Only %d bitmaps supplied for creation of cube map, 6 needed.", avBitmaps->size());
return false;
}
// Generate handles
if (mvTextureHandles.empty()) {
mvTextureHandles.resize(1);
GL_CHECK(glGenTextures(1, &mvTextureHandles[0]));
} else {
GL_CHECK(glDeleteTextures(1, &mvTextureHandles[0]));
GL_CHECK(glGenTextures(1, &mvTextureHandles[0]));
}
GLenum GLTarget = InitCreation(0);
// Create the cube map sides
for (int i = 0; i < 6; i++) {
Bitmap2D *pSrc = static_cast<Bitmap2D *>((*avBitmaps)[i]);
GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
int lChannels;
GLenum format;
GLint internalFormat;
getSettings(pSrc, lChannels, internalFormat, format);
glTexImage2D(target, 0, internalFormat, pSrc->getWidth(), pSrc->getHeight(),
0, format, GL_UNSIGNED_BYTE, pSrc->getRawData());
// No mip maps for cubemap
// if(mbUseMipMaps)
//{
// int x = gluBuild2DMipmaps(target,4,pSrc->GetWidth(), pSrc->GetHeight(),
// GL_RGBA, GL_UNSIGNED_BYTE, pSrc->GetSurface()->pixels);
// }
_width = pSrc->getWidth();
_height = pSrc->getHeight();
_bpp = lChannels * 8;
if (!cMath::IsPow2(_height) || !cMath::IsPow2(_width)) {
Hpl1::logWarning(Hpl1::kDebugTextures, "Texture '%s' does not have a pow2 size", msName.c_str());
}
}
PostCreation(GLTarget);
return true;
}
//-----------------------------------------------------------------------
bool cSDLTexture::Create(unsigned int alWidth, unsigned int alHeight, cColor aCol) {
error("call to unimplemented function SDLTexture::Create");
}
//-----------------------------------------------------------------------
static void generateMipmaps(eTextureTarget target) {
// gl 1.4
if (target == eTextureTarget_1D) {
GL_CHECK(glGenerateMipmap(GL_TEXTURE_1D))
} else {
GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D))
}
}
bool cSDLTexture::CreateFromArray(unsigned char *apPixelData, int alChannels, const cVector3l &avSize) {
if (mvTextureHandles.empty()) {
mvTextureHandles.resize(1);
GL_CHECK(glGenTextures(1, (GLuint *)&mvTextureHandles[0]));
}
GLenum GLTarget = InitCreation(0);
int lChannels = alChannels;
GLenum format = 0;
switch (lChannels) {
case 1:
format = GL_R;
break;
case 2:
format = GL_RG;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
_width = avSize.x;
_height = avSize.y;
_bpp = lChannels * 8;
if (!cMath::IsPow2(_height) || !cMath::IsPow2(_width) || !cMath::IsPow2(avSize.z)) {
Hpl1::logWarning(Hpl1::kDebugTextures, "Texture '%s' does not have a pow2 size", msName.c_str());
}
if (mTarget == eTextureTarget_1D) {
GL_CHECK(glTexImage1D(GLTarget, 0, format, _width, 0, format,
GL_UNSIGNED_BYTE, apPixelData));
} else if (mTarget == eTextureTarget_2D) {
GL_CHECK(glTexImage2D(GLTarget, 0, format, _width, _height,
0, format, GL_UNSIGNED_BYTE, apPixelData));
} else if (mTarget == eTextureTarget_3D) {
GL_CHECK(glTexImage3D(GLTarget, 0, format, avSize.x, avSize.y, avSize.z,
0, format, GL_UNSIGNED_BYTE, apPixelData));
}
if (mbUseMipMaps && mTarget != eTextureTarget_Rect && mTarget != eTextureTarget_3D)
generateMipmaps(mTarget);
PostCreation(GLTarget);
return true;
}
//-----------------------------------------------------------------------
void cSDLTexture::SetPixels2D(int alLevel, const cVector2l &avOffset, const cVector2l &avSize,
eColorDataFormat aDataFormat, void *apPixelData) {
if (mTarget != eTextureTarget_2D && mTarget != eTextureTarget_Rect)
return;
GL_CHECK(glTexSubImage2D(TextureTargetToGL(mTarget), alLevel, avOffset.x, avOffset.y, avSize.x, avSize.y,
ColorFormatToGL(aDataFormat), GL_UNSIGNED_BYTE, apPixelData));
}
//-----------------------------------------------------------------------
void cSDLTexture::Update(float afTimeStep) {
if (mvTextureHandles.size() > 1) {
float fMax = (float)(mvTextureHandles.size());
mfTimeCount += afTimeStep * (1.0f / mfFrameTime) * mfTimeDir;
if (mfTimeDir > 0) {
if (mfTimeCount >= fMax) {
if (mAnimMode == eTextureAnimMode_Loop) {
mfTimeCount = 0;
} else {
mfTimeCount = fMax - 1.0f;
mfTimeDir = -1.0f;
}
}
} else {
if (mfTimeCount < 0) {
mfTimeCount = 1;
mfTimeDir = 1.0f;
}
}
}
}
//-----------------------------------------------------------------------
bool cSDLTexture::HasAnimation() {
return mvTextureHandles.size() > 1;
}
void cSDLTexture::NextFrame() {
mfTimeCount += mfTimeDir;
if (mfTimeDir > 0) {
float fMax = (float)(mvTextureHandles.size());
if (mfTimeCount >= fMax) {
if (mAnimMode == eTextureAnimMode_Loop) {
mfTimeCount = 0;
} else {
mfTimeCount = fMax - 1.0f;
mfTimeDir = -1.0f;
}
}
} else {
if (mfTimeCount < 0) {
mfTimeCount = 1;
mfTimeDir = 1.0f;
}
}
}
void cSDLTexture::PrevFrame() {
mfTimeCount -= mfTimeDir;
if (mfTimeDir < 0) {
float fMax = (float)(mvTextureHandles.size());
if (mfTimeCount >= fMax) {
if (mAnimMode == eTextureAnimMode_Loop) {
mfTimeCount = 0;
} else {
mfTimeCount = fMax - 1.0f;
mfTimeDir = -1.0f;
}
}
} else {
if (mfTimeCount < 0) {
mfTimeCount = 1;
mfTimeDir = 1.0f;
}
}
}
float cSDLTexture::GetT() {
return cMath::Modulus(mfTimeCount, 1.0f);
}
float cSDLTexture::GetTimeCount() {
return mfTimeCount;
}
void cSDLTexture::SetTimeCount(float afX) {
mfTimeCount = afX;
}
int cSDLTexture::GetCurrentLowlevelHandle() {
return GetTextureHandle();
}
//-----------------------------------------------------------------------
void cSDLTexture::SetFilter(eTextureFilter aFilter) {
if (mFilter == aFilter)
return;
mFilter = aFilter;
if (mbContainsData) {
GLenum GLTarget = mpGfxSDL->GetGLTextureTargetEnum(mTarget);
GL_CHECK(glEnable(GLTarget));
for (size_t i = 0; i < mvTextureHandles.size(); ++i) {
glBindTexture(GLTarget, mvTextureHandles[i]);
if (mbUseMipMaps && mTarget != eTextureTarget_Rect) {
if (mFilter == eTextureFilter_Bilinear)
glTexParameteri(GLTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
else
glTexParameteri(GLTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(GLTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
GL_CHECK_FN();
GL_CHECK(glDisable(GLTarget));
}
}
//-----------------------------------------------------------------------
void cSDLTexture::SetAnisotropyDegree(float afX) {
// gl 4.6
#if 0
if(!mpLowLevelGraphics->GetCaps(eGraphicCaps_AnisotropicFiltering)) return;
if(afX < 1.0f) return;
if(afX > (float) mpLowLevelGraphics->GetCaps(eGraphicCaps_MaxAnisotropicFiltering)) return;
if(mfAnisotropyDegree == afX) return;
mfAnisotropyDegree = afX;
GLenum GLTarget = mpGfxSDL->GetGLTextureTargetEnum(mTarget);
glEnable(GLTarget);
for(size_t i=0; i < mvTextureHandles.size(); ++i)
{
glBindTexture(GLTarget, mvTextureHandles[i]);
glTexParameterf(GLTarget, GL_TEXTURE_MAX_ANISOTROPY ,mfAnisotropyDegree);
}
glDisable(GLTarget);
#endif
}
//-----------------------------------------------------------------------
void cSDLTexture::SetWrapS(eTextureWrap aMode) {
if (mbContainsData) {
GLenum GLTarget = mpGfxSDL->GetGLTextureTargetEnum(mTarget);
Hpl1::logInfo(Hpl1::kDebugTextures, "setting texture '%s' s wrap to %d\n", msName.c_str(), aMode);
GL_CHECK(glEnable(GLTarget));
for (size_t i = 0; i < mvTextureHandles.size(); ++i) {
glBindTexture(GLTarget, mvTextureHandles[i]);
glTexParameteri(GLTarget, GL_TEXTURE_WRAP_S, GetGLWrap(aMode));
}
GL_CHECK_FN();
GL_CHECK(glDisable(GLTarget));
}
}
//-----------------------------------------------------------------------
void cSDLTexture::SetWrapT(eTextureWrap aMode) {
if (mbContainsData) {
GLenum GLTarget = mpGfxSDL->GetGLTextureTargetEnum(mTarget);
Hpl1::logInfo(Hpl1::kDebugTextures, "setting texture '%s' t wrap to %d\n", msName.c_str(), aMode);
GL_CHECK(glEnable(GLTarget));
for (size_t i = 0; i < mvTextureHandles.size(); ++i) {
glBindTexture(GLTarget, mvTextureHandles[i]);
glTexParameteri(GLTarget, GL_TEXTURE_WRAP_T, GetGLWrap(aMode));
}
GL_CHECK(glDisable(GLTarget));
}
}
//-----------------------------------------------------------------------
void cSDLTexture::SetWrapR(eTextureWrap aMode) {
if (mbContainsData) {
GLenum GLTarget = mpGfxSDL->GetGLTextureTargetEnum(mTarget);
GL_CHECK(glEnable(GLTarget));
glEnable(GLTarget);
for (size_t i = 0; i < mvTextureHandles.size(); ++i) {
glBindTexture(GLTarget, mvTextureHandles[i]);
glTexParameteri(GLTarget, GL_TEXTURE_WRAP_R, GetGLWrap(aMode));
}
GL_CHECK(glDisable(GLTarget));
glDisable(GLTarget);
}
}
//-----------------------------------------------------------------------
unsigned int cSDLTexture::GetTextureHandle() {
if (mvTextureHandles.size() > 1) {
int lFrame = (int)mfTimeCount;
return mvTextureHandles[lFrame];
} else {
return mvTextureHandles[0];
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cSDLTexture::CreateFromBitmapToHandle(Bitmap2D *pBmp, int alHandleIdx) {
if (mType == eTextureType_RenderTarget)
error("trying to create a rendertarget in SDLTexture::CreateBitmapToHandle");
// For some reason checking for ARB texture is not working on radeon cards.
/*if(mTarget == eTextureTarget_Rect && !GLEE_ARB_texture_rectangle)
{
Error("Rectangle texture target not supported\n");
return false;
}*/
GLenum GLTarget = InitCreation(alHandleIdx);
Bitmap2D *pBitmapSrc = pBmp;
_width = pBitmapSrc->getWidth();
_height = pBitmapSrc->getHeight();
if ((!cMath::IsPow2(_height) || !cMath::IsPow2(_width)) && mTarget != eTextureTarget_Rect)
Hpl1::logWarning(Hpl1::kDebugTextures, "Texture '%s' does not have a pow2 size", msName.c_str());
int lChannels = 0;
GLint internalFormat = 0;
GLenum format = 0;
getSettings(pBitmapSrc, lChannels, internalFormat, format);
_bpp = lChannels * 8;
const unsigned char *pPixelSrc = (const unsigned char *)pBitmapSrc->getRawData();
unsigned char *pNewSrc = nullptr;
if (mlSizeLevel > 0 && (int)_width > mvMinLevelSize.x * 2) {
// Log("OldSize: %d x %d ",mlWidth,mlHeight);
int lOldW = _width;
// int lOldH = _height;
int lSizeDiv = (int)pow((float)2, (int)mlSizeLevel);
_width /= lSizeDiv;
_height /= lSizeDiv;
while (_width < (unsigned int)mvMinLevelSize.x) {
_width *= 2;
_height *= 2;
lSizeDiv /= 2;
}
// Log("NewSize: %d x %d SizeDiv: %d\n",mlWidth,mlHeight,lSizeDiv);
pNewSrc = hplNewArray(unsigned char, lChannels *_width *_height);
int lWidthCount = _width;
int lHeightCount = _height;
int lOldAdd = lChannels * lSizeDiv;
int lOldHeightAdd = lChannels * lOldW * (lSizeDiv - 1);
const unsigned char *pOldPixel = pPixelSrc;
unsigned char *pNewPixel = pNewSrc;
while (lHeightCount) {
memcpy(pNewPixel, pOldPixel, lChannels);
pOldPixel += lOldAdd;
pNewPixel += lChannels;
lWidthCount--;
if (!lWidthCount) {
lWidthCount = _width;
lHeightCount--;
pOldPixel += lOldHeightAdd;
}
}
pPixelSrc = pNewSrc;
}
// Log("Loading %s %d x %d\n",msName.c_str(), pSrc->GetWidth(), pSrc->GetHeight());
// Log("Channels: %d Format: %x\n",lChannels, format);
// Clear error flags
GL_CHECK_FN();
if (mTarget == eTextureTarget_1D)
glTexImage1D(GLTarget, 0, internalFormat, _width, 0, format,
GL_UNSIGNED_BYTE, pPixelSrc);
else
glTexImage2D(GLTarget, 0, internalFormat, _width, _height,
0, format, GL_UNSIGNED_BYTE, pPixelSrc);
if (glGetError() != GL_NO_ERROR)
return false;
if (mbUseMipMaps && mTarget != eTextureTarget_Rect)
generateMipmaps(mTarget);
PostCreation(GLTarget);
if (mlSizeLevel > 0 && pNewSrc)
hplDeleteArray(pNewSrc);
return true;
}
//-----------------------------------------------------------------------
GLenum cSDLTexture::InitCreation(int alHandleIdx) {
GLenum GLTarget = mpGfxSDL->GetGLTextureTargetEnum(mTarget);
GL_CHECK(glEnable(GLTarget));
GL_CHECK(glBindTexture(GLTarget, mvTextureHandles[alHandleIdx]));
return GLTarget;
}
//-----------------------------------------------------------------------
void cSDLTexture::PostCreation(GLenum aGLTarget) {
if (mbUseMipMaps && mTarget != eTextureTarget_Rect) {
if (mFilter == eTextureFilter_Bilinear)
glTexParameteri(aGLTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
else
glTexParameteri(aGLTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(aGLTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
GL_CHECK_FN();
GL_CHECK(glTexParameteri(aGLTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
if (aGLTarget != GL_TEXTURE_RECTANGLE) {
GL_CHECK(glTexParameteri(aGLTarget, GL_TEXTURE_WRAP_S, GL_REPEAT));
GL_CHECK(glTexParameteri(aGLTarget, GL_TEXTURE_WRAP_T, GL_REPEAT));
GL_CHECK(glTexParameteri(aGLTarget, GL_TEXTURE_WRAP_R, GL_REPEAT));
}
GL_CHECK(glDisable(aGLTarget));
mbContainsData = true;
}
//-----------------------------------------------------------------------
GLenum cSDLTexture::GetGLWrap(eTextureWrap aMode) {
switch (aMode) {
case eTextureWrap_Clamp:
return GL_CLAMP;
case eTextureWrap_Repeat:
return GL_REPEAT;
case eTextureWrap_ClampToEdge:
return GL_CLAMP_TO_EDGE;
case eTextureWrap_ClampToBorder:
return GL_CLAMP_TO_BORDER;
default:
break;
}
return GL_REPEAT;
}
//-----------------------------------------------------------------------
} // namespace hpl
#endif // HPL1_USE_OPENGL

View File

@@ -0,0 +1,106 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SDL_TEXTURE_H
#define HPL_SDL_TEXTURE_H
#include "common/scummsys.h"
#include "hpl1/engine/graphics/Texture.h"
#include "hpl1/engine/graphics/bitmap2D.h"
#include "hpl1/engine/impl/LowLevelGraphicsSDL.h"
#include "hpl1/opengl.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
class cSDLTexture : public iTexture {
public:
cSDLTexture(const tString &asName, Graphics::PixelFormat *apPxlFmt, iLowLevelGraphics *apLowLevelGraphics,
eTextureType aType, bool abUseMipMaps, eTextureTarget aTarget,
bool abCompress = false);
~cSDLTexture();
bool CreateFromBitmap(Bitmap2D *pBmp);
bool CreateAnimFromBitmapVec(tBitmap2DVec *avBitmaps);
bool CreateCubeFromBitmapVec(tBitmap2DVec *avBitmaps);
bool Create(unsigned int alWidth, unsigned int alHeight, cColor aCol);
bool CreateFromArray(unsigned char *apPixelData, int alChannels, const cVector3l &avSize);
void SetPixels2D(int alLevel, const cVector2l &avOffset, const cVector2l &avSize,
eColorDataFormat aDataFormat, void *apPixelData);
float GetGamma() { return 0; }
void SetGamma(float afGamma) {}
int GetHandle() { return (int)mvTextureHandles[0]; }
void SetFilter(eTextureFilter aFilter);
void SetAnisotropyDegree(float afX);
void SetWrapS(eTextureWrap aMode);
void SetWrapT(eTextureWrap aMode);
void SetWrapR(eTextureWrap aMode);
void Update(float afTimeStep);
bool HasAnimation();
void NextFrame();
void PrevFrame();
float GetT();
float GetTimeCount();
void SetTimeCount(float afX);
int GetCurrentLowlevelHandle();
/// SDL / OGL Specific ///////////
unsigned int GetTextureHandle();
// cPBuffer *GetPBuffer() { return mpPBuffer; }
private:
bool CreateFromBitmapToHandle(Bitmap2D *pBmp, int alHandleIdx);
GLenum InitCreation(int alHandleIdx);
void PostCreation(GLenum aGLTarget);
GLenum GetGLWrap(eTextureWrap aMode);
tUIntVec mvTextureHandles;
bool mbContainsData;
cLowLevelGraphicsSDL *mpGfxSDL;
float mfTimeCount;
int mlTextureIndex;
float mfTimeDir;
};
} // namespace hpl
#endif // HPL1_USE_OPENGL
#endif // HPL_SDL_TEXTURE_H

View File

@@ -0,0 +1,147 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/SqScript.h"
#include "common/file.h"
#include "hpl1/debug.h"
#include "hpl1/engine/libraries/angelscript/add-ons/scripthelper.h"
#include "hpl1/engine/libraries/angelscript/angelscript.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSqScript::cSqScript(const tString &asName, asIScriptEngine *apScriptEngine, int alHandle)
: iScript(asName) {
mpScriptEngine = apScriptEngine;
mlHandle = alHandle;
mpContext = mpScriptEngine->CreateContext();
// Create a unique module name
msModuleName = "Module_" + cString::ToString(cMath::RandRectl(0, 1000000)) +
"_" + cString::ToString(mlHandle);
}
cSqScript::~cSqScript() {
_module->Discard();
mpContext->Release();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cSqScript::CreateFromFile(const tString &asFileName) {
int lLength;
char *pCharBuffer = LoadCharBuffer(asFileName, lLength);
if (pCharBuffer == nullptr) {
Error("Couldn't load script '%s'!\n", asFileName.c_str());
return false;
}
_module = mpScriptEngine->GetModule(msModuleName.c_str(), asGM_ALWAYS_CREATE);
if (_module->AddScriptSection(msModuleName.c_str(), pCharBuffer, lLength) < 0) {
Error("Couldn't add script '%s'!\n", asFileName.c_str());
hplDeleteArray(pCharBuffer);
return false;
}
if (_module->Build() < 0) {
Hpl1::logError(Hpl1::kDebugSaves, "Couldn't build script '%s'!\n", asFileName.c_str());
hplDeleteArray(pCharBuffer);
return false;
}
hplDeleteArray(pCharBuffer);
return true;
}
//-----------------------------------------------------------------------
int cSqScript::GetFuncHandle(const tString &asFunc) {
return _module->GetFunctionByName(asFunc.c_str())->GetId();
}
//-----------------------------------------------------------------------
void cSqScript::AddArg(const tString &asArg) {
}
//-----------------------------------------------------------------------
bool cSqScript::Run(const tString &asFuncLine) {
ExecuteString(mpScriptEngine, asFuncLine.c_str(), _module);
return true;
}
//-----------------------------------------------------------------------
bool cSqScript::Run(int alHandle) {
error("call to unimplemented function cSqScript::run(int)");
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
char *cSqScript::LoadCharBuffer(const tString &asFileName, int &alLength) {
Common::File file;
file.open(Common::Path(asFileName));
if (!file.isOpen()) {
debugCN(Hpl1::kDebugLevelError, Hpl1::kDebugFilePath,
"script file at %s could not be opened", asFileName.c_str());
return nullptr;
}
alLength = file.size();
char *pBuffer = hplNewArray(char, alLength);
file.read(pBuffer, alLength);
if (file.err()) {
debugCN(Hpl1::kDebugLevelError, Hpl1::kDebugResourceLoading,
"error in reading script file %s", asFileName.c_str());
return nullptr;
}
return pBuffer;
}
} // namespace hpl

View File

@@ -0,0 +1,63 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SQ_SCRIPT_H
#define HPL_SQ_SCRIPT_H
#include "hpl1/engine/libraries/angelscript/angelscript.h"
#include "hpl1/engine/system/Script.h"
namespace hpl {
class cSqScript : public iScript {
public:
cSqScript(const tString &asName, asIScriptEngine *apScriptEngine, int alHandle);
~cSqScript();
bool CreateFromFile(const tString &asFileName);
int GetFuncHandle(const tString &asFunc);
void AddArg(const tString &asArg);
bool Run(const tString &asFuncLine);
bool Run(int alHandle);
private:
asIScriptEngine *mpScriptEngine;
asIScriptModule *_module;
asIScriptContext *mpContext;
int mlHandle;
tString msModuleName;
char *LoadCharBuffer(const tString &asFileName, int &alLength);
};
} // namespace hpl
#endif // HPL_SCRIPT_H

View File

@@ -0,0 +1,510 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/VertexBufferOGL.h"
#include "hpl1/debug.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/low_level_system.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cVertexBufferOGL::cVertexBufferOGL(iLowLevelGraphics *apLowLevelGraphics, tVertexFlag aFlags,
eVertexBufferDrawType aDrawType, eVertexBufferUsageType aUsageType,
int alReserveVtxSize, int alReserveIdxSize) : iVertexBuffer(apLowLevelGraphics, aFlags, aDrawType, aUsageType, alReserveVtxSize, alReserveIdxSize) {
error("trying to create VertexBufferOGL");
if (alReserveVtxSize > 0) {
for (int i = 0; i < klNumOfVertexFlags; i++) {
if (aFlags & kvVertexFlags[i]) {
mvVertexArray[i].reserve(alReserveVtxSize * kvVertexElements[i]);
}
}
}
if (alReserveIdxSize > 0)
mvIndexArray.reserve(alReserveIdxSize);
mbTangents = false;
mbHasShadowDouble = false;
mpLowLevelGraphics = apLowLevelGraphics;
}
cVertexBufferOGL::~cVertexBufferOGL() {
for (int i = 0; i < klNumOfVertexFlags; i++)
mvVertexArray[i].clear();
mvIndexArray.clear();
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cVertexBufferOGL::AddVertex(tVertexFlag aType, const cVector3f &avVtx) {
int idx = cMath::Log2ToInt((int)aType);
mvVertexArray[idx].push_back(avVtx.x);
mvVertexArray[idx].push_back(avVtx.y);
mvVertexArray[idx].push_back(avVtx.z);
if (kvVertexElements[idx] == 4)
mvVertexArray[idx].push_back(1);
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::AddColor(tVertexFlag aType, const cColor &aColor) {
int idx = cMath::Log2ToInt((int)aType);
mvVertexArray[idx].push_back(aColor.r);
mvVertexArray[idx].push_back(aColor.g);
mvVertexArray[idx].push_back(aColor.b);
mvVertexArray[idx].push_back(aColor.a);
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::AddIndex(unsigned int alIndex) {
mvIndexArray.push_back(alIndex);
}
//-----------------------------------------------------------------------
bool cVertexBufferOGL::Compile(tVertexCompileFlag aFlags) {
if (aFlags & eVertexCompileFlag_CreateTangents) {
mbTangents = true;
mVertexFlags |= eVertexFlag_Texture1;
int idx = cMath::Log2ToInt((int)eVertexFlag_Texture1);
int lSize = GetVertexNum() * 4;
mvVertexArray[idx].resize(lSize);
cMath::CreateTriTangentVectors(&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Texture1)][0]),
&mvIndexArray[0], GetIndexNum(),
&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Position)][0]),
kvVertexElements[cMath::Log2ToInt((int)eVertexFlag_Position)],
&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Texture0)][0]),
&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Normal)][0]),
GetVertexNum());
}
return true;
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::UpdateData(tVertexFlag aTypes, bool abIndices) {
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::CreateShadowDouble(bool abUpdateData) {
int lIdx = cMath::Log2ToInt(eVertexFlag_Position);
// Set to new size.
int lSize = (int)mvVertexArray[lIdx].size();
mvVertexArray[lIdx].reserve(lSize * 2);
int lCount = lSize / 4;
for (int i = 0; i < lCount; i++) {
mvVertexArray[lIdx].push_back(mvVertexArray[lIdx][i * 4 + 0]);
mvVertexArray[lIdx].push_back(mvVertexArray[lIdx][i * 4 + 1]);
mvVertexArray[lIdx].push_back(mvVertexArray[lIdx][i * 4 + 2]);
mvVertexArray[lIdx].push_back(0); // 0);
}
mbHasShadowDouble = true;
if (abUpdateData) {
UpdateData(eVertexFlag_Position, false);
}
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::Transform(const cMatrixf &a_mtxTransform) {
float *pPosArray = GetArray(eVertexFlag_Position);
float *pNormalArray = GetArray(eVertexFlag_Normal);
float *pTangentArray = NULL;
if (mbTangents)
pTangentArray = GetArray(eVertexFlag_Texture1);
int lVtxNum = GetVertexNum();
cMatrixf mtxRot = a_mtxTransform.GetRotation();
int lVtxStride = kvVertexElements[cMath::Log2ToInt(eVertexFlag_Position)];
int lOffset = GetVertexNum() * 4;
for (int i = 0; i < lVtxNum; i++) {
float *pPos = &pPosArray[i * lVtxStride];
float *pNorm = &pNormalArray[i * 3];
float *pTan = NULL;
if (mbTangents)
pTan = &pTangentArray[i * 4];
cVector3f vPos = cMath::MatrixMul(a_mtxTransform, cVector3f(pPos[0], pPos[1], pPos[2]));
pPos[0] = vPos.x;
pPos[1] = vPos.y;
pPos[2] = vPos.z;
if (mbHasShadowDouble) {
float *pExtraPos = &pPosArray[i * lVtxStride + lOffset];
pExtraPos[0] = vPos.x;
pExtraPos[1] = vPos.y;
pExtraPos[2] = vPos.z;
}
cVector3f vNorm = cMath::MatrixMul(mtxRot, cVector3f(pNorm[0], pNorm[1], pNorm[2]));
vNorm.Normalise();
pNorm[0] = vNorm.x;
pNorm[1] = vNorm.y;
pNorm[2] = vNorm.z;
if (mbTangents) {
cVector3f vTan = cMath::MatrixMul(mtxRot, cVector3f(pTan[0], pTan[1], pTan[2]));
vTan.Normalise();
pTan[0] = vTan.x;
pTan[1] = vTan.y;
pTan[2] = vTan.z;
}
}
if (mbTangents)
UpdateData(eVertexFlag_Position | eVertexFlag_Normal | eVertexFlag_Texture1, false);
else
UpdateData(eVertexFlag_Position | eVertexFlag_Normal, false);
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::Draw(eVertexBufferDrawType aDrawType) {
#if 0
eVertexBufferDrawType drawType = aDrawType == eVertexBufferDrawType_LastEnum ? mDrawType : aDrawType;
///////////////////////////////
//Get the draw type
GLenum mode = GL_TRIANGLES;
if(drawType==eVertexBufferDrawType_Quad) mode = GL_QUADS;
else if(drawType==eVertexBufferDrawType_Lines) mode = GL_LINE_STRIP;
int lSize = mlElementNum;
if(mlElementNum<0) lSize = GetIndexNum();
glDrawElements(mode,lSize,GL_UNSIGNED_INT, &mvIndexArray[0]);
#endif
}
void cVertexBufferOGL::DrawIndices(unsigned int *apIndices, int alCount,
eVertexBufferDrawType aDrawType) {
#if 0
eVertexBufferDrawType drawType = aDrawType == eVertexBufferDrawType_LastEnum ? mDrawType : aDrawType;
///////////////////////////////
//Get the draw type
GLenum mode = GL_TRIANGLES;
if(drawType==eVertexBufferDrawType_Quad) mode = GL_QUADS;
else if(drawType==eVertexBufferDrawType_Lines) mode = GL_LINE_STRIP;
//////////////////////////////////
//Bind and draw the buffer
glDrawElements(mode, alCount, GL_UNSIGNED_INT, apIndices);
#endif
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::Bind() {
SetVertexStates(mVertexFlags);
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::UnBind() {
}
//-----------------------------------------------------------------------
iVertexBuffer *cVertexBufferOGL::CreateCopy(eVertexBufferUsageType aUsageType) {
cVertexBufferOGL *pVtxBuff = hplNew(cVertexBufferOGL, (mpLowLevelGraphics,
mVertexFlags, mDrawType, aUsageType,
GetVertexNum(), GetIndexNum()));
// Copy the vertices to the new buffer.
for (int i = 0; i < klNumOfVertexFlags; i++) {
if (kvVertexFlags[i] & mVertexFlags) {
#if 0
int lElements = kvVertexElements[i];
if (mbTangents && kvVertexFlags[i] == eVertexFlag_Texture1)
lElements = 4;
#endif
pVtxBuff->ResizeArray(kvVertexFlags[i], (int)mvVertexArray[i].size());
memcpy(pVtxBuff->GetArray(kvVertexFlags[i]),
&mvVertexArray[i][0], mvVertexArray[i].size() * sizeof(float));
}
}
// Copy indices to the new buffer
pVtxBuff->ResizeIndices(GetIndexNum());
memcpy(pVtxBuff->GetIndices(), GetIndices(), GetIndexNum() * sizeof(unsigned int));
pVtxBuff->mbTangents = mbTangents;
pVtxBuff->mbHasShadowDouble = mbHasShadowDouble;
pVtxBuff->Compile(0);
return pVtxBuff;
}
//-----------------------------------------------------------------------
cBoundingVolume cVertexBufferOGL::CreateBoundingVolume() {
cBoundingVolume bv;
int lNum = cMath::Log2ToInt((int)eVertexFlag_Position);
bv.AddArrayPoints(&(mvVertexArray[lNum][0]), GetVertexNum());
bv.CreateFromPoints(kvVertexElements[cMath::Log2ToInt(eVertexFlag_Position)]);
return bv;
}
float *cVertexBufferOGL::GetArray(tVertexFlag aType) {
int idx = cMath::Log2ToInt((int)aType);
return &mvVertexArray[idx][0];
}
//-----------------------------------------------------------------------
unsigned int *cVertexBufferOGL::GetIndices() {
return &mvIndexArray[0];
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::ResizeArray(tVertexFlag aType, int alSize) {
int idx = cMath::Log2ToInt((int)aType);
mvVertexArray[idx].resize(alSize);
}
//-----------------------------------------------------------------------
void cVertexBufferOGL::ResizeIndices(int alSize) {
mvIndexArray.resize(alSize);
}
//-----------------------------------------------------------------------
int cVertexBufferOGL::GetVertexNum() {
int idx = cMath::Log2ToInt((int)eVertexFlag_Position);
int lSize = (int)mvVertexArray[idx].size() / kvVertexElements[idx];
// If there is a shadow double, just return the length of the first half.
if (mbHasShadowDouble)
return lSize / 2;
else
return lSize;
}
int cVertexBufferOGL::GetIndexNum() {
return (int)mvIndexArray.size();
}
cVector3f cVertexBufferOGL::GetVector3(tVertexFlag aType, unsigned alIdx) {
if (!(aType & mVertexFlags))
return cVector3f(0, 0, 0);
int idx = cMath::Log2ToInt((int)aType);
int pos = alIdx * kvVertexElements[idx];
return cVector3f(mvVertexArray[idx][pos + 0], mvVertexArray[idx][pos + 1],
mvVertexArray[idx][pos + 2]);
}
cVector3f cVertexBufferOGL::GetVector4(tVertexFlag aType, unsigned alIdx) {
if (!(aType & mVertexFlags))
return cVector3f(0, 0, 0);
int idx = cMath::Log2ToInt((int)aType);
int pos = alIdx * 4; // kvVertexElements[idx];
return cVector3f(mvVertexArray[idx][pos + 0], mvVertexArray[idx][pos + 1],
mvVertexArray[idx][pos + 2]);
}
cColor cVertexBufferOGL::GetColor(tVertexFlag aType, unsigned alIdx) {
if (!(aType & mVertexFlags))
return cColor();
int idx = cMath::Log2ToInt((int)aType);
int pos = alIdx * kvVertexElements[idx];
return cColor(mvVertexArray[idx][pos + 0], mvVertexArray[idx][pos + 1],
mvVertexArray[idx][pos + 2], mvVertexArray[idx][pos + 3]);
}
unsigned int cVertexBufferOGL::GetIndex(tVertexFlag aType, unsigned alIdx) {
return mvIndexArray[alIdx];
}
//-----------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
/////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cVertexBufferOGL::SetVertexStates(tVertexFlag aFlags) {
#if 0
/// POSITION /////////////////////////
if(aFlags & eVertexFlag_Position){
glEnableClientState(GL_VERTEX_ARRAY );
int idx = cMath::Log2ToInt(eVertexFlag_Position);
glVertexPointer(kvVertexElements[idx],GL_FLOAT, sizeof(float)*kvVertexElements[idx], &mvVertexArray[idx][0]);
}
else
{
glDisableClientState(GL_VERTEX_ARRAY );
}
/// COLOR 0 /////////////////////////
if(aFlags & eVertexFlag_Color0)
{
glEnableClientState(GL_COLOR_ARRAY );
int idx = cMath::Log2ToInt(eVertexFlag_Color0);
glColorPointer(kvVertexElements[idx],GL_FLOAT, sizeof(float)*kvVertexElements[idx], &mvVertexArray[idx][0]);
}
else
{
glDisableClientState(GL_COLOR_ARRAY );
}
/// NORMAL /////////////////////////
if(aFlags & eVertexFlag_Normal)
{
glEnableClientState(GL_NORMAL_ARRAY );
glNormalPointer(GL_FLOAT, sizeof(float)*3, &mvVertexArray[cMath::Log2ToInt(eVertexFlag_Normal)][0]);
}
else
{
glDisableClientState(GL_NORMAL_ARRAY );
}
/// TEXTURE 0 /////////////////////////
if(aFlags & eVertexFlag_Texture0)
{
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY );
int idx = cMath::Log2ToInt(eVertexFlag_Texture0);
glTexCoordPointer(kvVertexElements[idx],GL_FLOAT,sizeof(float)*kvVertexElements[idx],&mvVertexArray[idx][0] );
}
else {
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY );
}
/// TEXTURE 1 /////////////////////////
if(aFlags & eVertexFlag_Texture1){
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY );
int idx = cMath::Log2ToInt(eVertexFlag_Texture1);
if(mbTangents)
glTexCoordPointer(4,GL_FLOAT,sizeof(float)*4,&mvVertexArray[idx][0] );
else
glTexCoordPointer(kvVertexElements[idx],GL_FLOAT,sizeof(float)*kvVertexElements[idx],&mvVertexArray[idx][0] );
}
else {
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY );
}
/// TEXTURE 2 /////////////////////////
if(aFlags & eVertexFlag_Texture2){
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY );
int idx = cMath::Log2ToInt(eVertexFlag_Texture2);
glTexCoordPointer(kvVertexElements[idx],GL_FLOAT,sizeof(float)*kvVertexElements[idx],&mvVertexArray[idx][0] );
}
else {
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY );
}
/// TEXTURE 3 /////////////////////////
if(aFlags & eVertexFlag_Texture3){
glClientActiveTextureARB(GL_TEXTURE3_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY );
int idx = cMath::Log2ToInt(eVertexFlag_Texture3);
glTexCoordPointer(kvVertexElements[idx],GL_FLOAT,sizeof(float)*kvVertexElements[idx],&mvVertexArray[idx][0] );
}
else {
glClientActiveTextureARB(GL_TEXTURE3_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY );
}
/// TEXTURE 4 /////////////////////////
if(aFlags & eVertexFlag_Texture4){
glClientActiveTextureARB(GL_TEXTURE4_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY );
int idx = cMath::Log2ToInt(eVertexFlag_Texture4);
glTexCoordPointer(kvVertexElements[idx],GL_FLOAT,sizeof(float)*kvVertexElements[idx],&mvVertexArray[idx][0] );
}
else {
glClientActiveTextureARB(GL_TEXTURE4_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY );
}
#endif
}
//-----------------------------------------------------------------------
} // namespace hpl
#endif // HPL1_USE_OPENGL

View File

@@ -0,0 +1,97 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_VERTEXBUFFER_OGL_H
#define HPL_VERTEXBUFFER_OGL_H
#include "common/scummsys.h"
#include "hpl1/engine/graphics/VertexBuffer.h"
#include "hpl1/opengl.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
class cVertexBufferOGL : public iVertexBuffer {
public:
cVertexBufferOGL(iLowLevelGraphics *apLowLevelGraphics, tVertexFlag aFlags,
eVertexBufferDrawType aDrawType, eVertexBufferUsageType aUsageType,
int alReserveVtxSize, int alReserveIdxSize);
~cVertexBufferOGL();
void AddVertex(tVertexFlag aType, const cVector3f &avVtx);
void AddColor(tVertexFlag aType, const cColor &aColor);
void AddIndex(unsigned int alIndex);
bool Compile(tVertexCompileFlag aFlags);
void UpdateData(tVertexFlag aTypes, bool abIndices);
void CreateShadowDouble(bool abUpdateData);
void Transform(const cMatrixf &mtxTransform);
void Draw(eVertexBufferDrawType aDrawType);
void DrawIndices(unsigned int *apIndices, int alCount,
eVertexBufferDrawType aDrawType = eVertexBufferDrawType_LastEnum);
void Bind();
void UnBind();
iVertexBuffer *CreateCopy(eVertexBufferUsageType aUsageType);
cBoundingVolume CreateBoundingVolume();
float *GetArray(tVertexFlag aType);
unsigned int *GetIndices();
void ResizeArray(tVertexFlag aType, int alSize);
void ResizeIndices(int alSize);
// For debugging purposes
int GetVertexNum();
int GetIndexNum();
cVector3f GetVector3(tVertexFlag aType, unsigned alIdx);
cVector3f GetVector4(tVertexFlag aType, unsigned alIdx);
cColor GetColor(tVertexFlag aType, unsigned alIdx);
unsigned int GetIndex(tVertexFlag aType, unsigned alIdx);
private:
void SetVertexStates(tVertexFlag aFlags);
tFloatVec mvVertexArray[klNumOfVertexFlags];
tUIntVec mvIndexArray;
bool mbTangents;
bool mbHasShadowDouble;
};
} // namespace hpl
#endif // HPL1_USE_OPENGL
#endif // HPL_RENDERER3D_OGL_H

View File

@@ -0,0 +1,685 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/impl/VertexBufferVBO.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/system/low_level_system.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
#define BUFFER_OFFSET(i) ((void *)(i * sizeof(float)))
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cVertexBufferVBO::cVertexBufferVBO(iLowLevelGraphics *apLowLevelGraphics, tVertexFlag aFlags,
eVertexBufferDrawType aDrawType, eVertexBufferUsageType aUsageType,
int alReserveVtxSize, int alReserveIdxSize) : iVertexBuffer(apLowLevelGraphics, aFlags, aDrawType, aUsageType, alReserveVtxSize, alReserveIdxSize) {
if (alReserveVtxSize > 0) {
for (int i = 0; i < klNumOfVertexFlags; i++) {
if (aFlags & kvVertexFlags[i]) {
mvVertexArray[i].reserve(alReserveVtxSize * kvVertexElements[i]);
}
mvArrayHandle[i] = 0;
}
}
if (alReserveIdxSize > 0)
mvIndexArray.reserve(alReserveIdxSize);
mlElementHandle = 0;
mbTangents = false;
mbCompiled = false;
mbHasShadowDouble = false;
mpLowLevelGraphics = apLowLevelGraphics;
}
cVertexBufferVBO::~cVertexBufferVBO() {
for (int i = 0; i < klNumOfVertexFlags; i++) {
mvVertexArray[i].clear();
if (mVertexFlags & kvVertexFlags[i]) {
glDeleteBuffers(1, (GLuint *)&mvArrayHandle[i]);
}
}
GL_CHECK_FN();
mvIndexArray.clear();
GL_CHECK(glDeleteBuffers(1, (GLuint *)&mlElementHandle));
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cVertexBufferVBO::AddVertex(tVertexFlag aType, const cVector3f &avVtx) {
int idx = cMath::Log2ToInt((int)aType);
mvVertexArray[idx].push_back(avVtx.x);
mvVertexArray[idx].push_back(avVtx.y);
mvVertexArray[idx].push_back(avVtx.z);
if (kvVertexElements[idx] == 4)
mvVertexArray[idx].push_back(1);
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::AddColor(tVertexFlag aType, const cColor &aColor) {
int idx = cMath::Log2ToInt((int)aType);
mvVertexArray[idx].push_back(aColor.r);
mvVertexArray[idx].push_back(aColor.g);
mvVertexArray[idx].push_back(aColor.b);
mvVertexArray[idx].push_back(aColor.a);
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::AddIndex(unsigned int alIndex) {
mvIndexArray.push_back(alIndex);
}
//-----------------------------------------------------------------------
cBoundingVolume cVertexBufferVBO::CreateBoundingVolume() {
cBoundingVolume bv;
int lNum = cMath::Log2ToInt((int)eVertexFlag_Position);
bv.AddArrayPoints(mvVertexArray[lNum].data(), GetVertexNum());
bv.CreateFromPoints(kvVertexElements[cMath::Log2ToInt(eVertexFlag_Position)]);
return bv;
}
//-----------------------------------------------------------------------
bool cVertexBufferVBO::Compile(tVertexCompileFlag aFlags) {
if (mbCompiled)
return false;
mbCompiled = true;
// Create tangents
if (aFlags & eVertexCompileFlag_CreateTangents) {
mbTangents = true;
mVertexFlags |= eVertexFlag_Texture1;
int idx = cMath::Log2ToInt((int)eVertexFlag_Texture1);
int lSize = GetVertexNum() * 4;
mvVertexArray[idx].resize(lSize);
cMath::CreateTriTangentVectors(&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Texture1)][0]),
&mvIndexArray[0], GetIndexNum(),
&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Position)][0]),
kvVertexElements[cMath::Log2ToInt((int)eVertexFlag_Position)],
&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Texture0)][0]),
&(mvVertexArray[cMath::Log2ToInt((int)eVertexFlag_Normal)][0]),
GetVertexNum());
}
GLenum usageType = GL_STATIC_DRAW;
if (mUsageType == eVertexBufferUsageType_Dynamic)
usageType = GL_DYNAMIC_DRAW;
else if (mUsageType == eVertexBufferUsageType_Stream)
usageType = GL_STREAM_DRAW;
// Create the VBO vertex arrays
for (int i = 0; i < klNumOfVertexFlags; i++) {
if (mVertexFlags & kvVertexFlags[i]) {
glGenBuffers(1, (GLuint *)&mvArrayHandle[i]);
glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[i]);
glBufferData(GL_ARRAY_BUFFER, mvVertexArray[i].size() * sizeof(float),
mvVertexArray[i].data(), usageType);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Log("%d-Handle: %d, size: %d \n",i,mvArrayHandle[i], mvVertexArray);
}
}
GL_CHECK_FN();
// Create the VBO index array
GL_CHECK(glGenBuffers(1, (GLuint *)&mlElementHandle));
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mlElementHandle));
GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexNum() * sizeof(unsigned int),
mvIndexArray.data(), usageType));
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
// Log("VBO compile done!\n");
return true;
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::UpdateData(tVertexFlag aTypes, bool abIndices) {
GLenum usageType = GL_STATIC_DRAW;
if (mUsageType == eVertexBufferUsageType_Dynamic)
usageType = GL_DYNAMIC_DRAW;
else if (mUsageType == eVertexBufferUsageType_Stream)
usageType = GL_STREAM_DRAW;
// Create the VBO vertex arrays
for (int i = 0; i < klNumOfVertexFlags; i++) {
if ((mVertexFlags & kvVertexFlags[i]) && (aTypes & kvVertexFlags[i])) {
glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[i]);
// This was apparently VERY slow.
glBufferData(GL_ARRAY_BUFFER, mvVertexArray[i].size() * sizeof(float),
NULL, usageType); // Clear memory
glBufferData(GL_ARRAY_BUFFER, mvVertexArray[i].size() * sizeof(float),
mvVertexArray[i].data(), usageType);
}
}
GL_CHECK_FN();
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
// Create the VBO index array
if (abIndices) {
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mlElementHandle));
// glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER,GetIndexNum()*sizeof(unsigned int),
// NULL, usageType);
GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexNum() * sizeof(unsigned int),
mvIndexArray.data(), usageType));
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::CreateShadowDouble(bool abUpdateData) {
int lIdx = cMath::Log2ToInt(eVertexFlag_Position);
// Set to new size.
int lSize = (int)mvVertexArray[lIdx].size();
mvVertexArray[lIdx].reserve(lSize * 2);
int lCount = lSize / 4;
for (int i = 0; i < lCount; i++) {
mvVertexArray[lIdx].push_back(mvVertexArray[lIdx][i * 4 + 0]);
mvVertexArray[lIdx].push_back(mvVertexArray[lIdx][i * 4 + 1]);
mvVertexArray[lIdx].push_back(mvVertexArray[lIdx][i * 4 + 2]);
mvVertexArray[lIdx].push_back(0); // 0);
}
mbHasShadowDouble = true;
if (abUpdateData) {
UpdateData(eVertexFlag_Position, false);
}
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::Transform(const cMatrixf &a_mtxTransform) {
float *pPosArray = GetArray(eVertexFlag_Position);
float *pNormalArray = GetArray(eVertexFlag_Normal);
float *pTangentArray = NULL;
if (mbTangents)
pTangentArray = GetArray(eVertexFlag_Texture1);
int lVtxNum = GetVertexNum();
cMatrixf mtxRot = a_mtxTransform.GetRotation();
int lVtxStride = kvVertexElements[cMath::Log2ToInt(eVertexFlag_Position)];
int lOffset = GetVertexNum() * 4;
for (int i = 0; i < lVtxNum; i++) {
float *pPos = &pPosArray[i * lVtxStride];
float *pNorm = &pNormalArray[i * 3];
float *pTan = NULL;
if (mbTangents)
pTan = &pTangentArray[i * 4];
cVector3f vPos = cMath::MatrixMul(a_mtxTransform, cVector3f(pPos[0], pPos[1], pPos[2]));
pPos[0] = vPos.x;
pPos[1] = vPos.y;
pPos[2] = vPos.z;
if (mbHasShadowDouble) {
float *pExtraPos = &pPosArray[i * lVtxStride + lOffset];
pExtraPos[0] = vPos.x;
pExtraPos[1] = vPos.y;
pExtraPos[2] = vPos.z;
}
cVector3f vNorm = cMath::MatrixMul(mtxRot, cVector3f(pNorm[0], pNorm[1], pNorm[2]));
vNorm.Normalise();
pNorm[0] = vNorm.x;
pNorm[1] = vNorm.y;
pNorm[2] = vNorm.z;
if (mbTangents) {
cVector3f vTan = cMath::MatrixMul(mtxRot, cVector3f(pTan[0], pTan[1], pTan[2]));
vTan.Normalise();
pTan[0] = vTan.x;
pTan[1] = vTan.y;
pTan[2] = vTan.z;
}
}
if (mbCompiled) {
if (mbTangents)
UpdateData(eVertexFlag_Position | eVertexFlag_Normal | eVertexFlag_Texture1, false);
else
UpdateData(eVertexFlag_Position | eVertexFlag_Normal, false);
}
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::Draw(eVertexBufferDrawType aDrawType) {
eVertexBufferDrawType drawType = aDrawType == eVertexBufferDrawType_LastEnum ? mDrawType : aDrawType;
///////////////////////////////
// Get the draw type
GLenum mode = GL_TRIANGLES;
if (drawType == eVertexBufferDrawType_Quad)
mode = GL_QUADS;
else if (drawType == eVertexBufferDrawType_Lines)
mode = GL_LINE_STRIP;
//////////////////////////////////
// Bind and draw the buffer
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mlElementHandle));
int lSize = mlElementNum;
if (mlElementNum < 0)
lSize = GetIndexNum();
GL_CHECK(glDrawElements(mode, lSize, GL_UNSIGNED_INT, (char *)NULL));
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::DrawIndices(unsigned int *apIndices, int alCount, eVertexBufferDrawType aDrawType) {
eVertexBufferDrawType drawType = aDrawType == eVertexBufferDrawType_LastEnum ? mDrawType : aDrawType;
///////////////////////////////
// Get the draw type
GLenum mode = GL_TRIANGLES;
if (drawType == eVertexBufferDrawType_Quad)
mode = GL_QUADS;
else if (drawType == eVertexBufferDrawType_Lines)
mode = GL_LINE_STRIP;
//////////////////////////////////
// Bind and draw the buffer
GL_CHECK(glDrawElements(mode, alCount, GL_UNSIGNED_INT, apIndices));
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::Bind() {
SetVertexStates(mVertexFlags);
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::UnBind() {
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
//-----------------------------------------------------------------------
float *cVertexBufferVBO::GetArray(tVertexFlag aType) {
int idx = cMath::Log2ToInt((int)aType);
return mvVertexArray[idx].data();
}
//-----------------------------------------------------------------------
unsigned int *cVertexBufferVBO::GetIndices() {
return mvIndexArray.data();
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::ResizeArray(tVertexFlag aType, int alSize) {
int idx = cMath::Log2ToInt((int)aType);
mvVertexArray[idx].resize(alSize);
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::ResizeIndices(int alSize) {
mvIndexArray.resize(alSize);
}
//-----------------------------------------------------------------------
iVertexBuffer *cVertexBufferVBO::CreateCopy(eVertexBufferUsageType aUsageType) {
cVertexBufferVBO *pVtxBuff = hplNew(cVertexBufferVBO, (mpLowLevelGraphics,
mVertexFlags, mDrawType, aUsageType,
GetVertexNum(), GetIndexNum()));
// Copy the vertices to the new buffer.
for (int i = 0; i < klNumOfVertexFlags; i++) {
if (kvVertexFlags[i] & mVertexFlags) {
#if 0
int lElements = kvVertexElements[i];
if (mbTangents && kvVertexFlags[i] == eVertexFlag_Texture1)
lElements = 4;
#endif
pVtxBuff->ResizeArray(kvVertexFlags[i], (int)mvVertexArray[i].size());
memcpy(pVtxBuff->GetArray(kvVertexFlags[i]),
mvVertexArray[i].data(), mvVertexArray[i].size() * sizeof(float));
}
}
// Copy indices to the new buffer
pVtxBuff->ResizeIndices(GetIndexNum());
memcpy(pVtxBuff->GetIndices(), GetIndices(), GetIndexNum() * sizeof(unsigned int));
pVtxBuff->mbTangents = mbTangents;
pVtxBuff->mbHasShadowDouble = mbHasShadowDouble;
pVtxBuff->Compile(0);
return pVtxBuff;
}
//-----------------------------------------------------------------------
int cVertexBufferVBO::GetVertexNum() {
int idx = cMath::Log2ToInt((int)eVertexFlag_Position);
int lSize = (int)mvVertexArray[idx].size() / kvVertexElements[idx];
// If there is a shadow double, just return the length of the first half.
if (mbHasShadowDouble)
return lSize / 2;
else
return lSize;
}
int cVertexBufferVBO::GetIndexNum() {
return (int)mvIndexArray.size();
}
cVector3f cVertexBufferVBO::GetVector3(tVertexFlag aType, unsigned alIdx) {
if (!(aType & mVertexFlags))
return cVector3f(0, 0, 0);
int idx = cMath::Log2ToInt((int)aType);
int pos = alIdx * kvVertexElements[idx];
return cVector3f(mvVertexArray[idx][pos + 0], mvVertexArray[idx][pos + 1],
mvVertexArray[idx][pos + 2]);
}
cVector3f cVertexBufferVBO::GetVector4(tVertexFlag aType, unsigned alIdx) {
if (!(aType & mVertexFlags))
return cVector3f(0, 0, 0);
int idx = cMath::Log2ToInt((int)aType);
int pos = alIdx * 4; // kvVertexElements[idx];
return cVector3f(mvVertexArray[idx][pos + 0], mvVertexArray[idx][pos + 1],
mvVertexArray[idx][pos + 2]);
}
cColor cVertexBufferVBO::GetColor(tVertexFlag aType, unsigned alIdx) {
if (!(aType & mVertexFlags))
return cColor();
int idx = cMath::Log2ToInt((int)aType);
int pos = alIdx * kvVertexElements[idx];
return cColor(mvVertexArray[idx][pos + 0], mvVertexArray[idx][pos + 1],
mvVertexArray[idx][pos + 2], mvVertexArray[idx][pos + 3]);
}
unsigned int cVertexBufferVBO::GetIndex(tVertexFlag aType, unsigned alIdx) {
return mvIndexArray[alIdx];
}
//-----------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
/////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
int cVertexBufferVBO::GetElementNum(tVertexFlag aFlag) {
int idx = cMath::Log2ToInt((int)aFlag);
return kvVertexElements[idx];
}
//-----------------------------------------------------------------------
void cVertexBufferVBO::SetVertexStates(tVertexFlag aFlags) {
/// COLOR 0 /////////////////////////
if (aFlags & eVertexFlag_Color0) {
GL_CHECK(glEnableClientState(GL_COLOR_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Color0);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
GL_CHECK(glColorPointer(kvVertexElements[idx], GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glDisableClientState(GL_COLOR_ARRAY));
}
/// NORMAL /////////////////////////
if (aFlags & eVertexFlag_Normal) {
GL_CHECK(glEnableClientState(GL_NORMAL_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Normal);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
GL_CHECK(glNormalPointer(GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glDisableClientState(GL_NORMAL_ARRAY));
}
/// TEXTURE 0 /////////////////////////
if (aFlags & eVertexFlag_Texture0) {
GL_CHECK(glClientActiveTexture(GL_TEXTURE0));
GL_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Texture0);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
GL_CHECK(glTexCoordPointer(kvVertexElements[idx], GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glClientActiveTexture(GL_TEXTURE0));
GL_CHECK(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
}
/// TEXTURE 1 /////////////////////////
if (aFlags & eVertexFlag_Texture1) {
GL_CHECK(glClientActiveTexture(GL_TEXTURE1));
GL_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Texture1);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
if (mbTangents) {
GL_CHECK(glTexCoordPointer(4, GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glTexCoordPointer(kvVertexElements[idx], GL_FLOAT, 0, (char *)NULL));
}
} else {
GL_CHECK(glClientActiveTexture(GL_TEXTURE1));
GL_CHECK(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
}
/// TEXTURE 2 /////////////////////////
if (aFlags & eVertexFlag_Texture2) {
GL_CHECK(glClientActiveTexture(GL_TEXTURE2));
GL_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Texture2);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
GL_CHECK(glTexCoordPointer(kvVertexElements[idx], GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glClientActiveTexture(GL_TEXTURE2));
GL_CHECK(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
}
/// TEXTURE 3 /////////////////////////
if (aFlags & eVertexFlag_Texture3) {
GL_CHECK(glClientActiveTexture(GL_TEXTURE3));
GL_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Texture3);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
GL_CHECK(glTexCoordPointer(kvVertexElements[idx], GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glClientActiveTexture(GL_TEXTURE3));
GL_CHECK(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
}
/// TEXTURE 4 /////////////////////////
if (aFlags & eVertexFlag_Texture4) {
GL_CHECK(glClientActiveTexture(GL_TEXTURE4));
GL_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Texture4);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
GL_CHECK(glTexCoordPointer(kvVertexElements[idx], GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glClientActiveTexture(GL_TEXTURE4));
GL_CHECK(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
}
/// POSITION /////////////////////////
if (aFlags & eVertexFlag_Position) {
GL_CHECK(glEnableClientState(GL_VERTEX_ARRAY));
int idx = cMath::Log2ToInt(eVertexFlag_Position);
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, mvArrayHandle[idx]));
GL_CHECK(glVertexPointer(kvVertexElements[idx], GL_FLOAT, 0, (char *)NULL));
} else {
GL_CHECK(glDisableClientState(GL_VERTEX_ARRAY));
}
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
//-----------------------------------------------------------------------
} // namespace hpl
// Old code for compiling all to one array.
// Log("Compiling VBO..\n");
/*int lNum = 0;
int lSize = 0;
int lNumSize = 0;
//Deterimine the number of arrays and the size.
Log("calc size: ");
for(int i=0;i< klNumOfVertexFlags; i++)
{
if(mVertexFlags & kvVertexFlags[i]){
lNum++;
//if(lSize != -1 && lSize != mvTempVertexArray[i].size()){
// return false;
//}
lSize += (int)mvTempVertexArray[i].size();
lNumSize = (int)mvTempVertexArray[i].size()/GetElementNum(kvVertexFlags[i]);
Log(" %d (%d * %d),",lSize,lNumSize, GetElementNum(kvVertexFlags[i]));
}
}
Log("\n");
//Get memory for the main array
mvVertexArray.resize(lSize);
//Copy the temp arrays into the main one
int lPos =0;
Log("Copy: \n");
for(int i=0;i< klNumOfVertexFlags; i++)
{
if(mVertexFlags & kvVertexFlags[i])
{
int lArraySize = (int)mvTempVertexArray[i].size();
Log(" %d (%d) -> %d \n",i,lArraySize,lPos );
memcpy(&mvVertexArray[lPos], &(mvTempVertexArray[i][0]), sizeof(float)*lArraySize);
mvArrayOffset[i] = lPos;
lPos += lArraySize;
mvTempVertexArray[i].clear();
}
}
Log("Array:\n");
for(int i=0;i< klNumOfVertexFlags; i++)
{
if(mVertexFlags & kvVertexFlags[i])
{
int lOffset = mvArrayOffset[i];
int lElemNum = GetElementNum(kvVertexFlags[i]);
for(int j=0;j<lNumSize;j++)
{
Log("(");
for(int k=0;k<lElemNum;k++)
{
Log(" %.1f,",mvVertexArray[lOffset + j*lElemNum + k]);
}
Log(") ");
}
Log("\n");
}
}*/
#endif // HPL1_USE_OPENGL

View File

@@ -0,0 +1,104 @@
/* 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/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_VERTEXBUFFER_VBO_H
#define HPL_VERTEXBUFFER_VBO_H
#include "common/scummsys.h"
#include "hpl1/engine/graphics/VertexBuffer.h"
#include "hpl1/opengl.h"
#ifdef HPL1_USE_OPENGL
namespace hpl {
class cVertexBufferVBO : public iVertexBuffer {
public:
cVertexBufferVBO(iLowLevelGraphics *apLowLevelGraphics, tVertexFlag aFlags,
eVertexBufferDrawType aDrawType, eVertexBufferUsageType aUsageType,
int alReserveVtxSize, int alReserveIdxSize);
~cVertexBufferVBO();
void AddVertex(tVertexFlag aType, const cVector3f &avVtx);
void AddColor(tVertexFlag aType, const cColor &aColor);
void AddIndex(unsigned int alIndex);
bool Compile(tVertexCompileFlag aFlags);
void UpdateData(tVertexFlag aTypes, bool abIndices);
void CreateShadowDouble(bool abUpdateData);
void Transform(const cMatrixf &mtxTransform);
void Draw(eVertexBufferDrawType aDrawType = eVertexBufferDrawType_LastEnum);
void DrawIndices(unsigned int *apIndices, int alCount,
eVertexBufferDrawType aDrawType = eVertexBufferDrawType_LastEnum);
void Bind();
void UnBind();
iVertexBuffer *CreateCopy(eVertexBufferUsageType aUsageType);
cBoundingVolume CreateBoundingVolume();
int GetVertexNum();
int GetIndexNum();
float *GetArray(tVertexFlag aType);
unsigned int *GetIndices();
void ResizeArray(tVertexFlag aType, int alSize);
void ResizeIndices(int alSize);
// For debugging purposes
cVector3f GetVector3(tVertexFlag aType, unsigned alIdx);
cVector3f GetVector4(tVertexFlag aType, unsigned alIdx);
cColor GetColor(tVertexFlag aType, unsigned alIdx);
unsigned int GetIndex(tVertexFlag aType, unsigned alIdx);
private:
int GetElementNum(tVertexFlag aFlag);
void SetVertexStates(tVertexFlag aFlags);
unsigned int mlElementHandle;
tFloatVec mvVertexArray[klNumOfVertexFlags];
unsigned int mvArrayHandle[klNumOfVertexFlags];
tUIntVec mvIndexArray;
bool mbHasShadowDouble;
bool mbCompiled;
};
} // namespace hpl
#endif // HPL1_USE_OPENGL
#endif // HPL_RENDERER3D_VBO_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,282 @@
/* 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/>.
*
*/
#ifndef HPL_LOW_LEVEL_GRAPHICS_TGL_H
#define HPL_LOW_LEVEL_GRAPHICS_TGL_H
#include "common/ptr.h"
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "graphics/tinygl/tinygl.h"
#include "hpl1/engine/graphics/LowLevelGraphics.h"
#include "hpl1/engine/math/MathTypes.h"
#ifdef USE_TINYGL
namespace hpl {
TGLenum ColorFormatToTGL(eColorDataFormat format);
TGLenum TextureTargetToTGL(eTextureTarget target);
TGLenum GetTGLTextureTargetEnum(eTextureTarget type);
//-------------------------------------------------
class LowLevelGraphicsTGL : public iLowLevelGraphics {
public:
LowLevelGraphicsTGL();
~LowLevelGraphicsTGL();
bool Init(int alWidth, int alHeight, int alBpp, int abFullscreen, int alMultisampling,
const tString &asWindowCaption);
int GetCaps(eGraphicCaps aType) const;
void ShowCursor(bool abX);
void SetMultisamplingActive(bool abX);
void SetGammaCorrection(float afX);
float GetGammaCorrection();
int GetMultisampling() { return mlMultisampling; }
void SetClipPlane(int alIdx, const cPlanef &aPlane);
cPlanef GetClipPlane(int alIdx, const cPlanef &aPlane);
void SetClipPlaneActive(int alIdx, bool abX);
cVector2f GetScreenSize();
cVector2f GetVirtualSize();
void SetVirtualSize(cVector2f avSize);
Bitmap2D *CreateBitmap2D(const cVector2l &avSize);
FontData *CreateFontData(const tString &asName);
iTexture *CreateTexture(bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
iTexture *CreateTexture(const tString &asName, bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
iTexture *CreateTexture(Bitmap2D *apBmp, bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
iTexture *CreateTexture(const cVector2l &avSize, int alBpp, cColor aFillCol,
bool abUseMipMaps, eTextureType aType, eTextureTarget aTarget);
Graphics::PixelFormat *GetPixelFormat();
iGpuProgram *CreateGpuProgram(const tString &vertex, const tString &fragment);
void SaveScreenToBMP(const tString &asFile);
/////////// MATRIX METHODS /////////////////////////
void PushMatrix(eMatrix aMtxType);
void PopMatrix(eMatrix aMtxType);
void SetIdentityMatrix(eMatrix aMtxType);
void SetMatrix(eMatrix aMtxType, const cMatrixf &a_mtxA);
void TranslateMatrix(eMatrix aMtxType, const cVector3f &avPos);
void RotateMatrix(eMatrix aMtxType, const cVector3f &avRot);
void ScaleMatrix(eMatrix aMtxType, const cVector3f &avScale);
void SetOrthoProjection(const cVector2f &avSize, float afMin, float afMax);
/////////// DRAWING METHODS /////////////////////////
// OCCLUSION
iOcclusionQuery *CreateOcclusionQuery();
void DestroyOcclusionQuery(iOcclusionQuery *apQuery);
// CLEARING THE FRAMEBUFFER
void ClearScreen();
void SetClearColor(const cColor &aCol);
void SetClearDepth(float afDepth);
void SetClearStencil(int alVal);
void SetClearColorActive(bool abX);
void SetClearDepthActive(bool abX);
void SetClearStencilActive(bool abX);
void SetColorWriteActive(bool abR, bool abG, bool abB, bool abA);
void SetDepthWriteActive(bool abX);
void SetCullActive(bool abX);
void SetCullMode(eCullMode aMode);
// DEPTH
void SetDepthTestActive(bool abX);
void SetDepthTestFunc(eDepthTestFunc aFunc);
// ALPHA
void SetAlphaTestActive(bool abX);
void SetAlphaTestFunc(eAlphaTestFunc aFunc, float afRef);
// STENCIL
void SetStencilActive(bool abX);
void SetStencil(eStencilFunc aFunc, int alRef, unsigned int aMask,
eStencilOp aFailOp, eStencilOp aZFailOp, eStencilOp aZPassOp);
void SetStencilTwoSide(eStencilFunc aFrontFunc, eStencilFunc aBackFunc,
int alRef, unsigned int aMask,
eStencilOp aFrontFailOp, eStencilOp aFrontZFailOp, eStencilOp aFrontZPassOp,
eStencilOp aBackFailOp, eStencilOp aBackZFailOp, eStencilOp aBackZPassOp);
void SetStencilTwoSide(bool abX);
// SCISSOR
void SetScissorActive(bool abX);
void SetScissorRect(const cRect2l &aRect);
// BLENDING
void SetBlendActive(bool abX);
void SetBlendFunc(eBlendFunc aSrcFactor, eBlendFunc aDestFactor);
void SetBlendFuncSeparate(eBlendFunc aSrcFactorColor, eBlendFunc aDestFactorColor,
eBlendFunc aSrcFactorAlpha, eBlendFunc aDestFactorAlpha);
// TEXTURE
void SetTexture(unsigned int alUnit, iTexture *apTex);
void SetActiveTextureUnit(unsigned int alUnit);
void SetTextureEnv(eTextureParam aParam, int alVal);
void SetTextureConstantColor(const cColor &color);
void SetColor(const cColor &aColor);
// POLYGONS
iVertexBuffer *CreateVertexBuffer(tVertexFlag aFlags, eVertexBufferDrawType aDrawType,
eVertexBufferUsageType aUsageType,
int alReserveVtxSize = 0, int alReserveIdxSize = 0);
void DrawRect(const cVector2f &avPos, const cVector2f &avSize, float afZ);
void DrawTri(const tVertexVec &avVtx);
void DrawTri(const cVertex *avVtx);
void DrawQuad(const tVertexVec &avVtx);
void DrawQuad(const tVertexVec &avVtx, const cColor aCol);
void DrawQuad(const tVertexVec &avVtx, const float afZ);
void DrawQuad(const tVertexVec &avVtx, const float afZ, const cColor &aCol);
void DrawQuadMultiTex(const tVertexVec &avVtx, const tVector3fVec &avExtraUvs);
void AddVertexToBatch(const cVertex &apVtx);
void AddVertexToBatch(const cVertex *apVtx, const cVector3f *avTransform);
void AddVertexToBatch(const cVertex *apVtx, const cMatrixf *aMtx);
void AddVertexToBatch_Size2D(const cVertex *apVtx, const cVector3f *avTransform,
const cColor *apCol, const float &mfW, const float &mfH);
void AddVertexToBatch_Raw(const cVector3f &avPos, const cColor &aColor,
const cVector3f &avTex);
void AddTexCoordToBatch(unsigned int alUnit, const cVector3f *apCoord);
void SetBatchTextureUnitActive(unsigned int alUnit, bool abActive);
void AddIndexToBatch(int alIndex);
void FlushTriBatch(tVtxBatchFlag aTypeFlags, bool abAutoClear = true);
void FlushQuadBatch(tVtxBatchFlag aTypeFlags, bool abAutoClear = true);
void ClearBatch();
// PRIMITIVES
void DrawLine(const cVector3f &avBegin, const cVector3f &avEnd, cColor aCol);
void DrawBoxMaxMin(const cVector3f &avMax, const cVector3f &avMin, cColor aCol);
void DrawSphere(const cVector3f &avPos, float afRadius, cColor aCol);
void DrawLine2D(const cVector2f &avBegin, const cVector2f &avEnd, float afZ, cColor aCol);
void DrawLineRect2D(const cRect2f &aRect, float afZ, cColor aCol);
void DrawLineCircle2D(const cVector2f &avCenter, float afRadius, float afZ, cColor aCol);
void DrawFilledRect2D(const cRect2f &aRect, float afZ, cColor aCol);
// FRAMEBUFFER
void CopyContextToTexure(iTexture *apTex, const cVector2l &avPos,
const cVector2l &avSize, const cVector2l &avTexOffset = 0);
void SetRenderTarget(iTexture *pTex);
bool RenderTargetHasZBuffer();
void FlushRenderTarget();
void FlushRendering();
void SwapBuffers();
///// SDL Specific ////////////////////////////
void SetupGL();
private:
cVector2l mvScreenSize;
cVector2f mvVirtualSize;
int mlMultisampling;
int mlBpp;
// Gamma
// uint16 mvStartGammaArray[3][256];
float mfGammaCorrection;
// Clipping
cPlanef mvClipPlanes[kMaxClipPlanes];
// SDL Variables
// SDL_Surface *mpScreen;
Graphics::PixelFormat mpPixelFormat;
// Vertex Array variables
// The vertex arrays used:
float *mpVertexArray;
unsigned int mlVertexCount;
unsigned int *mpIndexArray;
unsigned int mlIndexCount;
unsigned int mlBatchStride;
float *mpTexCoordArray[MAX_TEXTUREUNITS];
bool mbTexCoordArrayActive[MAX_TEXTUREUNITS];
unsigned int mlTexCoordArrayCount[MAX_TEXTUREUNITS];
unsigned int mlBatchArraySize;
// Clearing
bool mbClearColor;
bool mbClearDepth;
bool mbClearStencil;
// Rendertarget variables
iTexture *mpRenderTarget;
// Texture
iTexture *mpCurrentTexture[MAX_TEXTUREUNITS];
// CG Compiler Variables
// CGcontext mCG_Context;
// Multisample
void CheckMultisampleCaps();
// Batch helper
void SetUpBatchArrays();
// Matrix Helper
void SetMatrixMode(eMatrix mType);
// Vtx helper
void SetVtxBatchStates(tVtxBatchFlag flags);
};
} // namespace hpl
#endif // USE_TINYGL
#endif // HPL_LOWLEVELGRAPHICS_TGL_H

View File

@@ -0,0 +1,47 @@
/* 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/>.
*
*/
#ifndef HPL_OCCLUSION_QUERY_TGL_H
#define HPL_OCCLUSION_QUERY_TGL_H
#include "common/scummsys.h"
#include "hpl1/engine/graphics/OcclusionQuery.h"
#ifdef USE_TINYGL
namespace hpl {
class OcclusionQueryTGL : public iOcclusionQuery {
public:
OcclusionQueryTGL() {}
~OcclusionQueryTGL() {}
void Begin() override {}
void End() override {}
bool FetchResults() override { return true; }
unsigned int GetSampleCount() override { return 0; }
};
} // namespace hpl
#endif // USE_TINYGL
#endif // HPL_OCCLUSION_QUERY_TGL_H

View File

@@ -0,0 +1,24 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// AMBIENT DIFFUSE COLOR FRAG PROGRAM ////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform vec3 ambientColor;
void main()
{
outColor = texture(tex0, vUv);
outColor.xyz *= ambientColor;
}

View File

@@ -0,0 +1,28 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SPECULAR BUMPMAPPING 2D FRAGMENT PROGRAM //////////
///////////////////////////////////////////////////////
in vec4 vColor;
in vec3 vUv; //in object space
in vec3 vLightDir;
in vec2 vScreenPos;
OUTPUT
uniform sampler2D tex0; //NormalMap
uniform sampler2D tex1; //LightMap
void main()
{
vec4 BumpVec = (1 - 2*texture(tex0, vUv));
vec4 LightCol = texture(tex1,vScreenPos);
float Diffuse = dot(vLightDir,BumpVec.xyz)*LightCol.x;
outColor.xyz = Diffuse*vColor.xyz;
}

View File

@@ -0,0 +1,48 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// BUMPMAPPING 2D VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 uv = gl_MultiTexCoord0.xyz;
out vec4 vColor;
out vec3 vUv;
out vec3 vLightDir;
out vec2 vScreenPos;
uniform mat4 worldViewProj;
uniform vec3 LightPos;
uniform float LightRadius;
uniform vec4 LightColor;
void main()
{
vec3 L;
//Get the direction of the light and normalize it
vLightDir.xy = position.xy - LightPos.xy;
vScreenPos = (vLightDir.xy + (LightRadius) )/ (LightRadius*2.0);
//rotate the light to texture (tangent) space. Normal x=cos(angle) y = sin(angle)
vec2 TempLight = vLightDir.xy;
vLightDir.x = normal.x*TempLight.x + normal.y*TempLight.y;
vLightDir.y = normal.x*TempLight.y - normal.y*TempLight.x;
vLightDir.x *= normal.z/abs(normal.z);
vLightDir.y *= abs(normal.z)-2.0;
vLightDir.z = -LightPos.z;
vLightDir = normalize(vLightDir);
gl_Position = worldViewProj * position;
vColor = clamp(LightColor, vec4(0.0), vec4(1.0));
vUv = uv;
}

View File

@@ -0,0 +1,41 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// BUMP COLOR SPECULAR LIGHTING FRAGMENT PROGRAM ///////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler1D tex3; //falloffMap
uniform sampler2D tex6; //specularMap
void main()
{
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec3 bumpVec = texture(tex1, vUv).xyz;
bumpVec.xyz = (2.0*bumpVec.xyz)-vec3(1.0);
vec3 normLightDir = normalize(vLightDir);
vec3 normHalfVec = normalize(vHalfVec);
float specular = clamp(dot(normHalfVec, bumpVec.xyz), 0.0, 1.0);
specular = pow(specular, 16.0) * vLightColor.w;
outColor.xyz = texture(tex0, vUv).xyz * vLightColor.xyz * dot(normLightDir, bumpVec.xyz)
+ (specular * texture(tex6, vUv).xyz);
outColor.xyz *= attenuation;
}

View File

@@ -0,0 +1,46 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE COLOR SPOTLIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler1D tex3; //falloffMap
uniform sampler2D tex4; //spotlightMap
uniform sampler1D tex5; //spotNegRejectMap
uniform sampler2D tex6; //specularMap
void main()
{
vec3 diffuse = texture(tex0, vUv).xyz;
vec3 bumpVec = (2.0*texture(tex1, vUv)-vec4(1.0)).xyz;
vec3 lightVec = normalize(vLightDir);
vec3 normHalfVec = normalize(vHalfVec);
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec4 spotColor = texture(tex4, vSpotlightUv.xy / vSpotlightUv.w);
float rejectNeg = texture1D(tex5,vSpotlightUv.z + 0.5).x;
float specular = clamp(dot(normHalfVec, bumpVec.xyz), 0.0, 1.0);
specular = pow(specular, 16.0)* vLightColor.w * spotColor.w;
outColor.xyz = diffuse * dot(lightVec, bumpVec.xyz) * vLightColor.xyz * spotColor.xyz
+ (specular * texture(tex6, vUv).xyz);
outColor.xyz *= attenuation * rejectNeg;
}

View File

@@ -0,0 +1,37 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in
// LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SPECULAR BUMPMAPPING 2D FRAGMENT PROGRAM //////////
///////////////////////////////////////////////////////
in vec4 vColor;
in vec3 vUv; // in object space
in vec3 vLightDir;
in vec3 vHalfVec;
in vec2 vScreenPos;
OUTPUT
uniform sampler2D tex0; //NormalMap
uniform sampler2D tex1; //LightMap
void main() {
vec4 BumpVec = (vec4(1.0) - 2.0 * texture(tex0, uv));
vec4 LightCol = texture(tex1, vScreenPos);
BumpVec.xyz = normalize(BumpVec.xyz);
float Diffuse = dot(normalize(vLightDir), BumpVec.xyz) * LightCol.x;
float Specular = dot(normalize(vHalfVec), BumpVec.xyz);
Specular = pow(Specular, 24.0) * BumpVec.w * vColor.w;
outColor.xyz = Diffuse * vColor.xyz;
outColor.w = Specular * LightCol.x;
}

View File

@@ -0,0 +1,67 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SPECULAR BUMPMAPPING 2D VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec2 uv = gl_MultiTexCoord0.xy;
out vec4 vColor
out vec2 vUv;
out vec3 vLightDir;
out vec3 vHalfVec;
out vec2 vScreenPos;
uniform mat4 worldViewProj;
uniform vec3 LightPos;
uniform vec3 EyePos;
uniform float LightRadius;
uniform vec4 LightColor;
void main()
{
vec3 L;
//Get the direction of the light and normalize it
vLightDir.xy = position.xy - LightPos.xy;
vScreenPos = (vLightDir.xy + (LightRadius)) / (LightRadius * 2.0);
//rotate the light to texture (tangent) space. Normal x=cos(angle) y = sin(angle)
vec2 TempLight = vLightDir.xy;
vLighttDir.x = normal.x*TempLight.x + normal.y*TempLight.y;
vLighttDir.y = normal.x*TempLight.y - normal.y*TempLight.x;
vLighttDir.x *= normal.z / abs(normal.z);
vLighttDir.y *= abs(normal.z)-2.0;
vLighttDir.z = -LightPos.z;
vLighttDir = normalize(vLightDir);
//Get the halfangle and normalize it
vHalfVec.xy = position.xy - EyePos.xy;
vHalfVec.z = -EyePos.y;
///rotate halfvec as well NOTE: Not sure you need this...
vec2 TempHalfVec = vHalfVec.xy;
vHalfVec.x = normal.x*TempHalfVec.x + normal.y*TempHalfVec.y;
vHalfVec.y = normal.x*TempHalfVec.y - normal.y*TempHalfVec.x;
vHalfVec.x *= normal.z/abs(normal.z);
vHalfVec.y *= abs(normal.z) - 2.0;
vHalfVec = normalize(vHalfVec);
vHalfVec = normalize(vHalfVec + vLightDir);
gl_Position = worldViewProj * position;
vColor = clamp(LightColor, vec4(0.0), vec4(1.0));
vUv = uv;
}

View File

@@ -0,0 +1,40 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// BUMP SPECULAR LIGHTING FRAGMENT PROGRAM ///////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler1D tex3; //falloffMap
void main()
{
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec4 bumpVec = texture(tex1, vUv);
bumpVec.xyz = (2.0*bumpVec.xyz)-vec3(1.0);
vec3 normLightDir = normalize(vLightDir);
vec3 normHalfVec = normalize(vHalfVec);
float specular = clamp(dot(normHalfVec, bumpVec.xyz), 0.0, 1.0);
specular = pow(specular, 16.0) * vLightColor.w * clamp(bumpVec.w, 0.0, 1.0);
outColor.xyz = texture(tex0, vUv).xyz * vLightColor.xyz * dot(normLightDir, bumpVec.xyz) +
specular;
outColor.xyz *= attenuation;
}

View File

@@ -0,0 +1,46 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPOTLIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform sampler1D tex3; //falloffMap
uniform sampler2D tex4; //spotlightMap
uniform sampler1D tex5; //spotNegRejectMap
void main()
{
vec3 diffuse = texture(tex0, vUv).xyz;
vec4 bumpVec = texture(tex1, vUv);
bumpVec.xyz = (2.0*bumpVec.xyz)-vec3(1.0);
vec3 lightVec = normalize(vLightDir);
vec3 normHalfVec = normalize(vHalfVec);
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec4 spotColor = texture(tex4, vSpotlightUv.xy / vSpotlightUv.w);
float rejectNeg = texture1D(tex5,vSpotlightUv.z + 0.5).x;
float specular = clamp(dot(normHalfVec, bumpVec.xyz), 0.0, 1.0);
specular = pow(specular, 16.0) * vLightColor.w * clamp(bumpVec.w, 0.0, 1.0) * clamp(spotColor.w, 0.0, 1.0);
outColor.xyz = diffuse * dot(lightVec, bumpVec.xyz) * vLightColor.xyz * spotColor.xyz +
specular;
outColor.xyz *= attenuation * rejectNeg;
}

View File

@@ -0,0 +1,42 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPOTLIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler2D tex3; //spotlightMap
void main()
{
vec3 diffuse = texture(tex0, vUv).xyz;
vec4 bumpVec = texture(tex1, vUv);
bumpVec.xyz = (2.0*bumpVec.xyz)-vec3(1.0);
vec3 lightVec = (2.0*textureCube(tex2,vLightDir)-vec4(1.0)).xyz;
vHalfVec = (2.0*textureCube(tex2,vHalfVec)-vec4(1.0)).xyz;
vec4 spotColor = texture(tex3, vSpotlightUv.xy / vSpotlightUv.w);
float specular = clamp(dot(vHalfVec, bumpVec.xyz), 0.0, 1.0);
specular = pow(specular, 16.0) * vLightColor.w * clamp(bumpVec.w, 0.0, 1.0) * clamp(spotColor.w, 0.0, 1.0);
outColor.xyz = diffuse * dot(lightVec, bumpVec.xyz) * vLightColor.xyz * spotColor.xyz +
specular;
}

View File

@@ -0,0 +1,32 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING FRAGMENT PROGRAM /////////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler1D tex3; //falloffMap
void main()
{
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec4 bumpVec = (2.0*texture(tex1, vUv)-vec4(1.0));
vec4 lightVec = (2.0*textureCube(tex2,vLightDir)-vec4(1.0));
outColor.xyz = texture(tex0, vUv).xyz * vLightColor.xyz * attenuation * dot(lightVec.xyz,bumpVec.xyz);
outColor.w = 0;
}

View File

@@ -0,0 +1,39 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in
// LICENSE-shaders
//
///////////////////////////////////////////////////////
/// BUMP SPOTLIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler1D tex3; //falloffMap
uniform sampler2D tex4; //spotlightMap
uniform sampler1D tex5; //spotNegRejectMap
void main() {
vec3 diffuse = texture(tex0, vUv).xyz;
vec3 bumpVec = (2 * texture(tex1, vUv) - 1).xyz;
vec3 lightVec = (2.0 * textureCube(tex2, vLightDir) - 1.0).xyz;
float attenuation = texture1D(tex3, dot(vLightDir, vLightDir)).x;
vec3 spotColor =
texture(tex4, vSpotlightUv.xy / vSpotlightUv.w).xyz;
float rejectNeg = texture1D(tex5, vSpotlightUv.z + 0.5).x;
outColor.xyz = diffuse * dot(lightVec, bumpVec) * attenuation *
vLightColor.xyz * spotColor * rejectNeg;
}

View File

@@ -0,0 +1,32 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in
// LICENSE-shaders
//
///////////////////////////////////////////////////////
/// BUMP SPOTLIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler2D tex3; //spotlightMap
void main() {
vec3 diffuse = texture(tex0, vUv).xyz;
vec3 bumpVec = (2.0 * texture(tex1, vUv) - vec4(1.0)).xyz;
vec3 lightVec = (2.0 * textureCube(tex2, vLightDir) - vec4(1.0)).xyz;
vec3 spotColor =
texture(tex3, vSpotlightUv.xy / vSpotlightUv.w).xyz;
outColor.xyz = diffuse * dot(lightVec, bumpVec) * vLightColor.xyz * spotColor;
}

View File

@@ -0,0 +1,34 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPECULAR LIGHTING FRAGMENT PROGRAM ////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler1D tex3; //falloffMap
void main()
{
float attenuation = texture1D(tex3, dot(vLightDir,vLightDir)).x;
vec3 lightDir = normalize(vLightDir);
vec3 halfVec = normalize(vHalfVec);
float specular = clamp(dot(halfVec, vec3(0,0,1)), 0.0, 1.0);
specular = pow(specular, 16.0) * vLightColor.w;
outColor.xyz = specular + texture(tex0, vUv).xyz * vLightColor.xyz * dot(normalize(lightDir), vec3(0,0,1));
outColor.xyz = outColor.xyz * attenuation;
}

View File

@@ -0,0 +1,51 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPECULAR LIGHTING VERTEX PROGRAM //////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec2 uv = gl_MultiTexCoord0.xy;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec2 vUv;
out vec3 vLightDir;
out vec3 vHalfVec;
uniform mat4 worldViewProj;
uniform vec3 EyePos;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vec3 lightDir = LightPos - position.xyz;
vLightDir = lightDir * LightDirMul;
//Calculate rotation for light to get it to tangent space.
vec3 binormal = cross(normal,tangent.xyz)*tangent.w;
mat3 rotation = transpose(mat3(tangent.xyz, binormal, normal));
//Transform the lightdir
vLightDir = (rotation * vLightDir);
//Get the halfvector for the specular term
vHalfVec = normalize(EyePos - position.xyz);
//transform to tangent space
vHalfVec = (rotation * vHalfVec);
vHalfVec = normalize(vLightDir)+vHalfVec;
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,41 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPECULAR SPOTLIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform sampler1D tex3; //falloffMap
uniform sampler2D tex4; //spotlightMap
uniform sampler1D tex5; //spotNegRejectMap
void main()
{
vec3 diffuse = texture(tex0, vUv).xyz;
vec3 lightNormal = normalize(vLightDir);
vec3 halfVec = normalize(vHalfVec);
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec4 spotColor = texture(tex4, vSpotlightUv.xy / vSpotlightUv.w);
float rejectNeg = texture1D(tex5,vSpotlightUv.z + 0.5).x;
float specular = clamp(dot(halfVec, vec3(0,0,1)), 0.0, 1.0);
specular = pow(specular, 16.0) * vLightColor.w * spotColor.w;
outColor.xyz = specular + diffuse * dot(lightNormal, vec3(0,0,1)) * vLightColor.xyz * spotColor.xyz;
outColor.xyz *= attenuation * rejectNeg;
}

View File

@@ -0,0 +1,57 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPECUALR SPOT LIGHTING VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec2 uv = gl_MultiTexCoord0.xy;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec2 vUv;
out vec3 vLightDir;
out vec3 vHalfVec;
out vec4 vSpotlightUv;
uniform mat4 worldViewProj;
uniform mat4 spotViewProj;
uniform vec3 EyePos;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vSpotlightUv = (spotViewProj * position);
vec3 lightDir = LightPos - position.xyz;
vLightDir = lightDir * LightDirMul;
//Calculate rotation for light to get it to tangent space.
vec3 binormal = cross(normal,tangent.xyz)*tangent.w;
mat3 rotation = transpose(mat3(tangent.xyz, binormal, normal));
//Transform the lightdir
vLightDir = (rotation * vLightDir);
//Get the halfvector for the specular term
vHalfVec = normalize(EyePos - position.xyz);
//transform to tangent space
vHalfVec = (rotation * vHalfVec);
vHalfVec = normalize(vLightDir)+vHalfVec;
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,37 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPECULAR SPOTLIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec3 vHalfVec;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler2D tex3; //spotlightMap
void main()
{
vec3 diffuse = texture(tex0, vUv).xyz;
vec3 lightNormal = (2.0*textureCube(tex2,vLightDir)-vec4(1.0)).xyz;
vHalfVec = (2.0*textureCube(tex2,vHalfVec)-vec4(1.0)).xyz;
vec4 spotColor = texture(tex3, vSpotlightUv.xy / vSpotlightUv.w);
float specular = clamp(dot(vHalfVec, vec3(0,0,1)), 0.0, 1.0);
specular = pow(specular, 16.0) * vLightColor.w * spotColor.w;
outColor.xyz = specular + diffuse * dot(lightNormal, vec3(0,0,1)) * vLightColor.xyz * spotColor.xyz;
}

View File

@@ -0,0 +1,22 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SIMPLE DIFFUSE COLOR FRAGMENT PROGRAM ////////////
///////////////////////////////////////////////////////
in vec4 vColor;
in vec2 vUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap;
void main()
{
outColor = texture(tex0, vUv) * vColor;
}

View File

@@ -0,0 +1,26 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SIMPLE DIFFUSE COLOR VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec4 color = gl_Color;
vec2 uv = gl_MultiTexCoord0.xy;
out vec4 vColor;
out vec2 vUv;
uniform mat4 worldViewProj;
void main()
{
gl_Position = worldViewProj * position;
vColor = clamp(color, vec4(0.0), vec4(1.0));
vUv = uv;
}

View File

@@ -0,0 +1,30 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE COLOR MUL VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 color = gl_Color.xyz;
vec3 uv = gl_MultiTexCoord0.xyz;
out vec3 vColor;
out vec3 vUv;
uniform mat4 worldViewProj
uniform vec4 colorMul;
void main()
{
gl_Position = worldViewProj * position;
vColor = clamp(color * colorMul, vec3(0.0), vec3(1.0));
vUv = uv;
}

View File

@@ -0,0 +1,16 @@
// Diffuse_EnvMap_Reflect.fragment
in vec3 vColor;
in vec3 vUv;
in vec3 vUv2;
OUTPUT
uniform sampler2D tex0; // diffuse
uniform samplerCube tex1;
void main() {
vec4 diffuseColor = texture(tex0, vUv.st);
vec4 reflectedColor = textureCube(tex1, vUv2);
outColor = mix(diffuseColor, reflectedColor, diffuseColor.a);
}

View File

@@ -0,0 +1,39 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SIMPLE DIFFUSE COLOR VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 color = gl_Color.xyz;
vec3 uv = gl_MultiTexCoord0.xyz;
out vec3 vColor;
out vec3 vUv;
out vec3 vUv2;
uniform mat4 worldViewProj;
uniform mat4 objectWorldMatrix;
uniform vec3 eyeWorldPos;
void main()
{
gl_Position = (worldViewProj * position);
vColor = clamp(color, vec3(0.0), vec3(1.0));
mat3 rotation = mat3(objectWorldMatrix);
vec3 worldPos = (objectWorldMatrix * position).xyz;
vec3 worldNormal = (rotation * normal);
vec3 eyeDir = worldPos - eyeWorldPos;
vUv = uv;
vUv2 = reflect(eyeDir, worldNormal);
}

View File

@@ -0,0 +1,30 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING FRAGMENT PROGRAM /////////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler1D tex3; //falloffMap
void main()
{
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec3 lightDir = (2.0*textureCube(tex2,vLightDir)-vec4(1.0)).xyz;
outColor.xyz = attenuation * texture(tex0, vUv).xyz * vLightColor.xyz * dot(lightDir, vec3(0,0,1));
outColor.w = 0.0;
}

View File

@@ -0,0 +1,43 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec2 uv = gl_MultiTexCoord0.xy;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec2 vUv;
out vec3 vLightDir;
uniform mat4 worldViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vec3 lightDir = LightPos - position.xyz;
vLightDir = lightDir * LightDirMul;
//Calculate rotation for light to get it to tangent space.
vec3 binormal = cross(normal,tangent.xyz)*tangent.w;
mat3 rotation = transpose(mat3(tangent.xyz, binormal, normal));
//Transform the lightdir
vLightDir = (rotation * vLightDir);
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,35 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPOT LIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler1D tex3; //falloffMap
uniform sampler2D tex4; //spotlightMap
uniform sampler1D tex5; //spotNegRejectMap
void main()
{
vec3 diffuse = texture(tex0, vUv).xyz;
vec3 lightNormal = (2.0*textureCube(tex2,vLightDir)-vec4(1.0)).xyz;
float attenuation = texture1D(tex3,dot(vLightDir,vLightDir)).x;
vec3 spotColor = texture(tex4, vSpotlightUv.xy / vSpotlightUv.w).xyz;
float rejectNeg = texture1D(tex5,vSpotlightUv.z + 0.5).x;
outColor.xyz = diffuse * dot(lightNormal, vec3(0,0,1)) * attenuation *
vLightColor.xyz * spotColor * rejectNeg;
}

View File

@@ -0,0 +1,47 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPOT LIGHTING VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec2 uv = gl_MultiTexCoord0.xy;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec2 vUv;
out vec3 vLightDir;
out vec4 vSpotlightUv;
uniform mat4 worldViewProj;
uniform mat4 spotViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vSpotlightUv = (spotViewProj * position);
vec3 lightDir = LightPos - position.xyz;
vLightDir = lightDir * LightDirMul;
//Calculate rotation for light to get it to tangent space.
vec3 binormal = cross(normal,tangent.xyz)*tangent.w;
mat3 rotation = transpose(mat3(tangent.xyz, binormal, normal));
//Transform the lightdir
vLightDir = (rotation * vLightDir);
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,29 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPOT LIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler1D tex0; //falloffMap
uniform sampler1D tex1; //spotNegRejectMap
void main()
{
float attenuation = texture1D(tex0, dot(vLightDir,vLightDir)).x;
float rejectNeg = texture1D(tex1, vSpotlightUv.z + 0.5).x;
outColor.w = attenuation * rejectNeg;
outColor.xyz = vec3(0.0);
}

View File

@@ -0,0 +1,30 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE SPOT LIGHTING FRAGMENT PROGRAM /////////////
///////////////////////////////////////////////////////
in vec4 vLightColor;
in vec2 vUv;
in vec3 vLightDir;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuseMap
uniform samplerCube tex2; //normalCubeMap
uniform sampler2D tex3; //spotlightMap
void main()
{
vec3 diffuse = texture(tex0, vUv).xyz;
vec3 lightNormal = (2.0*textureCube(tex2,vLightDir)-vec4(1.0)).xyz;
vec3 spotColor = texture(tex3, vSpotlightUv.xy / vSpotlightUv.w).xyz;
outColor.xyz = diffuse * dot(lightNormal, vec3(0,0,1)) * vLightColor.xyz * spotColor;
}

View File

@@ -0,0 +1,21 @@
//FallBack01_Bump_Light.fragment
in vec3 vLightDir;
in vec3 vUv;
in vec3 vLightPos;
OUTPUT
uniform samplerCube tex0; //normalizedVecMap
uniform sampler2D tex1; //normalMap
uniform sampler3D tex2; //attenuation
void main() {
vec4 nv = textureCube(tex0, vLightDir);
vec4 norm = texture(tex1, vUv.st);
vec4 attenuation = texture3D(tex2, vLightPos);
outColor = vec4(4*((nv.r - 0.5)*(norm.r - 0.5) + (nv.g - 0.5)*(norm.g - 0.5) + (nv.b - 0.5)*(norm.b - 0.5)));
outColor.a *= attenuation.g;
}

View File

@@ -0,0 +1,17 @@
//Fallback01_Diffuse_Light_Spot.fragment
in vec4 vLightColor;
in vec3 vUv;
in vec4 vSpotlightUv;
in float vRejectUv;
uniform sampler2D tex0; //diffuseMap
uniform sampler2D tex1; //normalMap
uniform sampler1D tex2; //spotNegRejectMap
void main() {
vec4 diffuse = texture(tex0, vUv.xy);
vec4 spot = texture(tex1, vSpotlightUv.xy / vSpotlightUv.w);
float spotNegReject = texture1D(tex2, vSpotlightUv.w).r;
outColor = diffuse * spot * spotNegReject * vLightColor;
}

View File

@@ -0,0 +1,37 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM //////////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 uv = gl_MultiTexCoord0.xyz;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec3 vUv;
out vec4 vSpotlightUv;
out float vRejectUv;
uniform mat4 worldViewProj;
uniform mat4 spotViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vSpotlightUv = (spotViewProj * position);
vRejectUv = vSpotlightUv.z + 0.5;
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,19 @@
//Fallback01_Diffuse_Light_p1.fragment
in vec4 vLightColor;
in vec3 vUv;
in vec3 vLightPos;
in vec3 vLightDir;
OUTPUT
uniform samplerCube tex0; //normalMap
uniform sampler3D tex2; //attenuation
void main() {
vec4 normalizedVec = textureCube(tex0, vLightDir);
vec4 attenuation = texture3D(tex2, vLightPos);
outColor = vec4(2.0*(normalizedVec.b - 0.5));
outColor.a *= attenuation.g;
}

View File

@@ -0,0 +1,45 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM //////////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 uv = gl_MultiTexCoord0.xyz;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec3 vLightDir;
out vec3 vUv;
out vec3 vLightPos;
uniform mat4 worldViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vec3 lightDir = LightPos - position.xyz;
vLightDir = lightDir * LightDirMul;
vLightPos = vLightDir *0.5 + 0.5;
//Calculate rotation for light to get it to tangent space.
vec3 binormal = cross(normal,tangent.xyz)*tangent.w;
mat3 rotation = transpose(mat3(tangent.xyz, binormal, normal));
//Transform the lightdir
vLightDir = (rotation * vLightDir);
vLightColor = vec4(1.0);
}

View File

@@ -0,0 +1,14 @@
//Fallback01_Diffuse_Light_p2.fragment
in vec4 vLightColor;
in vec3 vUv;
in vec3 vLightPos;
in vec3 vLightDir;
OUTPUT
uniform sampler2D tex0; //diffuseMap
void main() {
outColor = texture(tex0, vUv.xy) * vLightColor;
}

View File

@@ -0,0 +1,32 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM //////////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 uv = gl_MultiTexCoord0.xyz;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec3 vUv;
uniform mat4 worldViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,12 @@
//Fallback02_Diffuse_Light_Spot_p2.fragment
in vec4 vLightColor;
in float vRejectUv;
OUTPUT
uniform sampler1D tex0; //spotNegRejectMap
void main() {
outColor = texture1D(tex0, vRejectUv).r * vLightColor;
}

View File

@@ -0,0 +1,17 @@
//Fallback02_Diffuse_Light_Spot_p3.fragment
in vec4 vLightColor;
in vec3 vUv;
in vec4 vSpotlightUv;
OUTPUT
uniform sampler2D tex0; //diffuse
uniform sampler2D tex1; //spotlight
void main() {
vec4 diffuse = texture(tex0, vUv.xy);
vec4 spot = texture(tex1, vSpotlightUv.xy / vSpotlightUv.w);
outColor = diffuse * spot * vLightColor;
}

View File

@@ -0,0 +1,35 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM //////////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 uv = gl_MultiTexCoord0.xyz;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out float vRejectUv;
uniform mat4 worldViewProj;
uniform mat4 spotViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
//vUv = uv;
vec4 spotlightUv = (spotViewProj * position);
vRejectUv = spotlightUv.z + 0.5;
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,36 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM //////////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 uv = gl_MultiTexCoord0.xyz;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec3 vUv;
out vec4 vSpotlightUv;
uniform mat4 worldViewProj;
uniform mat4 spotViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vSpotlightUv = (spotViewProj * position);
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,16 @@
//Fallback02_Diffuse_Light_p1.fragment
in vec3 vLightDir;
in vec3 vLightPos;
OUTPUT
uniform samplerCube tex0;
uniform sampler3D tex1;
void main() {
vec4 normalizedVec = textureCube(tex0, vLightDir);
vec4 attenuation = texture3D(tex1, vLightPos);
outColor = vec4(2.0*(normalizedVec.b - 0.5));
outColor.a *= attenuation.g;
}

View File

@@ -0,0 +1,41 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM //////////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vColor;
out vec3 vLightDir;
out vec3 vLightPos;
uniform mat4 worldViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vec3 lightDir = LightPos - position.xyz;
vLightDir = lightDir * LightDirMul;
vLightPos = vLightDir *0.5 + 0.5;
//Calculate rotation for light to get it to tangent space.
vec3 binormal = cross(normal,tangent.xyz)*tangent.w;
mat3 rotation = transpose(mat3(tangent.xyz, binormal, normal));
//Transform the lightdir
vLightDir = (rotation * vLightDir);
vColor = vec4(1.0);
}

View File

@@ -0,0 +1,33 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// DIFFUSE LIGHTING VERTEX PROGRAM //////////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec3 uv = gl_MultiTexCoord0.xyz;
vec4 tangent = gl_MultiTexCoord1;
out vec4 vLightColor;
out vec3 vUv;
uniform mat4 worldViewProj;
uniform vec3 LightPos;
uniform vec4 LightColor;
uniform vec3 LightDirMul;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv;
vLightColor = clamp(LightColor, vec4(0.0), vec4(1.0));
}

View File

@@ -0,0 +1,22 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SOLID FOG FRAGMENT PROGRAM ////////////
///////////////////////////////////////////////////////
in vec4 vColor;
in float vUv;
OUTPUT
uniform sampler1D tex0; //diffuseMap;
void main()
{
outColor = texture1D(tex0, vUv).rrrg * vColor;
}

View File

@@ -0,0 +1,31 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SIMPLE DIFFUSE COLOR VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec3 color = gl_Color.xyz;
out vec4 vColor;
out float vUv;
uniform mat4 worldViewProj;
uniform vec3 fogColor;
uniform float fogStart;
uniform float fogEnd;
void main()
{
gl_Position = (worldViewProj * position);
vUv = (fogEnd - gl_Position.z)/(fogEnd - fogStart);
vColor.xyz = clamp(fogColor, vec3(0.0), vec3(1.0));
vColor.w = 1;
}

View File

@@ -0,0 +1,31 @@
// Copyright 2006-2010 (C) - Frictional Games
//
// This file is part of HPL1 Engine
//
// For conditions of distribution and use, see copyright notice in LICENSE-shaders
//
///////////////////////////////////////////////////////
/// SIMPLE DIFFUSE COLOR VERTEX PROGRAM ////////////
///////////////////////////////////////////////////////
vec4 position = gl_Vertex;
vec4 color = gl_Color;
vec3 uv = gl_MultiTexCoord0.xyz;
out vec4 vColor;
out vec2 vUv;
out float vFogUv;
uniform mat4 worldViewProj;
uniform float fogStart;
uniform float fogEnd;
void main()
{
gl_Position = (worldViewProj * position);
vUv = uv.xy;
vFogUv = (fogEnd - gl_Position.z)/(fogEnd - fogStart);
vColor = clamp(color, vec4(0.0), vec4(1.0));
}

Some files were not shown because too many files have changed in this diff Show More