/*
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 .
*/
#include "ScriptManager.h"
#include
#include
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) {
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) {
ScriptContextUtils().SetNativeException(ex);
return nullptr;
}
}
static void AddDebugLine(const Vector3& a, const Vector3& b,
const Vector4& color,
IRenderer *r) {
try{
return r->AddDebugLine(a, b, color);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void AddSprite(IImage *img, const Vector3& center,
float rad, float rot,
IRenderer *r) {
try{
return r->AddSprite(img, center, rad, rot);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void AddLongSprite(IImage *img,
const Vector3& p1,
const Vector3& p2,
float rad,
IRenderer *r) {
try{
return r->AddLongSprite(img, p1, p2, rad);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void MultiplyScreenColor(const Vector3& v,
IRenderer *r){
try{
return r->MultiplyScreenColor(v);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void SetColor(const Vector4& v,
IRenderer *r){
try{
return r->SetColor(v);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void SetColorOpaque(const Vector3& v,
IRenderer *r){
try{
return r->SetColorAlphaPremultiplied(MakeVector4(v.x,v.y,v.z,1.f));
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void SetColorAlphaPremultiplied(const Vector4& v,
IRenderer *r){
try{
return r->SetColorAlphaPremultiplied(v);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void SetColorAlphaNonPremultiplied(const Vector4& v,
IRenderer *r){
Vector4 v2 = {v.x * v.w, v.y * v.w, v.z * v.w, v.w};
try{
return r->SetColorAlphaPremultiplied(v2);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void SetFogColor(const Vector3& v,
IRenderer *r){
try{
return r->SetFogColor(v);
}catch(const std::exception& ex) {
ScriptContextUtils().SetNativeException(ex);
}
}
static void ModelRenderParamFactory(ModelRenderParam *p) {
new(p) ModelRenderParam();
}
static void DynamicLightParamFactory(DynamicLightParam *p) {
new(p) DynamicLightParam();
}
static void DynamicLightParamFactory2(const DynamicLightParam& other, DynamicLightParam *p) {
new(p) DynamicLightParam(other);
if(p->image)
p->image->AddRef();
}
static void DynamicLightParamAssign(const DynamicLightParam& other,
DynamicLightParam *self) {
IImage *old = self->image;
*self = other;
self->image->AddRef();
old->Release();
}
static void DynamicLightParamDestructor(DynamicLightParam *p) {
if(p->image)
p->image->Release();
}
static void SceneDefinitionFactory(SceneDefinition *def) {
new(def) SceneDefinition();
}
public:
RendererRegistrar():
ScriptObjectRegistrar("Renderer"){
}
virtual void Register(ScriptManager *manager, Phase phase) {
asIScriptEngine *eng = manager->GetEngine();
int r;
eng->SetDefaultNamespace("spades");
switch(phase){
case PhaseObjectType:
r = eng->RegisterObjectType("Renderer",
0, asOBJ_REF);
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("Renderer",
asBEHAVE_ADDREF, "void f()",
asMETHOD(IRenderer, AddRef),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("Renderer",
asBEHAVE_RELEASE, "void f()",
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);
r = eng->RegisterObjectType("DynamicLightParam",
sizeof(DynamicLightParam), asOBJ_VALUE|asOBJ_APP_CLASS_CDAK);
manager->CheckError(r);
r = eng->RegisterObjectType("SceneDefinition",
sizeof(SceneDefinition), asOBJ_VALUE|asOBJ_POD|asOBJ_APP_CLASS_CDAK);
manager->CheckError(r);
r = eng->RegisterEnum("DynamicLightType");
manager->CheckError(r);
break;
case PhaseObjectMember:
r = eng->RegisterEnumValue("DynamicLightType", "Point",
DynamicLightTypePoint);
manager->CheckError(r);
r = eng->RegisterEnumValue("DynamicLightType", "Spotlight",
DynamicLightTypeSpotlight);
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("ModelRenderParam",
asBEHAVE_CONSTRUCT,
"void f()",
asFUNCTION(ModelRenderParamFactory),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectProperty("ModelRenderParam",
"Matrix4 matrix",
asOFFSET(ModelRenderParam, matrix));
manager->CheckError(r);
r = eng->RegisterObjectProperty("ModelRenderParam",
"Vector3 customColor",
asOFFSET(ModelRenderParam, customColor));
manager->CheckError(r);
r = eng->RegisterObjectProperty("ModelRenderParam",
"bool depthHack",
asOFFSET(ModelRenderParam, depthHack));
manager->CheckError(r);
r = eng->RegisterObjectProperty("ModelRenderParam",
"bool castShadow",
asOFFSET(ModelRenderParam, castShadow));
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("DynamicLightParam",
asBEHAVE_CONSTRUCT,
"void f()",
asFUNCTION(DynamicLightParamFactory),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("DynamicLightParam",
asBEHAVE_CONSTRUCT,
"void f(const DynamicLightParam& in)",
asFUNCTION(DynamicLightParamFactory2),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("DynamicLightParam",
asBEHAVE_DESTRUCT,
"void f()",
asFUNCTION(DynamicLightParamDestructor),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("DynamicLightParam",
"void opAssign(const DynamicLightParam& in)",
asFUNCTION(DynamicLightParamAssign),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"DynamicLightType type",
asOFFSET(DynamicLightParam, type));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"Vector3 origin",
asOFFSET(DynamicLightParam, origin));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"float radius",
asOFFSET(DynamicLightParam, radius));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"Vector3 color",
asOFFSET(DynamicLightParam, color));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"Vector3 spotAxisX",
asOFFSET(DynamicLightParam, spotAxis[0]));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"Vector3 spotAxisY",
asOFFSET(DynamicLightParam, spotAxis[1]));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"Vector3 spotAxisZ",
asOFFSET(DynamicLightParam, spotAxis[2]));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"Image@ image",
asOFFSET(DynamicLightParam, image));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"float spotAngle",
asOFFSET(DynamicLightParam, spotAngle));
manager->CheckError(r);
r = eng->RegisterObjectProperty("DynamicLightParam",
"bool useLensFlare",
asOFFSET(DynamicLightParam, useLensFlare));
manager->CheckError(r);
r = eng->RegisterObjectBehaviour("SceneDefinition",
asBEHAVE_CONSTRUCT,
"void f()",
asFUNCTION(SceneDefinitionFactory),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"int viewportLeft",
asOFFSET(SceneDefinition, viewportLeft));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"int viewportTop",
asOFFSET(SceneDefinition, viewportTop));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"int viewportWidth",
asOFFSET(SceneDefinition, viewportWidth));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"int viewportHeight",
asOFFSET(SceneDefinition, viewportHeight));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"float fovX",
asOFFSET(SceneDefinition, fovX));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"float fovY",
asOFFSET(SceneDefinition, fovY));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"Vector3 viewOrigin",
asOFFSET(SceneDefinition, viewOrigin));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"Vector3 viewAxisX",
asOFFSET(SceneDefinition, viewAxis[0]));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"Vector3 viewAxisY",
asOFFSET(SceneDefinition, viewAxis[1]));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"Vector3 viewAxisZ",
asOFFSET(SceneDefinition, viewAxis[2]));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"float zNear",
asOFFSET(SceneDefinition, zNear));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"float zFar",
asOFFSET(SceneDefinition, zFar));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"bool skipWorld",
asOFFSET(SceneDefinition, skipWorld));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"float depthOfFieldFocalLength",
asOFFSET(SceneDefinition, depthOfFieldFocalLength));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"uint time",
asOFFSET(SceneDefinition, time));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"bool denyCameraBlur",
asOFFSET(SceneDefinition, denyCameraBlur));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"float blurVignette",
asOFFSET(SceneDefinition, blurVignette));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"float radialBlur",
asOFFSET(SceneDefinition, radialBlur));
manager->CheckError(r);
r = eng->RegisterObjectProperty("SceneDefinition",
"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),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"Model@ RegisterModel(const string& in)",
asFUNCTION(RegisterModel),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void ClearCache()",
asMETHOD(IRenderer, ClearCache),
asCALL_THISCALL);
manager->CheckError(r);
// OpenSpades' C++ functions increase the reference count of a passed object
// when storing it (just like the convention of Objective C), so we must
// use "auto handles" (`@+`). Otherwise, a memory leak would occur
// (https://github.com/yvt/openspades/issues/687).
r = eng->RegisterObjectMethod("Renderer",
"Image@ CreateImage(Bitmap@+)",
asMETHOD(IRenderer, CreateImage),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"Model@ CreateModel(VoxelModel@+)",
asMETHOD(IRenderer, CreateModel),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_GameMap(GameMap@+)",
asMETHOD(IRenderer, SetGameMap),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_FogDistance(float)",
asMETHOD(IRenderer, SetFogDistance),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_FogColor(const Vector3& in)",
asFUNCTION(SetFogColor),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void StartScene(const SceneDefinition& in)",
asMETHOD(IRenderer, StartScene),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void AddLight(const DynamicLightParam& in)",
asMETHOD(IRenderer, AddLight),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void AddModel(Model@+, const ModelRenderParam& in)",
asMETHOD(IRenderer, RenderModel),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void AddDebugLine(const Vector3&in, const Vector3&in, const Vector4&in)",
asFUNCTION(AddDebugLine),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void AddSprite(Image@+, const Vector3&in, float, float)",
asFUNCTION(AddSprite),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void AddLongSprite(Image@+, const Vector3& in, const Vector3& in, float)",
asFUNCTION(AddLongSprite),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void EndScene()",
asMETHOD(IRenderer, EndScene),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void MultiplyScreenColor(const Vector3& in)",
asFUNCTION(MultiplyScreenColor),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_Color(const Vector4&in)",
asFUNCTION(SetColor),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_ColorOpaque(const Vector3&in)",
asFUNCTION(SetColorOpaque),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_ColorP(const Vector4&in)",
asFUNCTION(SetColorAlphaPremultiplied),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void set_ColorNP(const Vector4&in)",
asFUNCTION(SetColorAlphaNonPremultiplied),
asCALL_CDECL_OBJLAST);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawImage(Image@+, const Vector2& in)",
asMETHODPR(IRenderer, DrawImage,
(IImage*, const Vector2&),
void),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawImage(Image@+, const AABB2& in)",
asMETHODPR(IRenderer, DrawImage,
(IImage*, const AABB2&),
void),
asCALL_THISCALL);
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);
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);
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);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void DrawFlatGameMap(const AABB2&in, const AABB2& in)",
asMETHOD(IRenderer,DrawFlatGameMap),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void FrameDone()",
asMETHOD(IRenderer,FrameDone),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"void Flip()",
asMETHOD(IRenderer,Flip),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"Bitmap@ ReadBitmap()",
asMETHOD(IRenderer,ReadBitmap),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"float get_ScreenWidth()",
asMETHOD(IRenderer,ScreenWidth),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("Renderer",
"float get_ScreenHeight()",
asMETHOD(IRenderer,ScreenHeight),
asCALL_THISCALL);
manager->CheckError(r);
break;
default:
break;
}
}
};
static RendererRegistrar registrar;
}
}