Browse Source

scene: start refactoring the camera code; we now have a stack of cameras

in the scene where we can push and pop cameras.
legacy
Sam Hocevar sam 11 years ago
parent
commit
16a620d537
9 changed files with 139 additions and 186 deletions
  1. +22
    -63
      src/camera.cpp
  2. +10
    -13
      src/camera.h
  3. +6
    -4
      src/easymesh/easymesh.cpp
  4. +2
    -2
      src/gradient.cpp
  5. +37
    -42
      src/scene.cpp
  6. +4
    -4
      src/scene.h
  7. +12
    -9
      test/btphystest.cpp
  8. +39
    -41
      test/meshviewer.cpp
  9. +7
    -8
      tutorial/05_easymesh.cpp

+ 22
- 63
src/camera.cpp View File

@@ -26,111 +26,70 @@
namespace lol
{

Camera::Camera(vec3 const &position, vec3 const &target, vec3 const &up)
: m_target(target),
m_up(up)
Camera::Camera()
{
m_gamegroup = GAMEGROUP_BEFORE;
m_drawgroup = DRAWGROUP_CAMERA;

/* Create a default perspective */
SetPerspective(45.f, 800.f, 600.f, -1000.f, 1000.f);
SetPosition(position);
SetProjection(mat4::perspective(45.f, 800.f, 600.f, -1000.f, 1000.f));
SetView(mat4::lookat(vec3(0.f, 50.f, 50.f),
vec3(0.f),
vec3(0.f, 1.f, 0.f)));
}

Camera::~Camera()
{
}

void Camera::SetPosition(vec3 const &pos)
void Camera::SetView(mat4 const &view)
{
m_position = pos;
m_view_matrix = view;
m_position = inverse(view)[3].xyz;
}

void Camera::SetRotation(quat const &rot)
void Camera::SetView(vec3 eye, vec3 target, vec3 up)
{
m_rotation = rot;
m_view_matrix = mat4::lookat(eye, target, up);
m_position = eye;
}

void Camera::SetOrtho(float width, float height, float near, float far)
void Camera::SetView(vec3 pos, quat rot)
{
m_proj_matrix = mat4::ortho(width, height, near, far);
}

void Camera::SetPerspective(float fov, float width, float height,
float near, float far)
{
m_proj_matrix = mat4::perspective(fov, width, height, near, far);
}

void Camera::SetTarget(vec3 const &pos)
{
m_target = pos;
m_view_matrix = mat4::lookat(pos,
pos + rot.transform(vec3(0.f, 0.f, -1.f)),
rot.transform(vec3(0.f, 1.f, 0.f)));
m_position = pos;
}

vec3 Camera::GetTarget()
{
return m_target;
}
vec3 Camera::GetPosition()
void Camera::SetProjection(mat4 const &proj)
{
return m_position;
m_proj_matrix = proj;
}

mat4 const &Camera::GetViewMatrix()
mat4 Camera::GetView()
{
return m_view_matrix;
}

mat4 const &Camera::GetProjMatrix()
mat4 Camera::GetProjection()
{
return m_proj_matrix;
}

void Camera::ForceSceneUpdate()
vec3 Camera::GetPosition()
{
Scene::GetDefault()->SetViewMatrix(m_view_matrix);
Scene::GetDefault()->SetProjMatrix(m_proj_matrix);
return m_position;
}

void Camera::TickGame(float seconds)
{
WorldEntity::TickGame(seconds);

#if 0
/* Hackish keyboard support */
float updown = 2.f * (Input::GetButtonState('w')
+ Input::GetButtonState('z')
- Input::GetButtonState('s'));
float rightleft = 2.f * (Input::GetButtonState('d')
- Input::GetButtonState('q')
- Input::GetButtonState('a'));
float pgupdown = 2.f * (Input::GetButtonState('r')
- Input::GetButtonState('f'));

/* Hackish stick support */
static Stick *stick = NULL;
if (!stick)
stick = Input::TrackStick();
if (stick && stick->GetAxisCount() >= 2)
{
rightleft += 2.f * stick->GetAxis(0) * std::abs(stick->GetAxis(0));
updown += -2.f * stick->GetAxis(1) * std::abs(stick->GetAxis(1));
}

m_position += vec3(rightleft, pgupdown, -updown) * 200.f * seconds;
m_target += vec3(rightleft, 0, -updown) * 200.f * seconds;

#endif
m_view_matrix = mat4::lookat(m_position, m_target, m_up)
* mat4(m_rotation);
}

void Camera::TickDraw(float seconds)
{
WorldEntity::TickDraw(seconds);

ForceSceneUpdate();
}

} /* namespace lol */


+ 10
- 13
src/camera.h View File

@@ -24,23 +24,21 @@ namespace lol
class Camera : public WorldEntity
{
public:
Camera(vec3 const &position, vec3 const &target, vec3 const &up);
Camera();
~Camera();

char const *GetName() { return "<camera>"; }

void SetPosition(vec3 const &pos);
void SetRotation(quat const &rot);
void SetOrtho(float width, float height, float near, float far);
void SetPerspective(float fov, float width, float height,
float near, float far);
void SetTarget(vec3 const &pos);
vec3 GetTarget();
vec3 GetPosition();
void SetView(mat4 const &view);
void SetView(vec3 eye, vec3 target, vec3 up);
void SetView(vec3 pos, quat rot);

void SetProjection(mat4 const &proj);

mat4 const &GetViewMatrix();
mat4 const &GetProjMatrix();
void ForceSceneUpdate();
mat4 GetView();
mat4 GetProjection();

vec3 GetPosition();

protected:
virtual void TickGame(float seconds);
@@ -48,7 +46,6 @@ protected:

private:
mat4 m_view_matrix, m_proj_matrix;
vec3 m_target, m_up;
};

} /* namespace lol */


+ 6
- 4
src/easymesh/easymesh.cpp View File

@@ -151,7 +151,9 @@ void DefaultShaderData::SetupDefaultData(bool with_UV)
//-----------------------------------------------------------------------------
void DefaultShaderData::SetupShaderDatas(mat4 const &model)
{
mat4 modelview = Scene::GetDefault()->GetViewMatrix() * model;
mat4 proj = Scene::GetDefault()->GetCamera()->GetProjection();
mat4 view = Scene::GetDefault()->GetCamera()->GetView();
mat4 modelview = view * model;
mat3 normalmat = transpose(inverse(mat3(modelview)));

/* FIXME: this should be hidden in the shader */
@@ -167,9 +169,9 @@ void DefaultShaderData::SetupShaderDatas(mat4 const &model)

m_shader->SetUniform(*GetUniform("in_ModelView"), modelview);
m_shader->SetUniform(*GetUniform("in_Inv_ModelView"), inverse(modelview));
m_shader->SetUniform(*GetUniform("in_View"), Scene::GetDefault()->GetViewMatrix());
m_shader->SetUniform(*GetUniform("in_Inv_View"), inverse(Scene::GetDefault()->GetViewMatrix()));
m_shader->SetUniform(*GetUniform("in_Proj"), Scene::GetDefault()->GetProjMatrix());
m_shader->SetUniform(*GetUniform("in_View"), view);
m_shader->SetUniform(*GetUniform("in_Inv_View"), inverse(view));
m_shader->SetUniform(*GetUniform("in_Proj"), proj);
m_shader->SetUniform(*GetUniform("in_NormalMat"), normalmat);
m_shader->SetUniform(*GetUniform("in_Damage"), 0);
}


+ 2
- 2
src/gradient.cpp View File

@@ -95,9 +95,9 @@ void Gradient::TickDraw(float seconds)
data->shader->Bind();

uni_mat = data->shader->GetUniformLocation("proj_matrix");
data->shader->SetUniform(uni_mat, Scene::GetDefault()->GetProjMatrix());
data->shader->SetUniform(uni_mat, Scene::GetDefault()->GetCamera()->GetProjection());
uni_mat = data->shader->GetUniformLocation("view_matrix");
data->shader->SetUniform(uni_mat, Scene::GetDefault()->GetViewMatrix());
data->shader->SetUniform(uni_mat, Scene::GetDefault()->GetCamera()->GetView());
uni_mat = data->shader->GetUniformLocation("model_matrix");
data->shader->SetUniform(uni_mat, model_matrix);



+ 37
- 42
src/scene.cpp View File

@@ -57,10 +57,6 @@ private:
return 0;
}

mat4 m_model_matrix;
mat4 m_view_matrix;
mat4 m_proj_matrix;

Array<Tile> m_tiles;
Array<Light *> m_lights;

@@ -68,6 +64,9 @@ private:
VertexDeclaration *m_vdecl;
Array<VertexBuffer *> bufs;

Camera *m_default_cam;
Array<Camera *> m_camera_stack;

static Scene *scene;
};

@@ -80,10 +79,12 @@ Scene *SceneData::scene = NULL;
Scene::Scene()
: data(new SceneData())
{
data->m_model_matrix = mat4(1.f);
data->m_view_matrix = mat4(1.f);
data->m_proj_matrix = mat4::ortho(0, Video::GetSize().x,
0, Video::GetSize().y, -1000.f, 1000.f);
/* Create a default orthographic camera, in case the user doesn’t. */
data->m_default_cam = new Camera();
mat4 proj = mat4::ortho(0, Video::GetSize().x, 0, Video::GetSize().y,
-1000.f, 1000.f);
data->m_default_cam->SetProjection(proj);
PushCamera(data->m_default_cam);

data->m_shader = 0;
data->m_vdecl = new VertexDeclaration(VertexStream<vec3>(VertexUsage::Position),
@@ -92,6 +93,8 @@ Scene::Scene()

Scene::~Scene()
{
PopCamera(data->m_default_cam);

/* FIXME: this must be done while the GL context is still active.
* Change the code architecture to make sure of that. */
/* FIXME: also, make sure we do not add code to Reset() that will
@@ -109,32 +112,40 @@ Scene *Scene::GetDefault()
return SceneData::scene;
}

void Scene::Reset()
void Scene::PushCamera(Camera *cam)
{
for (int i = 0; i < data->bufs.Count(); i++)
delete data->bufs[i];
data->bufs.Empty();
data->m_lights.Empty();
Ticker::Ref(cam);
data->m_camera_stack.Push(cam);
}

void Scene::SetViewMatrix(mat4 const &m)
void Scene::PopCamera(Camera *cam)
{
data->m_view_matrix = m;
}
/* Parse from the end because that’s probably where we’ll find
* our camera first. */
for (int i = data->m_camera_stack.Count(); i--; )
{
if (data->m_camera_stack[i] == cam)
{
Ticker::Unref(cam);
data->m_camera_stack.Remove(i);
return;
}
}

void Scene::SetProjMatrix(mat4 const &m)
{
data->m_proj_matrix = m;
ASSERT(false, "trying to pop a nonexistent camera from the scene");
}

mat4 const &Scene::GetViewMatrix(void)
Camera *Scene::GetCamera()
{
return data->m_view_matrix;
return data->m_camera_stack.Last();
}

mat4 const &Scene::GetProjMatrix(void)
void Scene::Reset()
{
return data->m_proj_matrix;
for (int i = 0; i < data->bufs.Count(); i++)
delete data->bufs[i];
data->bufs.Empty();
data->m_lights.Empty();
}

void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale)
@@ -183,22 +194,6 @@ void Scene::Render() // XXX: rename to Blit()
qsort(&data->m_tiles[0], data->m_tiles.Count(),
sizeof(Tile), SceneData::Compare);

// XXX: debug stuff
data->m_model_matrix = mat4::translate(320.0f, 240.0f, 0.0f);
#if 0
static float f = 0.0f;
f += 0.01f;
data->m_model_matrix *= mat4::rotate(6.0f * sinf(f), 1.0f, 0.0f, 0.0f);
data->m_model_matrix *= mat4::rotate(17.0f * cosf(f), 0.0f, 0.0f, 1.0f);
#endif
data->m_model_matrix *= mat4::translate(-320.0f, -240.0f, 0.0f);
#if __ANDROID__
data->m_model_matrix = mat4::scale(1280.0f / 640,
736.0f / 480,
1.0f) * data->m_model_matrix;
#endif
// XXX: end of debug stuff

ShaderUniform uni_mat, uni_tex;
ShaderAttrib attr_pos, attr_tex;
attr_pos = data->m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0);
@@ -207,11 +202,11 @@ void Scene::Render() // XXX: rename to Blit()
data->m_shader->Bind();

uni_mat = data->m_shader->GetUniformLocation("proj_matrix");
data->m_shader->SetUniform(uni_mat, data->m_proj_matrix);
data->m_shader->SetUniform(uni_mat, GetCamera()->GetProjection());
uni_mat = data->m_shader->GetUniformLocation("view_matrix");
data->m_shader->SetUniform(uni_mat, data->m_view_matrix);
data->m_shader->SetUniform(uni_mat, GetCamera()->GetView());
uni_mat = data->m_shader->GetUniformLocation("model_matrix");
data->m_shader->SetUniform(uni_mat, data->m_model_matrix);
data->m_shader->SetUniform(uni_mat, mat4(1.f));

#if defined USE_D3D9 || defined _XBOX
#else


+ 4
- 4
src/scene.h View File

@@ -20,6 +20,7 @@

#include "tileset.h"
#include "light.h"
#include "camera.h"

namespace lol
{
@@ -34,10 +35,9 @@ public:

static Scene *GetDefault();

void SetViewMatrix(mat4 const &m);
void SetProjMatrix(mat4 const &m);
mat4 const &GetViewMatrix(void);
mat4 const &GetProjMatrix(void);
Camera *GetCamera();
void PushCamera(Camera *cam);
void PopCamera(Camera *cam);

void Reset();
void Render();


+ 12
- 9
test/btphystest.cpp View File

@@ -66,13 +66,12 @@ BtPhysTest::BtPhysTest(bool editor)
m_loop_value = .0f;

/* Create a camera that matches the settings of XNA BtPhysTest */
m_camera = new Camera(vec3(0.f, 600.f, 0.f),
vec3(0.f, 0.f, 0.f),
vec3(0, 1, 0));
m_camera->SetRotation(quat::fromeuler_xyz(0.f, 0.f, 0.f));
m_camera->SetPerspective(45.f, 1280.f, 960.f, .1f, 1000.f);
//m_camera->SetOrtho(1280.f / 6, 960.f / 6, -1000.f, 1000.f);
Ticker::Ref(m_camera);
m_camera = new Camera();
m_camera->SetView(vec3(0.f, 600.f, 0.f),
vec3(0.f, 0.f, 0.f),
vec3(0, 1, 0));
m_camera->SetProjection(mat4::perspective(45.f, 1280.f, 960.f, .1f, 1000.f));
Scene::GetDefault()->PushCamera(m_camera);

m_ready = false;

@@ -304,7 +303,7 @@ void BtPhysTest::TickGame(float seconds)

mat4 GroundMat = PhysObj->GetTransform();
vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
vec3 CenterToCam = m_camera->m_position - GroundBarycenter;
vec3 CenterToCam = m_camera->GetPosition() - GroundBarycenter;

if (dot(normalize(CenterToCam - CenterToGround),
normalize(CenterToGround)) > 0.f)
@@ -393,9 +392,11 @@ void BtPhysTest::TickGame(float seconds)

PhysObjBarycenter /= factor;

#if 0
m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
#endif
}
else
{
@@ -411,8 +412,10 @@ void BtPhysTest::TickGame(float seconds)

PhysObjBarycenter /= factor;

#if 0
m_camera->SetTarget(PhysObjBarycenter);
m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
#endif
}

}
@@ -433,7 +436,7 @@ void BtPhysTest::TickDraw(float seconds)

BtPhysTest::~BtPhysTest()
{
Ticker::Unref(m_camera);
Scene::GetDefault()->PopCamera(m_camera);
Ticker::Unref(m_light1);
Ticker::Unref(m_light2);



+ 39
- 41
test/meshviewer.cpp View File

@@ -64,9 +64,9 @@ public:
//m_fov_compensation = mat4::translate(-0.5f * video_size.x, -0.5f * video_size.y, -dist);
m_fov_compensation = mat4::translate(vec3(.0f));
if (new_fov > 0.1f)
m_camera->SetPerspective(new_fov, (float)video_size.x, (float)video_size.y, .1f, 1000.f);
Scene::GetDefault()->GetCamera()->SetProjection(mat4::perspective(new_fov, (float)video_size.x, (float)video_size.y, .1f, 1000.f));
else
m_camera->SetOrtho((float)video_size.x, (float)video_size.y, .1f, 1000.f);
Scene::GetDefault()->GetCamera()->SetProjection(mat4::ortho((float)video_size.x, (float)video_size.y, .1f, 1000.f));
}

MeshViewer(char const *file_name = "data/mesh-buffer.txt")
@@ -98,20 +98,18 @@ public:
Input::LinkActionToKey(IPT_MESH_ROT_DOWN, Key::KP5);

m_angle = 0;
DefaultTexture = NULL;
m_default_texture = NULL;

//Camera Setup
m_fov_zoom_damp = .0f;
m_fov_damp = 60.0f;
m_fov = 60.0f;
m_camera = new Camera(vec3(0.f, 600.f, 0.f),
vec3(0.f, 0.f, 0.f),
vec3(0, 1, 0));
m_camera = new Camera();
SetFov(m_fov_damp);
m_camera->SetTarget(vec3(0.f, 0.f, 0.f));
m_camera->SetPosition(vec3(0.f, 0.f, 10.f));
m_camera->ForceSceneUpdate();
Ticker::Ref(m_camera);
m_camera->SetView(vec3(0.f, 0.f, 10.f),
vec3(0.f, 0.f, 0.f),
vec3(0.f, 1.f, 0.f));
Scene::GetDefault()->PushCamera(m_camera);

//Lights setup
m_lights << new Light();
@@ -148,7 +146,7 @@ public:

~MeshViewer()
{
Ticker::Unref(m_camera);
Scene::GetDefault()->PopCamera(m_camera);
for (int i = 0; i < m_lights.Count(); ++i)
Ticker::Unref(m_lights[i]);
}
@@ -213,8 +211,8 @@ public:
m_fov_damp = damp(m_fov_damp, m_fov, .2f, seconds);
SetFov(m_fov_damp);

m_camera->SetPosition(m_camera->GetPosition() + cam_move);
m_camera->SetTarget(m_camera->GetPosition() + vec3(0, 0, -5.0f));
vec3 campos = Scene::GetDefault()->GetCamera()->GetPosition();
Scene::GetDefault()->GetCamera()->SetView(campos + cam_move, quat(1.f));

//--
//Mesh movement handling
@@ -329,12 +327,12 @@ public:
Video::SetDebugRenderMode(DebugRenderMode::UV);
}

if (!DefaultTexture)
if (!m_default_texture)
{
m_texture_shader = Shader::Create(LOLFX_RESOURCE_NAME(shinymvtexture));
m_texture_uni = m_texture_shader->GetUniformLocation("u_Texture");
//m_image = new Image("data/test-texture.png");
DefaultTexture = Tiler::Register("data/test-texture.png", ivec2(0), ivec2(0,1));
m_default_texture = Tiler::Register("data/test-texture.png", ivec2(0), ivec2(0,1));

//ivec2 size = m_image->GetSize();
//// m_image->GetFormat()
@@ -342,8 +340,8 @@ public:
//m_texture->SetData(m_image->GetData());
// PixelFormat::ABGR_8
}
else if (m_texture && DefaultTexture)
m_texture_shader->SetUniform(m_texture_uni, DefaultTexture->GetTexture(), 0);
else if (m_texture && m_default_texture)
m_texture_shader->SetUniform(m_texture_uni, m_default_texture->GetTexture(), 0);

for (int i = 0; i < m_meshes.Count(); i++)
{
@@ -365,7 +363,7 @@ public:

Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

mat4 default_proj = Scene::GetDefault()->GetProjMatrix();
mat4 default_proj = Scene::GetDefault()->GetCamera()->GetProjection();
for (int i = 0; i < m_meshes.Count(); i++)
{
float new_scale = max(.0f, 1.0f - (m_mesh_offset_damp.y * (float)(m_meshes.Count() - (i + 1))));
@@ -379,11 +377,11 @@ public:
new_mesh_offset = new_mesh_offset + vec3(m_meshes[j].m3 * ofs_scale * ofs_scale * m_mesh_offset_damp.x, .0f, .0f);
}
m_meshes[i].m4 = damp(m_meshes[i].m4, new_mesh_offset, .35f, seconds);
Scene::GetDefault()->SetProjMatrix(mat4::translate(m_meshes[i].m4) *
mat4::translate(vec3(m_mesh_screen_offset_damp, .0f)) *
mat4::scale(vec3(vec2(m_meshes[i].m3), 1.0f)) *
default_proj *
m_fov_compensation);
Scene::GetDefault()->GetCamera()->SetProjection(mat4::translate(m_meshes[i].m4) *
mat4::translate(vec3(m_mesh_screen_offset_damp, .0f)) *
mat4::scale(vec3(vec2(m_meshes[i].m3), 1.0f)) *
default_proj *
m_fov_compensation);
#if WITH_FUR
for (int j=0; j < 40; j++)
m_meshes[i].m1.Render(m_mat, 0.1 * j);
@@ -393,40 +391,40 @@ public:
Video::Clear(ClearMask::Depth);
}
}
Scene::GetDefault()->SetProjMatrix(default_proj);
Scene::GetDefault()->GetCamera()->SetProjection(default_proj);
}

private:
float m_angle;
mat4 m_mat;
Camera * m_camera;
float m_angle;
mat4 m_mat;

//Mesh infos
//Move damping
vec2 m_mesh_rotate_damp;
vec2 m_mesh_screen_move_damp;
vec2 m_mesh_move_damp;
vec2 m_mesh_rotate_damp;
vec2 m_mesh_screen_move_damp;
vec2 m_mesh_move_damp;

//Move transform damping
vec2 m_mesh_rotation_damp;
vec2 m_mesh_screen_offset_damp;
vec2 m_mesh_offset_damp;
vec2 m_mesh_rotation_damp;
vec2 m_mesh_screen_offset_damp;
vec2 m_mesh_offset_damp;

vec2 m_mesh_rotation; //Meshes rotation
vec2 m_mesh_screen_offset;//Meshes screen offset
vec2 m_mesh_offset; //Mesh Offset after first mesh (x: offset, y: scale)
vec2 m_mesh_rotation; //Meshes rotation
vec2 m_mesh_screen_offset;//Meshes screen offset
vec2 m_mesh_offset; //Mesh Offset after first mesh (x: offset, y: scale)

//File data
String m_file_name;
Array<String> m_cmdlist;
float m_stream_update_time;
float m_stream_update_timer;
String m_file_name;
Array<String> m_cmdlist;
float m_stream_update_time;
float m_stream_update_timer;

//misc datas
Array<EasyMesh, bool, float, vec3> m_meshes;
Array<Light *> m_lights;
Camera * m_camera;
Shader * m_texture_shader;
TileSet * DefaultTexture;
TileSet * m_default_texture;
Texture * m_texture;
ShaderUniform m_texture_uni;
Image * m_image;


+ 7
- 8
tutorial/05_easymesh.cpp View File

@@ -46,13 +46,12 @@ public:

m_angle = 0;

m_camera = new Camera(vec3(0.f, 600.f, 0.f),
vec3(0.f, 0.f, 0.f),
vec3(0, 1, 0));
m_camera->SetPerspective(30.f, 960.f, 600.f, .1f, 1000.f);
m_camera->SetTarget(vec3(0.f, -1.f, 0.f));
m_camera->SetPosition(vec3(-15.f, 5.f, 0.f));
Ticker::Ref(m_camera);
m_camera = new Camera();
m_camera->SetProjection(mat4::perspective(30.f, 960.f, 600.f, .1f, 1000.f));
m_camera->SetView(mat4::lookat(vec3(-15.f, 5.f, 0.f),
vec3(0.f, -1.f, 0.f),
vec3(0.f, 1.f, 0.f)));
Scene::GetDefault()->PushCamera(m_camera);

/* Add a white directional light */
m_light1 = new Light();
@@ -71,7 +70,7 @@ public:

~EasyMeshTutorial()
{
Ticker::Unref(m_camera);
Scene::GetDefault()->PopCamera(m_camera);
Ticker::Unref(m_light1);
Ticker::Unref(m_light2);
}


Loading…
Cancel
Save