Update IRenderer for null safety and safe memory management

This commit is contained in:
yvt 2019-07-20 13:48:49 +09:00
parent 464b88a23b
commit e6227b3361
No known key found for this signature in database
GPG Key ID: 48F2768FA8D07C92
44 changed files with 442 additions and 373 deletions

View File

@ -88,13 +88,13 @@ namespace spades {
void Init() { OnProhibitedAction(); }
void Shutdown() { OnProhibitedAction(); }
IImage *RegisterImage(const char *filename) { return base->RegisterImage(filename); }
IModel *RegisterModel(const char *filename) { return base->RegisterModel(filename); }
Handle<IImage> RegisterImage(const char *filename) { return base->RegisterImage(filename); }
Handle<IModel> RegisterModel(const char *filename) { return base->RegisterModel(filename); }
IImage *CreateImage(Bitmap *bmp) { return base->CreateImage(bmp); }
IModel *CreateModel(VoxelModel *m) { return base->CreateModel(m); }
Handle<IImage> CreateImage(Bitmap &bmp) { return base->CreateImage(bmp); }
Handle<IModel> CreateModel(VoxelModel &m) { return base->CreateModel(m); }
void SetGameMap(GameMap *) { OnProhibitedAction(); }
void SetGameMap(stmp::optional<GameMap &>) { OnProhibitedAction(); }
void SetFogDistance(float) { OnProhibitedAction(); }
void SetFogColor(Vector3) { OnProhibitedAction(); }
@ -108,14 +108,9 @@ namespace spades {
}
}
void RenderModel(IModel *model, const ModelRenderParam &_p) {
void RenderModel(IModel &model, const ModelRenderParam &_p) {
ModelRenderParam p = _p;
if (!model) {
SPInvalidArgument("model");
return;
}
if (p.depthHack && !allowDepthHack) {
OnProhibitedAction();
return;
@ -133,20 +128,20 @@ namespace spades {
return;
}
auto bounds = (p.matrix * OBB3(model->GetBoundingBox())).GetBoundingAABB();
auto bounds = (p.matrix * OBB3(model.GetBoundingBox())).GetBoundingAABB();
if (CheckVisibility(bounds)) {
base->RenderModel(model, p);
}
}
void AddDebugLine(Vector3 a, Vector3 b, Vector4 color) { OnProhibitedAction(); }
void AddSprite(IImage *image, Vector3 center, float radius, float rotation) {
void AddSprite(IImage &image, Vector3 center, float radius, float rotation) {
Vector3 rad(radius * 1.5f, radius * 1.5f, radius * 1.5f);
if (CheckVisibility(AABB3(center - rad, center + rad))) {
base->AddSprite(image, center, radius, rotation);
}
}
void AddLongSprite(IImage *image, Vector3 p1, Vector3 p2, float radius) {
void AddLongSprite(IImage &image, Vector3 p1, Vector3 p2, float radius) {
Vector3 rad(radius * 1.5f, radius * 1.5f, radius * 1.5f);
AABB3 bounds1(p1 - rad, p1 + rad);
AABB3 bounds2(p2 - rad, p2 + rad);
@ -169,31 +164,31 @@ namespace spades {
/** Sets color for image drawing. Always alpha premultiplied. */
void SetColorAlphaPremultiplied(Vector4 col) { base->SetColorAlphaPremultiplied(col); }
void DrawImage(IImage *img, const Vector2 &outTopLeft) {
void DrawImage(stmp::optional<IImage &> img, const Vector2 &outTopLeft) {
if (allowDepthHack)
base->DrawImage(img, outTopLeft);
else
OnProhibitedAction();
}
void DrawImage(IImage *img, const AABB2 &outRect) {
void DrawImage(stmp::optional<IImage &> img, const AABB2 &outRect) {
if (allowDepthHack)
base->DrawImage(img, outRect);
else
OnProhibitedAction();
}
void DrawImage(IImage *img, const Vector2 &outTopLeft, const AABB2 &inRect) {
void DrawImage(stmp::optional<IImage &> img, const Vector2 &outTopLeft, const AABB2 &inRect) {
if (allowDepthHack)
base->DrawImage(img, outTopLeft, inRect);
else
OnProhibitedAction();
}
void DrawImage(IImage *img, const AABB2 &outRect, const AABB2 &inRect) {
void DrawImage(stmp::optional<IImage &> img, const AABB2 &outRect, const AABB2 &inRect) {
if (allowDepthHack)
base->DrawImage(img, outRect, inRect);
else
OnProhibitedAction();
}
void DrawImage(IImage *img, const Vector2 &outTopLeft, const Vector2 &outTopRight,
void DrawImage(stmp::optional<IImage &> img, const Vector2 &outTopLeft, const Vector2 &outTopRight,
const Vector2 &outBottomLeft, const AABB2 &inRect) {
if (allowDepthHack)
base->DrawImage(img, outTopLeft, outTopRight, outBottomLeft, inRect);
@ -209,9 +204,9 @@ namespace spades {
void Flip() { OnProhibitedAction(); }
Bitmap *ReadBitmap() {
Handle<Bitmap> ReadBitmap() {
OnProhibitedAction();
return nullptr;
return {};
}
float ScreenWidth() { return base->ScreenWidth(); }
@ -679,7 +674,7 @@ namespace spades {
// add glare
renderer->SetColorAlphaPremultiplied(MakeVector4(1, .7f, .5f, 0) * brightness *
.3f);
renderer->AddSprite(renderer->RegisterImage("Gfx/Glare.png"),
renderer->AddSprite(*renderer->RegisterImage("Gfx/Glare.png"),
(eyeMatrix * MakeVector3(0, 0.3f, -0.3f)).GetXYZ(), .8f, 0.f);
}
@ -756,8 +751,8 @@ namespace spades {
ModelRenderParam param;
param.depthHack = true;
IModel *model = renderer->RegisterModel("Models/Player/Arm.kv6");
IModel *model2 = renderer->RegisterModel("Models/Player/UpperArm.kv6");
Handle<IModel> model = renderer->RegisterModel("Models/Player/Arm.kv6");
Handle<IModel> model2 = renderer->RegisterModel("Models/Player/UpperArm.kv6");
IntVector3 col = p.GetColor();
param.customColor = MakeVector3(col.x / 255.f, col.y / 255.f, col.z / 255.f);
@ -797,7 +792,7 @@ namespace spades {
mat = eyeMatrix * mat;
param.matrix = mat;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
}
{
@ -812,7 +807,7 @@ namespace spades {
mat = eyeMatrix * mat;
param.matrix = mat;
renderer->RenderModel(model2, param);
renderer->RenderModel(*model2, param);
}
}
}
@ -833,8 +828,8 @@ namespace spades {
IntVector3 col = p.GetColor();
param.customColor = MakeVector3(col.x / 255.f, col.y / 255.f, col.z / 255.f);
IModel *model = renderer->RegisterModel("Models/Player/Dead.kv6");
renderer->RenderModel(model, param);
Handle<IModel> model = renderer->RegisterModel("Models/Player/Dead.kv6");
renderer->RenderModel(*model, param);
}
return;
}
@ -870,7 +865,7 @@ namespace spades {
}
ModelRenderParam param;
IModel *model;
Handle<IModel> model;
Vector3 front = p.GetFront();
IntVector3 col = p.GetColor();
param.customColor = MakeVector3(col.x / 255.f, col.y / 255.f, col.z / 255.f);
@ -907,16 +902,16 @@ namespace spades {
model = renderer->RegisterModel("Models/Player/LegCrouch.kv6");
param.matrix = leg1 * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
param.matrix = leg2 * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
torso = Matrix4::Translate(0.f, 0.f, -0.55f);
torso = lower * torso;
model = renderer->RegisterModel("Models/Player/TorsoCrouch.kv6");
param.matrix = torso * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
head = Matrix4::Translate(0.f, 0.f, -0.0f);
head = torso * head;
@ -941,16 +936,16 @@ namespace spades {
model = renderer->RegisterModel("Models/Player/Leg.kv6");
param.matrix = leg1 * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
param.matrix = leg2 * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
torso = Matrix4::Translate(0.f, 0.f, -1.0f);
torso = lower * torso;
model = renderer->RegisterModel("Models/Player/Torso.kv6");
param.matrix = torso * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
head = Matrix4::Translate(0.f, 0.f, -0.0f);
head = torso * head;
@ -973,13 +968,13 @@ namespace spades {
model = renderer->RegisterModel("Models/Player/Arms.kv6");
param.matrix = arms * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
head = head * Matrix4::Rotate(MakeVector3(1, 0, 0), pitch);
model = renderer->RegisterModel("Models/Player/Head.kv6");
param.matrix = head * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
// draw tool
{
@ -1009,7 +1004,7 @@ namespace spades {
model = renderer->RegisterModel("Models/MapObjects/Intel.kv6");
param.matrix = mIntel * scaler;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
param.customColor =
MakeVector3(col.x / 255.f, col.y / 255.f, col.z / 255.f);
@ -1219,7 +1214,7 @@ namespace spades {
if (cg_ejectBrass) {
float dist = (player.GetOrigin() - lastSceneDef.viewOrigin).GetPoweredLength();
if (dist < 130.f * 130.f) {
IModel *model = NULL;
Handle<IModel> model;
Handle<IAudioChunk> snd = NULL;
Handle<IAudioChunk> snd2 = NULL;
switch (player.GetWeapon().GetWeaponType()) {

View File

@ -494,7 +494,7 @@ namespace spades {
void Client::AddGrenadeToScene(Grenade &g) {
SPADES_MARK_FUNCTION();
IModel *model;
Handle<IModel> model;
model = renderer->RegisterModel("Models/Weapons/Grenade/Grenade.kv6");
if (g.GetPosition().z > 63.f) {
@ -512,7 +512,7 @@ namespace spades {
mat = Matrix4::Translate(position) * mat;
param.matrix = mat;
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
}
void Client::AddDebugObjectToScene(const spades::OBB3 &obb, const Vector4 &color) {
@ -547,8 +547,8 @@ namespace spades {
SPADES_MARK_FUNCTION();
CTFGameMode &mode = dynamic_cast<CTFGameMode &>(world->GetMode().value());
int tId;
IModel *base = renderer->RegisterModel("Models/MapObjects/CheckPoint.kv6");
IModel *intel = renderer->RegisterModel("Models/MapObjects/Intel.kv6");
Handle<IModel> base = renderer->RegisterModel("Models/MapObjects/CheckPoint.kv6");
Handle<IModel> intel = renderer->RegisterModel("Models/MapObjects/Intel.kv6");
for (tId = 0; tId < 2; tId++) {
CTFGameMode::Team &team = mode.GetTeam(tId);
IntVector3 col = world->GetTeam(tId).color;
@ -560,13 +560,13 @@ namespace spades {
// draw base
param.matrix = Matrix4::Translate(team.basePos);
param.matrix = param.matrix * Matrix4::Scale(.3f);
renderer->RenderModel(base, param);
renderer->RenderModel(*base, param);
// draw flag
if (!mode.GetTeam(1 - tId).hasIntel) {
param.matrix = Matrix4::Translate(team.flagPos);
param.matrix = param.matrix * Matrix4::Scale(.1f);
renderer->RenderModel(intel, param);
renderer->RenderModel(*intel, param);
}
}
}
@ -575,7 +575,7 @@ namespace spades {
SPADES_MARK_FUNCTION();
TCGameMode &mode = dynamic_cast<TCGameMode &>(world->GetMode().value());
int tId;
IModel *base = renderer->RegisterModel("Models/MapObjects/CheckPoint.kv6");
Handle<IModel> base = renderer->RegisterModel("Models/MapObjects/CheckPoint.kv6");
int cnt = mode.GetNumTerritories();
for (tId = 0; tId < cnt; tId++) {
TCGameMode::Territory &t = mode.GetTerritory(tId);
@ -593,7 +593,7 @@ namespace spades {
// draw base
param.matrix = Matrix4::Translate(t.pos);
param.matrix = param.matrix * Matrix4::Scale(.3f);
renderer->RenderModel(base, param);
renderer->RenderModel(*base, param);
}
}
@ -657,9 +657,9 @@ namespace spades {
if ((int)blocks.size() > p->GetNumBlocks())
color = MakeVector3(1.f, 0.f, 0.f);
IModel *curLine =
Handle<IModel> curLine =
renderer->RegisterModel("Models/MapObjects/BlockCursorLine.kv6");
IModel *curSingle =
Handle<IModel> curSingle =
renderer->RegisterModel("Models/MapObjects/BlockCursorSingle.kv6");
for (size_t i = 0; i < blocks.size(); i++) {
IntVector3 &v = blocks[i];
@ -676,7 +676,7 @@ namespace spades {
1.f / 24.f +
(solid ? 0.0005f
: 0.f)); // make cursor larger if needed to stop z-fighting
renderer->RenderModel(blocks.size() > 1 ? curLine : curSingle, param);
renderer->RenderModel(blocks.size() > 1 ? *curLine : *curSingle, param);
}
}
}

View File

@ -618,7 +618,7 @@ namespace spades {
ModelRenderParam param;
param.customColor = color;
IModel *model;
Handle<IModel> model;
Matrix4 scaler = Matrix4::Scale(.1f);
// draw torso
@ -639,7 +639,7 @@ namespace spades {
param.matrix = torso * scaler;
model = renderer.RegisterModel("Models/Player/Torso.kv6");
renderer.RenderModel(model, param);
renderer.RenderModel(*model, param);
}
// draw Head
{
@ -658,7 +658,7 @@ namespace spades {
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(-aX, aY, -aZ, headBase) * scaler;
renderer.RenderModel(model, param);
renderer.RenderModel(*model, param);
}
// draw Arms
@ -677,7 +677,7 @@ namespace spades {
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, arm1Base) * scaler;
renderer.RenderModel(model, param);
renderer.RenderModel(*model, param);
aZ = nodes[Arm2].pos - nodes[Torso2].pos;
aZ = aZ.Normalize();
@ -686,7 +686,7 @@ namespace spades {
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, arm2Base) * scaler;
renderer.RenderModel(model, param);
renderer.RenderModel(*model, param);
}
// draw Leg
@ -705,7 +705,7 @@ namespace spades {
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, leg1Base) * scaler;
renderer.RenderModel(model, param);
renderer.RenderModel(*model, param);
aZ = nodes[Leg2].pos - nodes[Torso4].pos;
aZ = aZ.Normalize();
@ -714,7 +714,7 @@ namespace spades {
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, leg2Base) * scaler;
renderer.RenderModel(model, param);
renderer.RenderModel(*model, param);
}
}

View File

@ -101,7 +101,7 @@ namespace spades {
Bin(int width, int height, client::IRenderer &r) : width(width), height(height) {
Handle<Bitmap> tmpbmp(new Bitmap(width, height), false);
memset(tmpbmp->GetPixels(), 0, tmpbmp->GetWidth() * tmpbmp->GetHeight() * 4);
image.Set(r.CreateImage(tmpbmp), false);
image = r.CreateImage(*tmpbmp);
skyline.emplace_back(0, 0);
skyline.emplace_back(width, 0);
}

View File

@ -89,7 +89,7 @@ namespace spades {
matrix = Matrix4::Translate(matTrans);
// build renderer model
model = client->GetRenderer()->CreateModel(vmodel);
model = client->GetRenderer()->CreateModel(*vmodel).Unmanage();
time = 0.f;
}
@ -223,7 +223,7 @@ namespace spades {
void FallingBlock::Render3D() {
ModelRenderParam param;
param.matrix = matrix;
client->GetRenderer()->RenderModel(model, param);
client->GetRenderer()->RenderModel(*model, param);
}
} // namespace client
} // namespace spades

View File

@ -217,7 +217,7 @@ namespace spades {
float move = (groundTime - 1.f) * .2f;
param.matrix = Matrix4::Translate(0, 0, move) * param.matrix;
}
renderer->RenderModel(model, param);
renderer->RenderModel(*model, param);
}
} // namespace client
} // namespace spades

View File

@ -176,10 +176,10 @@ namespace spades {
: renderer(renderer), manager(manager) {
for (auto font = manager->fonts.begin(); font != manager->fonts.end(); ++font) {
auto imgPath = (*font)->imagePath;
auto *img = renderer->RegisterImage(imgPath.c_str()); // addref'd
auto img = renderer->RegisterImage(imgPath.c_str()).Unmanage();
images.push_back(img);
}
whiteImage.Set(renderer->RegisterImage("Gfx/White.tga"), false);
whiteImage = renderer->RegisterImage("Gfx/White.tga");
// SW renderer doesn't perform linear interpolation on
// rendering images, so size rounding must be done to

View File

@ -22,10 +22,10 @@
#include <array>
#include <Core/Math.h>
#include "IImage.h"
#include "IModel.h"
#include "SceneDefinition.h"
#include <Core/Math.h>
#include <Core/RefCountedObject.h>
namespace spades {
@ -95,8 +95,8 @@ namespace spades {
virtual void Init() = 0;
virtual void Shutdown() = 0;
virtual IImage *RegisterImage(const char *filename) = 0;
virtual IModel *RegisterModel(const char *filename) = 0;
virtual Handle<IImage> RegisterImage(const char *filename) = 0;
virtual Handle<IModel> RegisterModel(const char *filename) = 0;
/**
* Clear the cache of models and images loaded via `RegisterModel`
@ -105,10 +105,10 @@ namespace spades {
*/
virtual void ClearCache() {}
virtual IImage *CreateImage(Bitmap *) = 0;
virtual IModel *CreateModel(VoxelModel *) = 0;
virtual Handle<IImage> CreateImage(Bitmap &) = 0;
virtual Handle<IModel> CreateModel(VoxelModel &) = 0;
virtual void SetGameMap(GameMap *) = 0;
virtual void SetGameMap(stmp::optional<GameMap &>) = 0;
virtual void SetFogDistance(float) = 0;
virtual void SetFogColor(Vector3) = 0;
@ -118,11 +118,11 @@ namespace spades {
virtual void AddLight(const client::DynamicLightParam &light) = 0;
virtual void RenderModel(IModel *, const ModelRenderParam &) = 0;
virtual void RenderModel(IModel &, const ModelRenderParam &) = 0;
virtual void AddDebugLine(Vector3 a, Vector3 b, Vector4 color) = 0;
virtual void AddSprite(IImage *, Vector3 center, float radius, float rotation) = 0;
virtual void AddLongSprite(IImage *, Vector3 p1, Vector3 p2, float radius) = 0;
virtual void AddSprite(IImage &, Vector3 center, float radius, float rotation) = 0;
virtual void AddLongSprite(IImage &, Vector3 p1, Vector3 p2, float radius) = 0;
/** Finalizes a scene. 2D drawing follows. */
virtual void EndScene() = 0;
@ -138,12 +138,15 @@ namespace spades {
/** Sets color for image drawing. Always alpha premultiplied. */
virtual void SetColorAlphaPremultiplied(Vector4) = 0;
virtual void DrawImage(IImage *, const Vector2 &outTopLeft) = 0;
virtual void DrawImage(IImage *, const AABB2 &outRect) = 0;
virtual void DrawImage(IImage *, const Vector2 &outTopLeft, const AABB2 &inRect) = 0;
virtual void DrawImage(IImage *, const AABB2 &outRect, const AABB2 &inRect) = 0;
virtual void DrawImage(IImage *, const Vector2 &outTopLeft, const Vector2 &outTopRight,
const Vector2 &outBottomLeft, const AABB2 &inRect) = 0;
virtual void DrawImage(stmp::optional<IImage &>, const Vector2 &outTopLeft) = 0;
virtual void DrawImage(stmp::optional<IImage &>, const AABB2 &outRect) = 0;
virtual void DrawImage(stmp::optional<IImage &>, const Vector2 &outTopLeft,
const AABB2 &inRect) = 0;
virtual void DrawImage(stmp::optional<IImage &>, const AABB2 &outRect,
const AABB2 &inRect) = 0;
virtual void DrawImage(stmp::optional<IImage &>, const Vector2 &outTopLeft,
const Vector2 &outTopRight, const Vector2 &outBottomLeft,
const AABB2 &inRect) = 0;
virtual void DrawFlatGameMap(const AABB2 &outRect, const AABB2 &inRect) = 0;
@ -154,10 +157,10 @@ namespace spades {
virtual void Flip() = 0;
/** get a rendered image. */
virtual Bitmap *ReadBitmap() = 0;
virtual Handle<Bitmap> ReadBitmap() = 0;
virtual float ScreenWidth() = 0;
virtual float ScreenHeight() = 0;
};
}
}
} // namespace client
} // namespace spades

View File

@ -156,7 +156,7 @@ namespace spades {
col.w = 0.f;
renderer->SetColorAlphaPremultiplied(col);
renderer->AddSprite(image, position, radius, angle);
renderer->AddSprite(*image, position, radius, angle);
}
void ParticleSpriteEntity::SetImage(IImage *img) {
if (img == image)

View File

@ -79,7 +79,7 @@ namespace spades {
Vector3 pos2 = startPos + dir * endDist;
Vector4 col = {1.f, .6f, .2f, 0.f};
r->SetColorAlphaPremultiplied(col * 0.4f);
r->AddLongSprite(image, pos1, pos2, .05f);
r->AddLongSprite(*image, pos1, pos2, .05f);
}
}
}

View File

@ -9,6 +9,7 @@
#pragma once
#include <Core/Math.h>
#include <Core/RefCountedObject.h>
#include "ILocalEntity.h"
namespace spades {
@ -17,7 +18,7 @@ namespace spades {
class IImage;
class Tracer : public ILocalEntity {
Client *client;
IImage *image;
Handle<IImage> image;
Vector3 startPos, dir;
float length;
float curDistance;
@ -33,4 +34,4 @@ namespace spades {
void Render3D() override;
};
}
}
}

View File

@ -40,6 +40,7 @@ namespace spades {
Bitmap(int w, int h);
Bitmap(uint32_t *pixels, int w, int h);
// TODO: Return `Handle<Bitmap>`
static Bitmap *Load(const std::string &);
static Bitmap *Load(IStream *); // must be seekable
void Save(const std::string &);

View File

@ -38,6 +38,8 @@ namespace spades {
lastRenderer = NULL;
}
GLDynamicLightShader::~GLDynamicLightShader() {}
std::vector<GLShader *>
GLDynamicLightShader::RegisterShader(spades::draw::GLProgramManager *r) {
std::vector<GLShader *> shaders;
@ -54,7 +56,7 @@ namespace spades {
int GLDynamicLightShader::operator()(GLRenderer *renderer, spades::draw::GLProgram *program,
const GLDynamicLight &light, int texStage) {
if (lastRenderer != renderer) {
whiteImage = static_cast<GLImage *>(renderer->RegisterImage("Gfx/White.tga"));
whiteImage = renderer->RegisterImage("Gfx/White.tga").Cast<GLImage>();
lastRenderer = renderer;
}

View File

@ -34,7 +34,7 @@ namespace spades {
class GLProgramManager;
class GLDynamicLightShader {
GLRenderer *lastRenderer;
GLImage *whiteImage;
Handle<GLImage> whiteImage;
GLProgramUniform dynamicLightOrigin;
GLProgramUniform dynamicLightColor;
@ -45,7 +45,7 @@ namespace spades {
public:
GLDynamicLightShader();
~GLDynamicLightShader() {}
~GLDynamicLightShader();
static std::vector<GLShader *> RegisterShader(GLProgramManager *);

View File

@ -37,11 +37,7 @@ namespace spades {
chunkInvalid.push_back(false);
Handle<Bitmap> bmp(GenerateBitmap(0, 0, m->Width(), m->Height()), false);
try {
image = static_cast<GLImage *>(renderer->CreateImage(bmp));
} catch (...) {
throw;
}
image = renderer->CreateImage(*bmp).Cast<GLImage>();
image->Bind(IGLDevice::Texture2D);
IGLDevice *dev = renderer->GetGLDevice();
@ -51,7 +47,7 @@ namespace spades {
IGLDevice::Nearest);
}
GLFlatMapRenderer::~GLFlatMapRenderer() { image->Release(); }
GLFlatMapRenderer::~GLFlatMapRenderer() {}
Bitmap *GLFlatMapRenderer::GenerateBitmap(int mx, int my, int w, int h) {
SPADES_MARK_FUNCTION();
@ -119,7 +115,7 @@ namespace spades {
chunkInvalid[i] = false;
}
renderer->DrawImage(image, dest, src);
renderer->DrawImage(*image, dest, src);
}
}
}

View File

@ -23,6 +23,7 @@
#include <vector>
#include <Core/Math.h>
#include <Core/RefCountedObject.h>
namespace spades {
class Bitmap;
@ -39,7 +40,7 @@ namespace spades {
client::GameMap *map;
std::vector<bool> chunkInvalid;
GLImage *image;
Handle<GLImage> image;
int chunkCols, chunkRows;
@ -53,4 +54,4 @@ namespace spades {
void GameMapChanged(int x, int y, int z, client::GameMap *);
};
}
}
}

View File

@ -53,22 +53,22 @@ namespace spades {
device->BindTexture(target, tex);
}
GLImage *GLImage::FromBitmap(spades::Bitmap *bmp, spades::draw::IGLDevice *dev) {
Handle<GLImage> GLImage::FromBitmap(spades::Bitmap &bmp, spades::draw::IGLDevice *dev) {
SPADES_MARK_FUNCTION();
IGLDevice::UInteger tex;
tex = dev->GenTexture();
dev->BindTexture(IGLDevice::Texture2D, tex);
dev->TexImage2D(IGLDevice::Texture2D, 0, IGLDevice::RGBA, bmp->GetWidth(),
bmp->GetHeight(), 0, IGLDevice::RGBA, IGLDevice::UnsignedByte,
bmp->GetPixels());
dev->TexImage2D(IGLDevice::Texture2D, 0, IGLDevice::RGBA, bmp.GetWidth(),
bmp.GetHeight(), 0, IGLDevice::RGBA, IGLDevice::UnsignedByte,
bmp.GetPixels());
dev->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureMagFilter, IGLDevice::Linear);
dev->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureMinFilter,
IGLDevice::LinearMipmapNearest);
dev->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureWrapS, IGLDevice::Repeat);
dev->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureWrapT, IGLDevice::Repeat);
dev->GenerateMipmap(IGLDevice::Texture2D);
return new GLImage(tex, dev, bmp->GetWidth(), bmp->GetHeight());
return Handle<GLImage>::New(tex, dev, (float)bmp.GetWidth(), (float)bmp.GetHeight());
}
void GLImage::SubImage(spades::Bitmap *bmp, int x, int y) {

View File

@ -42,7 +42,7 @@ namespace spades {
public:
GLImage(IGLDevice::UInteger textureObject, IGLDevice *device, float w, float h,
bool autoDelete = true);
static GLImage *FromBitmap(Bitmap *, IGLDevice *);
static Handle<GLImage> FromBitmap(Bitmap &, IGLDevice *);
void Bind(IGLDevice::Enum target);
float GetWidth() override { return width; }

View File

@ -73,7 +73,7 @@ namespace spades {
Handle<Bitmap> bmp(Bitmap::Load(name), false);
return GLImage::FromBitmap(bmp, device);
return GLImage::FromBitmap(*bmp, device).Unmanage();
}
// draw all imaegs so that all textures are resident

View File

@ -38,7 +38,7 @@ namespace spades {
thru = renderer->RegisterProgram("Shaders/PostFilters/PassThroughConstAlpha.program");
gauss1d = renderer->RegisterProgram("Shaders/PostFilters/Gauss1D.program");
dust = renderer->RegisterProgram("Shaders/PostFilters/LensDust.program");
dustImg = (GLImage *)renderer->RegisterImage("Textures/LensDustTexture.jpg");
dustImg = renderer->RegisterImage("Textures/LensDustTexture.jpg").Cast<GLImage>();
IGLDevice *dev = renderer->GetGLDevice();
noiseTex = dev->GenTexture();

View File

@ -36,7 +36,7 @@ namespace spades {
GLProgram *thru;
GLProgram *dust;
GLProgram *gauss1d;
GLImage *dustImg;
Handle<GLImage> dustImg;
GLRenderer *renderer;
IGLDevice::UInteger noiseTex;
std::vector<uint32_t> noise;

View File

@ -39,14 +39,14 @@ namespace spades {
blurProgram = renderer->RegisterProgram("Shaders/PostFilters/Gauss1D.program");
scannerProgram = renderer->RegisterProgram("Shaders/LensFlare/Scanner.program");
drawProgram = renderer->RegisterProgram("Shaders/LensFlare/Draw.program");
flare1 = (GLImage *)renderer->RegisterImage("Gfx/LensFlare/1.png");
flare2 = (GLImage *)renderer->RegisterImage("Gfx/LensFlare/2.png");
flare3 = (GLImage *)renderer->RegisterImage("Gfx/LensFlare/3.png");
flare4 = (GLImage *)renderer->RegisterImage("Gfx/LensFlare/4.jpg");
mask1 = (GLImage *)renderer->RegisterImage("Gfx/LensFlare/mask1.png");
mask2 = (GLImage *)renderer->RegisterImage("Gfx/LensFlare/mask2.png");
mask3 = (GLImage *)renderer->RegisterImage("Gfx/LensFlare/mask3.png");
white = (GLImage *)renderer->RegisterImage("Gfx/White.tga");
flare1 = renderer->RegisterImage("Gfx/LensFlare/1.png").Cast<GLImage>();
flare2 = renderer->RegisterImage("Gfx/LensFlare/2.png").Cast<GLImage>();
flare3 = renderer->RegisterImage("Gfx/LensFlare/3.png").Cast<GLImage>();
flare4 = renderer->RegisterImage("Gfx/LensFlare/4.jpg").Cast<GLImage>();
mask1 = renderer->RegisterImage("Gfx/LensFlare/mask1.png").Cast<GLImage>();
mask2 = renderer->RegisterImage("Gfx/LensFlare/mask2.png").Cast<GLImage>();
mask3 = renderer->RegisterImage("Gfx/LensFlare/mask3.png").Cast<GLImage>();
white = renderer->RegisterImage("Gfx/White.tga").Cast<GLImage>();
}
GLColorBuffer GLLensFlareFilter::Blur(GLColorBuffer buffer, float spread) {

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades 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.
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
@ -30,8 +30,8 @@ namespace spades {
class GLLensFlareFilter {
GLRenderer *renderer;
GLProgram *blurProgram, *scannerProgram, *drawProgram;
GLImage *flare1, *flare2, *flare3, *flare4, *white;
GLImage *mask1, *mask2, *mask3;
Handle<GLImage> flare1, flare2, flare3, flare4, white;
Handle<GLImage> mask1, mask2, mask3;
GLColorBuffer Blur(GLColorBuffer, float spread = 1.f);
public:
GLLensFlareFilter(GLRenderer *);

View File

@ -73,7 +73,7 @@ namespace spades {
depthonlyProgram = renderer->RegisterProgram("Shaders/BasicBlockDepthOnly.program");
dlightProgram = renderer->RegisterProgram("Shaders/BasicBlockDynamicLit.program");
backfaceProgram = renderer->RegisterProgram("Shaders/BackFaceBlock.program");
aoImage = (GLImage *)renderer->RegisterImage("Gfx/AmbientOcclusion.png");
aoImage = renderer->RegisterImage("Gfx/AmbientOcclusion.png").Cast<GLImage>();
static const uint8_t squareVertices[] = {0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1};
squareVertexBuffer = device->GenBuffer();

View File

@ -44,7 +44,7 @@ namespace spades {
GLProgram *basicProgram;
GLProgram *dlightProgram;
GLProgram *backfaceProgram;
GLImage *aoImage;
Handle<GLImage> aoImage;
IGLDevice::UInteger squareVertexBuffer;

View File

@ -64,7 +64,7 @@ namespace spades {
Handle<VoxelModel> voxelModel{VoxelModelLoader::Load(name), false};
return static_cast<GLModel *>(renderer->CreateModelOptimized(voxelModel));
return renderer->CreateModelOptimized(*voxelModel).Cast<GLModel>().Unmanage();
}
void GLModelManager::ClearCache() { models.clear(); }

View File

@ -58,7 +58,7 @@ namespace spades {
renderer->RegisterProgram("Shaders/OptimizedVoxelModelDynamicLit.program");
shadowMapProgram =
renderer->RegisterProgram("Shaders/OptimizedVoxelModelShadowMap.program");
aoImage = (GLImage *)renderer->RegisterImage("Gfx/AmbientOcclusion.png");
aoImage = renderer->RegisterImage("Gfx/AmbientOcclusion.png").Cast<GLImage>();
buffer = device->GenBuffer();
device->BindBuffer(IGLDevice::ArrayBuffer, buffer);
@ -96,7 +96,6 @@ namespace spades {
GLOptimizedVoxelModel::~GLOptimizedVoxelModel() {
SPADES_MARK_FUNCTION();
image->Release();
device->DeleteBuffer(idxBuffer);
device->DeleteBuffer(buffer);
}
@ -137,7 +136,7 @@ namespace spades {
std::vector<uint16_t>().swap(bmpIndex);
image = static_cast<GLImage *>(renderer->CreateImage(bmp));
image = renderer->CreateImage(*bmp).Cast<GLImage>();
}
uint8_t GLOptimizedVoxelModel::calcAOID(VoxelModel *m, int x, int y, int z, int ux, int uy,

View File

@ -51,8 +51,8 @@ namespace spades {
GLProgram *program;
GLProgram *dlightProgram;
GLProgram *shadowMapProgram;
GLImage *image;
GLImage *aoImage;
Handle<GLImage> image;
Handle<GLImage> aoImage;
IGLDevice::UInteger buffer;
IGLDevice::UInteger idxBuffer;

View File

@ -241,12 +241,12 @@ namespace spades {
SPLog("GLRenderer finalized");
}
client::IImage *GLRenderer::RegisterImage(const char *filename) {
Handle<client::IImage> GLRenderer::RegisterImage(const char *filename) {
SPADES_MARK_FUNCTION();
return imageManager->RegisterImage(filename);
}
client::IModel *GLRenderer::RegisterModel(const char *filename) {
Handle<client::IModel> GLRenderer::RegisterModel(const char *filename) {
SPADES_MARK_FUNCTION();
return modelManager->RegisterModel(filename);
}
@ -257,22 +257,22 @@ namespace spades {
imageManager->ClearCache();
}
client::IImage *GLRenderer::CreateImage(spades::Bitmap *bmp) {
Handle<client::IImage> GLRenderer::CreateImage(spades::Bitmap &bmp) {
SPADES_MARK_FUNCTION();
return GLImage::FromBitmap(bmp, device);
return GLImage::FromBitmap(bmp, device).Cast<client::IImage>();
}
client::IModel *GLRenderer::CreateModel(spades::VoxelModel *model) {
Handle<client::IModel> GLRenderer::CreateModel(spades::VoxelModel &model) {
SPADES_MARK_FUNCTION();
return new GLVoxelModel(model, this);
return Handle<GLVoxelModel>::New(&model, this).Cast<client::IModel>();
}
client::IModel *GLRenderer::CreateModelOptimized(spades::VoxelModel *model) {
Handle<client::IModel> GLRenderer::CreateModelOptimized(spades::VoxelModel &model) {
SPADES_MARK_FUNCTION();
if (settings.r_optimizedVoxelModel) {
return new GLOptimizedVoxelModel(model, this);
return Handle<GLOptimizedVoxelModel>::New(&model, this).Cast<client::IModel>();
} else {
return new GLVoxelModel(model, this);
return Handle<GLVoxelModel>::New(&model, this).Cast<client::IModel>();
}
}
@ -283,11 +283,12 @@ namespace spades {
}
}
void GLRenderer::SetGameMap(client::GameMap *mp) {
void GLRenderer::SetGameMap(stmp::optional<client::GameMap &> newMap) {
SPADES_MARK_FUNCTION();
if (mp)
if (newMap) {
EnsureInitialized();
}
client::GameMap *oldMap = map;
@ -305,34 +306,34 @@ namespace spades {
delete ambientShadowRenderer;
ambientShadowRenderer = NULL;
if (mp) {
if (newMap) {
SPLog("Creating new renderers...");
SPLog("Creating Terrain Shadow Map Renderer");
mapShadowRenderer = new GLMapShadowRenderer(this, mp);
mapShadowRenderer = new GLMapShadowRenderer(this, newMap.get_pointer());
SPLog("Creating TerrainRenderer");
mapRenderer = new GLMapRenderer(mp, this);
mapRenderer = new GLMapRenderer(newMap.get_pointer(), this);
SPLog("Creating Minimap Renderer");
flatMapRenderer = new GLFlatMapRenderer(this, mp);
flatMapRenderer = new GLFlatMapRenderer(this, newMap.get_pointer());
SPLog("Creating Water Renderer");
waterRenderer = new GLWaterRenderer(this, mp);
waterRenderer = new GLWaterRenderer(this, newMap.get_pointer());
if (settings.r_radiosity) {
SPLog("Creating Ray-traced Ambient Occlusion Renderer");
ambientShadowRenderer = new GLAmbientShadowRenderer(this, mp);
ambientShadowRenderer = new GLAmbientShadowRenderer(this, newMap.get_pointer());
SPLog("Creating Relective Shadow Maps Renderer");
radiosityRenderer = new GLRadiosityRenderer(this, mp);
radiosityRenderer = new GLRadiosityRenderer(this, newMap.get_pointer());
} else {
SPLog("Radiosity is disabled");
}
mp->AddListener(this);
mp->AddRef();
newMap->AddListener(this);
newMap->AddRef();
SPLog("Created");
} else {
SPLog("No map loaded");
}
this->map = mp;
this->map = newMap.get_pointer();
if (oldMap) {
oldMap->RemoveListener(this);
oldMap->Release();
@ -490,20 +491,17 @@ namespace spades {
#pragma mark - Add Scene Objects
void GLRenderer::RenderModel(client::IModel *model, const client::ModelRenderParam &param) {
void GLRenderer::RenderModel(client::IModel &model, const client::ModelRenderParam &param) {
SPADES_MARK_FUNCTION();
GLModel *m = dynamic_cast<GLModel *>(model);
if (!m) {
SPInvalidArgument("model");
}
GLModel &glModel = dynamic_cast<GLModel &>(model);
EnsureInitialized();
EnsureSceneStarted();
// TODO: early frustrum cull?
modelRenderer->AddModel(m, param);
modelRenderer->AddModel(&glModel, param);
}
void GLRenderer::AddLight(const client::DynamicLightParam &light) {
@ -523,12 +521,10 @@ namespace spades {
debugLines.push_back(line);
}
void GLRenderer::AddSprite(client::IImage *img, spades::Vector3 center, float radius,
void GLRenderer::AddSprite(client::IImage &img, spades::Vector3 center, float radius,
float rotation) {
SPADES_MARK_FUNCTION_DEBUG();
GLImage *im = dynamic_cast<GLImage *>(img);
if (!im)
SPInvalidArgument("im");
GLImage &glImage = dynamic_cast<GLImage &>(img);
if (!SphereFrustrumCull(center, radius * 1.5f))
return;
@ -536,20 +532,18 @@ namespace spades {
EnsureInitialized();
EnsureSceneStarted();
spriteRenderer->Add(im, center, radius, rotation, drawColorAlphaPremultiplied);
spriteRenderer->Add(&glImage, center, radius, rotation, drawColorAlphaPremultiplied);
}
void GLRenderer::AddLongSprite(client::IImage *img, spades::Vector3 p1, spades::Vector3 p2,
void GLRenderer::AddLongSprite(client::IImage &img, spades::Vector3 p1, spades::Vector3 p2,
float radius) {
SPADES_MARK_FUNCTION_DEBUG();
GLImage *im = dynamic_cast<GLImage *>(img);
if (!im)
SPInvalidArgument("im");
GLImage &glImage = dynamic_cast<GLImage &>(img);
EnsureInitialized();
EnsureSceneStarted();
longSpriteRenderer->Add(im, p1, p2, radius, drawColorAlphaPremultiplied);
longSpriteRenderer->Add(&glImage, p1, p2, radius, drawColorAlphaPremultiplied);
}
#pragma mark - Scene Finalizer
@ -1045,7 +1039,7 @@ namespace spades {
handle.GetHeight(), false),
false);
SetColorAlphaPremultiplied(MakeVector4(1, 1, 1, 1));
DrawImage(image,
DrawImage(*image,
AABB2(0, handle.GetHeight(), handle.GetWidth(), -handle.GetHeight()));
imageRenderer->Flush();
}
@ -1115,7 +1109,8 @@ namespace spades {
IGLDevice::Zero, IGLDevice::One);
}
void GLRenderer::DrawImage(client::IImage *image, const spades::Vector2 &outTopLeft) {
void GLRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::Vector2 &outTopLeft) {
SPADES_MARK_FUNCTION();
if (image == nullptr) {
@ -1127,15 +1122,16 @@ namespace spades {
AABB2(0, 0, image->GetWidth(), image->GetHeight()));
}
void GLRenderer::DrawImage(client::IImage *image, const spades::AABB2 &outRect) {
void GLRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::AABB2 &outRect) {
SPADES_MARK_FUNCTION();
DrawImage(image, outRect,
AABB2(0, 0, image ? image->GetWidth() : 0, image ? image->GetHeight() : 0));
}
void GLRenderer::DrawImage(client::IImage *image, const spades::Vector2 &outTopLeft,
const spades::AABB2 &inRect) {
void GLRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::Vector2 &outTopLeft, const spades::AABB2 &inRect) {
SPADES_MARK_FUNCTION();
DrawImage(image,
@ -1143,8 +1139,8 @@ namespace spades {
inRect);
}
void GLRenderer::DrawImage(client::IImage *image, const spades::AABB2 &outRect,
const spades::AABB2 &inRect) {
void GLRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::AABB2 &outRect, const spades::AABB2 &inRect) {
SPADES_MARK_FUNCTION();
DrawImage(image, Vector2::Make(outRect.GetMinX(), outRect.GetMinY()),
@ -1152,7 +1148,8 @@ namespace spades {
Vector2::Make(outRect.GetMinX(), outRect.GetMaxY()), inRect);
}
void GLRenderer::DrawImage(client::IImage *image, const spades::Vector2 &outTopLeft,
void GLRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::Vector2 &outTopLeft,
const spades::Vector2 &outTopRight,
const spades::Vector2 &outBottomLeft,
const spades::AABB2 &inRect) {
@ -1163,7 +1160,7 @@ namespace spades {
// d = a + (b - a) + (c - a)
// = b + c - a
Vector2 outBottomRight = outTopRight + outBottomLeft - outTopLeft;
GLImage *img = dynamic_cast<GLImage *>(image);
GLImage *img = dynamic_cast<GLImage *>(image.get_pointer());
if (!img) {
if (!image) {
img = imageManager->GetWhiteImage();
@ -1237,7 +1234,7 @@ namespace spades {
Handle<GLImage> image(new GLImage(lastColorBufferTexture, device, w, h, false),
false);
SetColorAlphaPremultiplied(MakeVector4(1, 1, 1, 1));
DrawImage(image, AABB2(0, h, w, -h));
DrawImage(*image, AABB2(0, h, w, -h));
imageRenderer->Flush(); // must flush now because handle is released soon
}
@ -1259,11 +1256,10 @@ namespace spades {
device->Swap();
}
Bitmap *GLRenderer::ReadBitmap() {
Handle<Bitmap> GLRenderer::ReadBitmap() {
SPADES_MARK_FUNCTION();
Bitmap *bmp;
EnsureSceneNotStarted();
bmp = new Bitmap(device->ScreenWidth(), device->ScreenHeight());
auto bmp = Handle<Bitmap>::New(device->ScreenWidth(), device->ScreenHeight());
device->ReadPixels(0, 0, device->ScreenWidth(), device->ScreenHeight(), IGLDevice::RGBA,
IGLDevice::UnsignedByte, bmp->GetPixels());
return bmp;

View File

@ -70,7 +70,7 @@ namespace spades {
Handle<IGLDevice> device;
GLFramebufferManager *fbManager;
client::GameMap *map;
client::GameMap *map; // TODO: get rid of raw pointers
GLSettings settings;
std::unique_ptr<GLProfiler> profiler;
@ -88,6 +88,7 @@ namespace spades {
GLImageManager *imageManager;
GLModelManager *modelManager;
// TODO: get rid of these abominations called raw pointers
IGLShadowMapRenderer *shadowMapRenderer;
GLMapShadowRenderer *mapShadowRenderer;
GLMapRenderer *mapRenderer;
@ -150,19 +151,19 @@ namespace spades {
void Init() override;
void Shutdown() override;
client::IImage *RegisterImage(const char *filename) override;
client::IModel *RegisterModel(const char *filename) override;
Handle<client::IImage> RegisterImage(const char *filename) override;
Handle<client::IModel> RegisterModel(const char *filename) override;
void ClearCache() override;
client::IImage *CreateImage(Bitmap *) override;
client::IModel *CreateModel(VoxelModel *) override;
client::IModel *CreateModelOptimized(VoxelModel *);
Handle<client::IImage> CreateImage(Bitmap &) override;
Handle<client::IModel> CreateModel(VoxelModel &) override;
Handle<client::IModel> CreateModelOptimized(VoxelModel &);
GLProgram *RegisterProgram(const std::string &name);
GLShader *RegisterShader(const std::string &name);
void SetGameMap(client::GameMap *) override;
void SetGameMap(stmp::optional<client::GameMap &>) override;
void SetFogColor(Vector3 v) override;
void SetFogDistance(float f) override { fogDistance = f; }
@ -172,14 +173,14 @@ namespace spades {
void StartScene(const client::SceneDefinition &) override;
void RenderModel(client::IModel *, const client::ModelRenderParam &) override;
void RenderModel(client::IModel &, const client::ModelRenderParam &) override;
void AddLight(const client::DynamicLightParam &light) override;
void AddDebugLine(Vector3 a, Vector3 b, Vector4 color) override;
void AddSprite(client::IImage *, Vector3 center, float radius, float rotation) override;
void AddLongSprite(client::IImage *, Vector3 p1, Vector3 p2, float radius) override;
void AddSprite(client::IImage &, Vector3 center, float radius, float rotation) override;
void AddLongSprite(client::IImage &, Vector3 p1, Vector3 p2, float radius) override;
void EndScene() override;
@ -188,19 +189,21 @@ namespace spades {
void SetColor(Vector4) override;
void SetColorAlphaPremultiplied(Vector4) override;
void DrawImage(client::IImage *, const Vector2 &outTopLeft) override;
void DrawImage(client::IImage *, const AABB2 &outRect) override;
void DrawImage(client::IImage *, const Vector2 &outTopLeft,
void DrawImage(stmp::optional<client::IImage &>, const Vector2 &outTopLeft) override;
void DrawImage(stmp::optional<client::IImage &>, const AABB2 &outRect) override;
void DrawImage(stmp::optional<client::IImage &>, const Vector2 &outTopLeft,
const AABB2 &inRect) override;
void DrawImage(stmp::optional<client::IImage &>, const AABB2 &outRect,
const AABB2 &inRect) override;
void DrawImage(stmp::optional<client::IImage &>, const Vector2 &outTopLeft,
const Vector2 &outTopRight, const Vector2 &outBottomLeft,
const AABB2 &inRect) override;
void DrawImage(client::IImage *, const AABB2 &outRect, const AABB2 &inRect) override;
void DrawImage(client::IImage *, const Vector2 &outTopLeft, const Vector2 &outTopRight,
const Vector2 &outBottomLeft, const AABB2 &inRect) override;
void DrawFlatGameMap(const AABB2 &outRect, const AABB2 &inRect) override;
void FrameDone() override;
void Flip() override;
Bitmap *ReadBitmap() override;
Handle<Bitmap> ReadBitmap() override;
float ScreenWidth() override;
float ScreenHeight() override;
@ -228,5 +231,5 @@ namespace spades {
bool BoxFrustrumCull(const AABB3 &);
bool SphereFrustrumCull(const Vector3 &center, float radius);
};
}
}
} // namespace draw
} // namespace spades

View File

@ -42,7 +42,7 @@ namespace spades {
bilateralProgram =
renderer->RegisterProgram("Shaders/PostFilters/BilateralFilter.program");
ditherPattern = static_cast<GLImage *>(renderer->RegisterImage("Gfx/DitherPattern4x4.png"));
ditherPattern = renderer->RegisterImage("Gfx/DitherPattern4x4.png").Cast<GLImage>();
}
GLColorBuffer GLSSAOFilter::GenerateRawSSAOImage(int width, int height) {

View File

@ -34,7 +34,7 @@ namespace spades {
GLProgram *ssaoProgram;
GLProgram *bilateralProgram;
GLImage *ditherPattern;
Handle<GLImage> ditherPattern;
GLColorBuffer GenerateRawSSAOImage(int width, int height);
GLColorBuffer ApplyBilateralFilter(GLColorBuffer, bool direction, int width = -1,

View File

@ -131,7 +131,7 @@ namespace spades {
dev->BindTexture(IGLDevice::Texture2D, renderer->mapShadowRenderer->GetTexture());
} else {
// TODO: do this case properly
GLImage *img = (GLImage *)renderer->RegisterImage("Gfx/White.tga");
auto img = renderer->RegisterImage("Gfx/White.tga").Cast<GLImage>();
img->Bind(IGLDevice::Texture2D);
}
mapShadowTexture.SetValue(texStage);

View File

@ -47,7 +47,7 @@ namespace spades {
program = renderer->RegisterProgram("Shaders/VoxelModel.program");
dlightProgram = renderer->RegisterProgram("Shaders/VoxelModelDynamicLit.program");
shadowMapProgram = renderer->RegisterProgram("Shaders/VoxelModelShadowMap.program");
aoImage = (GLImage *)renderer->RegisterImage("Gfx/AmbientOcclusion.png");
aoImage = renderer->RegisterImage("Gfx/AmbientOcclusion.png").Cast<GLImage>();
BuildVertices(m);

View File

@ -52,7 +52,7 @@ namespace spades {
GLProgram *program;
GLProgram *dlightProgram;
GLProgram *shadowMapProgram;
GLImage *aoImage;
Handle<GLImage> aoImage;
IGLDevice::UInteger buffer;
IGLDevice::UInteger idxBuffer;

View File

@ -30,8 +30,8 @@
namespace spades {
namespace draw {
SWFlatMapRenderer::SWFlatMapRenderer(SWRenderer *r, client::GameMap *map)
: r(r), map(map), w(map->Width()), h(map->Height()), needsUpdate(true) {
SWFlatMapRenderer::SWFlatMapRenderer(SWRenderer *r, Handle<client::GameMap> inMap)
: r(r), map(std::move(inMap)), w(map->Width()), h(map->Height()), needsUpdate(true) {
SPADES_MARK_FUNCTION();
if (w & 31) {

View File

@ -46,7 +46,7 @@ namespace spades {
uint32_t GeneratePixel(int x, int y);
public:
SWFlatMapRenderer(SWRenderer *r, client::GameMap *);
SWFlatMapRenderer(SWRenderer *r, Handle<client::GameMap>);
~SWFlatMapRenderer();
SWImage *GetImage() {

View File

@ -42,19 +42,19 @@ namespace spades {
}
}
SWImage::SWImage(Bitmap *m)
: ew(m->GetWidth()),
eh(m->GetHeight()),
SWImage::SWImage(Bitmap &m)
: ew(m.GetWidth()),
eh(m.GetHeight()),
isWhite(false),
w(static_cast<float>(m->GetWidth())),
h(static_cast<float>(m->GetHeight())),
w(static_cast<float>(m.GetWidth())),
h(static_cast<float>(m.GetHeight())),
iw(1.f / w),
ih(1.f / h) {
bmp.resize(ew * eh);
// premultiplied alpha
{
uint32_t *inpix = m->GetPixels();
uint32_t *inpix = m.GetPixels();
uint32_t *outpix = bmp.data();
bool foundNonWhite = false;
for (std::size_t i = ew * eh; i; i--) {
@ -106,27 +106,24 @@ namespace spades {
}
SWImageManager::~SWImageManager() {
for (auto it = images.begin(); it != images.end(); it++)
it->second->Release();
}
SWImage *SWImageManager::RegisterImage(const std::string &name) {
Handle<SWImage> SWImageManager::RegisterImage(const std::string &name) {
auto it = images.find(name);
if (it == images.end()) {
Handle<Bitmap> vm;
vm.Set(Bitmap::Load(name), false);
auto *m = CreateImage(vm);
images.insert(std::make_pair(name, m));
m->AddRef();
return m;
} else {
auto *image = it->second;
image->AddRef();
Handle<Bitmap> bitmap;
bitmap.Set(Bitmap::Load(name), false);
Handle<SWImage> image = CreateImage(*bitmap);
images.insert(std::make_pair(name, image));
return image;
} else {
return it->second;
}
}
SWImage *SWImageManager::CreateImage(Bitmap *vm) { return new SWImage(vm); }
Handle<SWImage> SWImageManager::CreateImage(Bitmap &bitmap) {
return Handle<SWImage>::New(bitmap);
}
void SWImageManager::ClearCache() {
images.clear();

View File

@ -42,7 +42,7 @@ namespace spades {
~SWImage();
public:
SWImage(Bitmap *bmp);
SWImage(Bitmap &bmp);
SWImage(int w, int h);
uint32_t *GetRawBitmap() { return bmp.data(); }
@ -60,14 +60,14 @@ namespace spades {
};
class SWImageManager {
std::unordered_map<std::string, SWImage *> images;
std::unordered_map<std::string, Handle<SWImage>> images;
public:
SWImageManager() {}
~SWImageManager();
SWImage *RegisterImage(const std::string &);
SWImage *CreateImage(Bitmap *);
Handle<SWImage> RegisterImage(const std::string &);
Handle<SWImage> CreateImage(Bitmap &);
void ClearCache();
};

View File

@ -25,27 +25,27 @@
namespace spades {
namespace draw {
SWModel::SWModel(VoxelModel *m) : rawModel(m) {
center.x = m->GetWidth();
center.y = m->GetHeight();
center.z = m->GetDepth();
SWModel::SWModel(VoxelModel &m) : rawModel(m) {
center.x = m.GetWidth();
center.y = m.GetHeight();
center.z = m.GetDepth();
center *= 0.5f;
radius = center.GetLength();
int w = m->GetWidth();
int h = m->GetHeight();
int d = m->GetDepth();
int w = m.GetWidth();
int h = m.GetHeight();
int d = m.GetDepth();
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
renderDataAddr.push_back(static_cast<uint32_t>(renderData.size()));
uint64_t map = m->GetSolidBitsAt(x, y);
uint64_t map1 = x > 0 ? m->GetSolidBitsAt(x - 1, y) : 0;
uint64_t map2 = x < (w - 1) ? m->GetSolidBitsAt(x + 1, y) : 0;
uint64_t map3 = y > 0 ? m->GetSolidBitsAt(x, y - 1) : 0;
uint64_t map4 = y < (h - 1) ? m->GetSolidBitsAt(x, y + 1) : 0;
uint64_t map = m.GetSolidBitsAt(x, y);
uint64_t map1 = x > 0 ? m.GetSolidBitsAt(x - 1, y) : 0;
uint64_t map2 = x < (w - 1) ? m.GetSolidBitsAt(x + 1, y) : 0;
uint64_t map3 = y > 0 ? m.GetSolidBitsAt(x, y - 1) : 0;
uint64_t map4 = y < (h - 1) ? m.GetSolidBitsAt(x, y + 1) : 0;
map1 &= map2;
map1 &= map3;
map1 &= map4;
@ -55,7 +55,7 @@ namespace spades {
continue;
if (z == 0 || z == (d - 1) || ((map >> (z - 1)) & 7ULL) != 7ULL ||
(map1 & (1ULL << z)) == 0) {
uint32_t col = m->GetColor(x, y, z);
uint32_t col = m.GetColor(x, y, z);
uint32_t encodedColor;
encodedColor =
@ -75,7 +75,7 @@ namespace spades {
for (int cx = -1; cx <= 1; cx++)
for (int cy = -1; cy <= 1; cy++)
for (int cz = -1; cz <= 1; cz++) {
if (m->IsSolid(x + cx, y + cy, z + cz)) {
if (m.IsSolid(x + cx, y + cy, z + cz)) {
nx -= cx;
ny -= cy;
nz -= cz;
@ -124,29 +124,27 @@ namespace spades {
}
SWModelManager::~SWModelManager() {
for (auto it = models.begin(); it != models.end(); it++)
it->second->Release();
}
SWModel *SWModelManager::RegisterModel(const std::string &name) {
Handle<SWModel> SWModelManager::RegisterModel(const std::string &name) {
auto it = models.find(name);
if (it == models.end()) {
Handle<VoxelModel> vm;
vm.Set(VoxelModelLoader::Load(name.c_str()), false);
SWModel *model = CreateModel(vm);
Handle<SWModel> model = CreateModel(*vm);
models.insert(std::make_pair(name, model));
model->AddRef();
return model;
} else {
SWModel *model = it->second;
model->AddRef();
return model;
return it->second;
}
}
SWModel *SWModelManager::CreateModel(spades::VoxelModel *vm) { return new SWModel(vm); }
Handle<SWModel> SWModelManager::CreateModel(spades::VoxelModel &vm) {
return Handle<SWModel>::New(vm);
}
void SWModelManager::ClearCache() {
models.clear();

View File

@ -44,7 +44,7 @@ namespace spades {
~SWModel();
public:
SWModel(VoxelModel *model);
SWModel(VoxelModel &model);
float GetRadius() { return radius; }
Vector3 GetCenter() { return center; }
@ -54,16 +54,16 @@ namespace spades {
};
class SWModelManager {
std::unordered_map<std::string, SWModel *> models;
std::unordered_map<std::string, Handle<SWModel>> models;
public:
SWModelManager() {}
~SWModelManager();
SWModel *RegisterModel(const std::string &);
SWModel *CreateModel(VoxelModel *);
Handle<SWModel> RegisterModel(const std::string &);
Handle<SWModel> CreateModel(VoxelModel &);
void ClearCache();
};
}
}
} // namespace draw
} // namespace spades

View File

@ -140,16 +140,16 @@ namespace spades {
inited = false;
}
client::IImage *SWRenderer::RegisterImage(const char *filename) {
Handle<client::IImage> SWRenderer::RegisterImage(const char *filename) {
SPADES_MARK_FUNCTION();
EnsureValid();
return imageManager->RegisterImage(filename);
return imageManager->RegisterImage(filename).Cast<client::IImage>();
}
client::IModel *SWRenderer::RegisterModel(const char *filename) {
Handle<client::IModel> SWRenderer::RegisterModel(const char *filename) {
SPADES_MARK_FUNCTION();
EnsureInitialized();
return modelManager->RegisterModel(filename);
return modelManager->RegisterModel(filename).Cast<client::IModel>();
}
void SWRenderer::ClearCache() {
@ -159,23 +159,23 @@ namespace spades {
modelManager->ClearCache();
}
client::IImage *SWRenderer::CreateImage(spades::Bitmap *bmp) {
Handle<client::IImage> SWRenderer::CreateImage(spades::Bitmap &bmp) {
SPADES_MARK_FUNCTION();
EnsureValid();
return imageManager->CreateImage(bmp);
return imageManager->CreateImage(bmp).Cast<client::IImage>();
}
client::IModel *SWRenderer::CreateModel(spades::VoxelModel *model) {
Handle<client::IModel> SWRenderer::CreateModel(spades::VoxelModel &model) {
SPADES_MARK_FUNCTION();
EnsureInitialized();
return modelManager->CreateModel(model);
return modelManager->CreateModel(model).Cast<client::IModel>();
}
void SWRenderer::SetGameMap(client::GameMap *map) {
void SWRenderer::SetGameMap(stmp::optional<client::GameMap &> map) {
SPADES_MARK_FUNCTION();
if (map)
EnsureInitialized();
if (map == this->map)
if (map.get_pointer() == this->map)
return;
flatMapRenderer.reset();
@ -187,7 +187,7 @@ namespace spades {
if (this->map) {
this->map->AddListener(this);
flatMapRenderer = std::make_shared<SWFlatMapRenderer>(this, map);
mapRenderer = std::make_shared<SWMapRenderer>(this, map, featureLevel);
mapRenderer = std::make_shared<SWMapRenderer>(this, map.get_pointer(), featureLevel);
}
}
@ -601,17 +601,15 @@ namespace spades {
projectionViewMatrix = projectionMatrix * viewMatrix;
}
void SWRenderer::RenderModel(client::IModel *model, const client::ModelRenderParam &param) {
void SWRenderer::RenderModel(client::IModel &model, const client::ModelRenderParam &param) {
SPADES_MARK_FUNCTION();
EnsureInitialized();
EnsureSceneStarted();
auto *mdl = dynamic_cast<SWModel *>(model);
if (mdl == nullptr)
SPInvalidArgument("model");
SWModel &swModel = dynamic_cast<SWModel &>(model);
Model m;
m.model = mdl;
m.model = swModel;
m.param = param;
models.push_back(m);
@ -705,7 +703,7 @@ namespace spades {
debugLines.push_back(l);
}
void SWRenderer::AddSprite(client::IImage *image, spades::Vector3 center, float radius,
void SWRenderer::AddSprite(client::IImage &image, spades::Vector3 center, float radius,
float rotation) {
SPADES_MARK_FUNCTION();
EnsureInitialized();
@ -714,22 +712,19 @@ namespace spades {
if (!SphereFrustrumCull(center, radius * 1.5f))
return;
SWImage *img = dynamic_cast<SWImage *>(image);
if (!img) {
SPInvalidArgument("image");
}
SWImage &swImage = dynamic_cast<SWImage &>(image);
sprites.push_back(Sprite());
auto &spr = sprites.back();
spr.img = img;
spr.img = swImage;
spr.center = center;
spr.radius = radius;
spr.rotation = rotation;
spr.color = drawColorAlphaPremultiplied;
}
void SWRenderer::AddLongSprite(client::IImage *, spades::Vector3 p1, spades::Vector3 p2,
void SWRenderer::AddLongSprite(client::IImage &, spades::Vector3 p1, spades::Vector3 p2,
float radius) {
SPADES_MARK_FUNCTION();
EnsureInitialized();
@ -975,7 +970,8 @@ namespace spades {
drawColorAlphaPremultiplied = col;
}
void SWRenderer::DrawImage(client::IImage *image, const spades::Vector2 &outTopLeft) {
void SWRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::Vector2 &outTopLeft) {
SPADES_MARK_FUNCTION();
if (image == nullptr) {
@ -987,15 +983,16 @@ namespace spades {
AABB2(0, 0, image->GetWidth(), image->GetHeight()));
}
void SWRenderer::DrawImage(client::IImage *image, const spades::AABB2 &outRect) {
void SWRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::AABB2 &outRect) {
SPADES_MARK_FUNCTION();
DrawImage(image, outRect,
AABB2(0, 0, image ? image->GetWidth() : 0, image ? image->GetHeight() : 0));
}
void SWRenderer::DrawImage(client::IImage *image, const spades::Vector2 &outTopLeft,
const spades::AABB2 &inRect) {
void SWRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::Vector2 &outTopLeft, const spades::AABB2 &inRect) {
SPADES_MARK_FUNCTION();
DrawImage(image,
@ -1003,8 +1000,8 @@ namespace spades {
inRect);
}
void SWRenderer::DrawImage(client::IImage *image, const spades::AABB2 &outRect,
const spades::AABB2 &inRect) {
void SWRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::AABB2 &outRect, const spades::AABB2 &inRect) {
SPADES_MARK_FUNCTION();
DrawImage(image, Vector2::Make(outRect.GetMinX(), outRect.GetMinY()),
@ -1012,7 +1009,8 @@ namespace spades {
Vector2::Make(outRect.GetMinX(), outRect.GetMaxY()), inRect);
}
void SWRenderer::DrawImage(client::IImage *image, const spades::Vector2 &outTopLeft,
void SWRenderer::DrawImage(stmp::optional<client::IImage &> image,
const spades::Vector2 &outTopLeft,
const spades::Vector2 &outTopRight,
const spades::Vector2 &outBottomLeft,
const spades::AABB2 &inRect) {
@ -1025,7 +1023,7 @@ namespace spades {
// = b + c - a
Vector2 outBottomRight = outTopRight + outBottomLeft - outTopLeft;
SWImage *img = dynamic_cast<SWImage *>(image);
SWImage *img = dynamic_cast<SWImage *>(image.get_pointer());
if (img == nullptr && image != nullptr) {
// not SWImage
SPInvalidArgument("image");
@ -1116,7 +1114,7 @@ namespace spades {
SetFramebuffer(port->GetFramebuffer());
}
Bitmap *SWRenderer::ReadBitmap() {
Handle<Bitmap> SWRenderer::ReadBitmap() {
SPADES_MARK_FUNCTION();
EnsureValid();
EnsureSceneNotStarted();
@ -1124,7 +1122,7 @@ namespace spades {
int w = fb->GetWidth();
int h = fb->GetHeight();
uint32_t *inPix = fb->GetPixels();
Bitmap *bm = new Bitmap(w, h);
auto bm = Handle<Bitmap>::New(w, h);
uint32_t *outPix = bm->GetPixels();
for (int y = 0; y < h; y++) {
uint32_t *src = inPix + y * w;

View File

@ -154,15 +154,15 @@ namespace spades {
void Init() override;
void Shutdown() override;
client::IImage *RegisterImage(const char *filename) override;
client::IModel *RegisterModel(const char *filename) override;
Handle<client::IImage> RegisterImage(const char *filename) override;
Handle<client::IModel> RegisterModel(const char *filename) override;
client::IImage *CreateImage(Bitmap *) override;
client::IModel *CreateModel(VoxelModel *) override;
Handle<client::IImage> CreateImage(Bitmap &) override;
Handle<client::IModel> CreateModel(VoxelModel &) override;
void ClearCache() override;
void SetGameMap(client::GameMap *) override;
void SetGameMap(stmp::optional<client::GameMap &>) override;
void SetFogColor(Vector3 v) override;
void SetFogDistance(float f) override { fogDistance = f; }
@ -171,14 +171,14 @@ namespace spades {
void StartScene(const client::SceneDefinition &) override;
void RenderModel(client::IModel *, const client::ModelRenderParam &) override;
void RenderModel(client::IModel &, const client::ModelRenderParam &) override;
void AddLight(const client::DynamicLightParam &light) override;
void AddDebugLine(Vector3 a, Vector3 b, Vector4 color) override;
void AddSprite(client::IImage *, Vector3 center, float radius, float rotation) override;
void AddLongSprite(client::IImage *, Vector3 p1, Vector3 p2, float radius) override;
void AddSprite(client::IImage &, Vector3 center, float radius, float rotation) override;
void AddLongSprite(client::IImage &, Vector3 p1, Vector3 p2, float radius) override;
void EndScene() override;
@ -187,19 +187,21 @@ namespace spades {
void SetColor(Vector4) override;
void SetColorAlphaPremultiplied(Vector4) override;
void DrawImage(client::IImage *, const Vector2 &outTopLeft) override;
void DrawImage(client::IImage *, const AABB2 &outRect) override;
void DrawImage(client::IImage *, const Vector2 &outTopLeft,
void DrawImage(stmp::optional<client::IImage &>, const Vector2 &outTopLeft) override;
void DrawImage(stmp::optional<client::IImage &>, const AABB2 &outRect) override;
void DrawImage(stmp::optional<client::IImage &>, const Vector2 &outTopLeft,
const AABB2 &inRect) override;
void DrawImage(stmp::optional<client::IImage &>, const AABB2 &outRect,
const AABB2 &inRect) override;
void DrawImage(stmp::optional<client::IImage &>, const Vector2 &outTopLeft,
const Vector2 &outTopRight, const Vector2 &outBottomLeft,
const AABB2 &inRect) override;
void DrawImage(client::IImage *, const AABB2 &outRect, const AABB2 &inRect) override;
void DrawImage(client::IImage *, const Vector2 &outTopLeft, const Vector2 &outTopRight,
const Vector2 &outBottomLeft, const AABB2 &inRect) override;
void DrawFlatGameMap(const AABB2 &outRect, const AABB2 &inRect) override;
void FrameDone() override;
void Flip() override;
Bitmap *ReadBitmap() override;
Handle<Bitmap> ReadBitmap() override;
float ScreenWidth() override;
float ScreenHeight() override;

View File

@ -1,55 +1,90 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades 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.
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptManager.h"
#include <Client/IRenderer.h>
#include <Client/SceneDefinition.h>
#include <Core/Bitmap.h>
namespace spades {
namespace client{
class RendererRegistrar: public ScriptObjectRegistrar {
static IModel *RegisterModel(const std::string& str,
IRenderer *r) {
try{
IModel *m = r->RegisterModel(str.c_str());
m->AddRef();
return m;
}catch(const std::exception& ex) {
static void SetGameMap(GameMap *gameMap, IRenderer *r) {
try {
r->SetGameMap(gameMap);
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
return NULL;
}
}
static IImage *RegisterImage(const std::string& str,
IRenderer *r) {
try{
IImage *im = r->RegisterImage(str.c_str());
im->AddRef();
return im;
}catch(const std::exception& ex) {
static IModel *RegisterModel(const std::string &str, IRenderer *r) {
try {
return r->RegisterModel(str.c_str()).Unmanage();
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
return {};
}
}
static IImage *RegisterImage(const std::string &str, IRenderer *r) {
try {
return r->RegisterImage(str.c_str()).Unmanage();
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
return nullptr;
}
}
static IImage *CreateImage(Bitmap *bitmap, IRenderer *r) {
try {
if (!bitmap) {
SPInvalidArgument("bitmap");
}
return r->CreateImage(*bitmap).Unmanage();
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
return nullptr;
}
}
static IModel *CreateModel(VoxelModel *model, IRenderer *r) {
try {
if (!model) {
SPInvalidArgument("model");
}
return r->CreateModel(*model).Unmanage();
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
return nullptr;
}
}
static void RenderModel(IModel *model, const ModelRenderParam &param,
IRenderer *r) {
try {
if (!model) {
SPInvalidArgument("model");
}
return r->RenderModel(*model, param);
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void AddDebugLine(const Vector3& a, const Vector3& b,
const Vector4& color,
IRenderer *r) {
@ -63,7 +98,10 @@ namespace spades {
float rad, float rot,
IRenderer *r) {
try{
return r->AddSprite(img, center, rad, rot);
if (!img) {
SPInvalidArgument("img");
}
return r->AddSprite(*img, center, rad, rot);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
@ -71,10 +109,13 @@ namespace spades {
static void AddLongSprite(IImage *img,
const Vector3& p1,
const Vector3& p2,
float rad,
float rad,
IRenderer *r) {
try{
return r->AddLongSprite(img, p1, p2, rad);
if (!img) {
SPInvalidArgument("img");
}
return r->AddLongSprite(*img, p1, p2, rad);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
@ -120,7 +161,6 @@ namespace spades {
ScriptContextUtils().SetNativeException(ex);
}
}
static void SetFogColor(const Vector3& v,
IRenderer *r){
try{
@ -129,6 +169,53 @@ namespace spades {
ScriptContextUtils().SetNativeException(ex);
}
}
static void DrawImage1(IImage *image, const Vector2 &outTopLeft, IRenderer *self) {
try {
return self->DrawImage(image, outTopLeft);
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void DrawImage2(IImage *image, const AABB2 &outRect, IRenderer *self) {
try {
return self->DrawImage(image, outRect);
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void DrawImage3(IImage *image, const Vector2 &outTopLeft, const AABB2 &inRect,
IRenderer *self) {
try {
return self->DrawImage(image, outTopLeft, inRect);
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void DrawImage4(IImage *image, const AABB2 &outRect, const AABB2 &inRect,
IRenderer *self) {
try {
return self->DrawImage(image, outRect, inRect);
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void DrawImage5(IImage *image, const Vector2 &outTopLeft,
const Vector2 &outTopRight, const Vector2 &outBottomLeft,
const AABB2 &inRect, IRenderer *self) {
try {
return self->DrawImage(image, outTopLeft, outTopRight, outBottomLeft, inRect);
} catch (const std::exception &ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static Bitmap *ReadBitmap(IRenderer *r){
try{
return r->ReadBitmap().Unmanage();
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
return nullptr;
}
}
static void ModelRenderParamFactory(ModelRenderParam *p) {
new(p) ModelRenderParam();
}
@ -157,7 +244,7 @@ namespace spades {
public:
RendererRegistrar():
ScriptObjectRegistrar("Renderer"){
}
virtual void Register(ScriptManager *manager, Phase phase) {
asIScriptEngine *eng = manager->GetEngine();
@ -178,8 +265,8 @@ namespace spades {
asMETHOD(IRenderer, Release),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectType("ModelRenderParam",
sizeof(ModelRenderParam), asOBJ_VALUE|asOBJ_POD|asOBJ_APP_CLASS_CDAK);
manager->CheckError(r);
@ -191,8 +278,8 @@ namespace spades {
manager->CheckError(r);
r = eng->RegisterEnum("DynamicLightType");
manager->CheckError(r);
break;
case PhaseObjectMember:
r = eng->RegisterEnumValue("DynamicLightType", "Point",
@ -201,7 +288,7 @@ namespace spades {
r = eng->RegisterEnumValue("DynamicLightType", "Spotlight",
DynamicLightTypeSpotlight);
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("ModelRenderParam",
asBEHAVE_CONSTRUCT,
"void f()",
@ -288,7 +375,7 @@ namespace spades {
"bool useLensFlare",
asOFFSET(DynamicLightParam, useLensFlare));
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("SceneDefinition",
asBEHAVE_CONSTRUCT,
"void f()",
@ -371,19 +458,19 @@ namespace spades {
"float globalBlur",
asOFFSET(SceneDefinition, globalBlur));
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void Init()",
asMETHOD(IRenderer, Init),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void Shutdown()",
asMETHOD(IRenderer, Shutdown),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"Image@ RegisterImage(const string& in)",
asFUNCTION(RegisterImage),
@ -405,18 +492,18 @@ namespace spades {
// (https://github.com/yvt/openspades/issues/687).
r = eng->RegisterObjectMethod("Renderer",
"Image@ CreateImage(Bitmap@+)",
asMETHOD(IRenderer, CreateImage),
asCALL_THISCALL);
asFUNCTION(CreateImage),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"Model@ CreateModel(VoxelModel@+)",
asMETHOD(IRenderer, CreateModel),
asCALL_THISCALL);
asFUNCTION(CreateModel),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_GameMap(GameMap@+)",
asMETHOD(IRenderer, SetGameMap),
asCALL_THISCALL);
asFUNCTION(SetGameMap),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_FogDistance(float)",
@ -440,8 +527,8 @@ namespace spades {
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void AddModel(Model@+, const ModelRenderParam& in)",
asMETHOD(IRenderer, RenderModel),
asCALL_THISCALL);
asFUNCTION(RenderModel),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void AddDebugLine(const Vector3&in, const Vector3&in, const Vector4&in)",
@ -490,38 +577,28 @@ namespace spades {
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawImage(Image@+, const Vector2& in)",
asMETHODPR(IRenderer, DrawImage,
(IImage*, const Vector2&),
void),
asCALL_THISCALL);
asFUNCTION(DrawImage1),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawImage(Image@+, const AABB2& in)",
asMETHODPR(IRenderer, DrawImage,
(IImage*, const AABB2&),
void),
asCALL_THISCALL);
asFUNCTION(DrawImage2),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawImage(Image@+, const Vector2&in, const AABB2& in)",
asMETHODPR(IRenderer, DrawImage,
(IImage*, const Vector2&, const AABB2&),
void),
asCALL_THISCALL);
asFUNCTION(DrawImage3),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawImage(Image@+, const AABB2&in, const AABB2& in)",
asMETHODPR(IRenderer, DrawImage,
(IImage*, const AABB2&, const AABB2&),
void),
asCALL_THISCALL);
asFUNCTION(DrawImage4),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawImage(Image@+, const Vector2&in, const Vector2&in, const Vector2&in, const AABB2& in)",
asMETHODPR(IRenderer, DrawImage,
(IImage*, const Vector2&, const Vector2&, const Vector2&, const AABB2&),
void),
asCALL_THISCALL);
asFUNCTION(DrawImage5),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawFlatGameMap(const AABB2&in, const AABB2& in)",
@ -540,8 +617,8 @@ namespace spades {
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"Bitmap@ ReadBitmap()",
asMETHOD(IRenderer,ReadBitmap),
asCALL_THISCALL);
asFUNCTION(ReadBitmap),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"float get_ScreenWidth()",
@ -559,7 +636,7 @@ namespace spades {
}
}
};
static RendererRegistrar registrar;
}
}