|
|
@@ -40,19 +40,7 @@ namespace lol |
|
|
|
|
|
|
|
array<Scene*> Scene::g_scenes; |
|
|
|
|
|
|
|
/* |
|
|
|
* A quick and dirty Tile structure for 2D blits |
|
|
|
*/ |
|
|
|
|
|
|
|
struct Tile |
|
|
|
{ |
|
|
|
mat4 m_model; |
|
|
|
TileSet *m_tileset; |
|
|
|
int m_id; |
|
|
|
}; |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
static array<SceneDisplay*> m_scene_displays; |
|
|
|
static array<SceneDisplay*> g_scene_displays; |
|
|
|
|
|
|
|
static inline void gpu_marker(char const *message) |
|
|
|
{ |
|
|
@@ -64,35 +52,34 @@ static inline void gpu_marker(char const *message) |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* Public SceneDisplay class |
|
|
|
*/ |
|
|
|
// |
|
|
|
// Public SceneDisplay class |
|
|
|
// |
|
|
|
|
|
|
|
void SceneDisplay::Add(SceneDisplay* display) |
|
|
|
{ |
|
|
|
m_scene_displays << display; |
|
|
|
g_scene_displays << display; |
|
|
|
} |
|
|
|
|
|
|
|
int SceneDisplay::GetCount() |
|
|
|
{ |
|
|
|
return m_scene_displays.count(); |
|
|
|
return g_scene_displays.count(); |
|
|
|
} |
|
|
|
|
|
|
|
SceneDisplay* SceneDisplay::GetDisplay(int index) |
|
|
|
{ |
|
|
|
ASSERT(0 <= index && index < m_scene_displays.count(), |
|
|
|
ASSERT(0 <= index && index < g_scene_displays.count(), |
|
|
|
"invalid display index %d", index); |
|
|
|
return m_scene_displays[index]; |
|
|
|
return g_scene_displays[index]; |
|
|
|
} |
|
|
|
|
|
|
|
void SceneDisplay::DestroyAll() |
|
|
|
{ |
|
|
|
for (SceneDisplay* display : m_scene_displays) |
|
|
|
for (SceneDisplay* display : g_scene_displays) |
|
|
|
delete display; |
|
|
|
m_scene_displays.clear(); |
|
|
|
g_scene_displays.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
/* ------------------------------------------------ */ |
|
|
|
void SceneDisplay::Enable() |
|
|
|
{ |
|
|
|
// TODO: PROFILER STUFF |
|
|
@@ -119,87 +106,9 @@ void PrimitiveRenderer::Render(Scene& scene, std::shared_ptr<PrimitiveSource> pr |
|
|
|
* Scene implementation class |
|
|
|
*/ |
|
|
|
|
|
|
|
class SceneData |
|
|
|
{ |
|
|
|
friend class Scene; |
|
|
|
|
|
|
|
public: |
|
|
|
SceneData() |
|
|
|
{ |
|
|
|
/* TODO: FIX THAT */ |
|
|
|
ASSERT(!(m_used_id & ((uint64_t)1 << 63)), "Too many scenes !!!!"); |
|
|
|
m_mask_id = m_used_id; |
|
|
|
m_used_id = m_used_id << 1; |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
/* Mask ID */ |
|
|
|
/* TODO: Do a mask class that handles more than 64 slots */ |
|
|
|
static uint64_t m_used_id; |
|
|
|
uint64_t m_mask_id = 0; |
|
|
|
|
|
|
|
/* Scene display: if none has been set to the scene, |
|
|
|
* the default one created by the app will be used */ |
|
|
|
SceneDisplay* m_display = nullptr; |
|
|
|
|
|
|
|
/** Render buffers: where to render to. */ |
|
|
|
std::shared_ptr<Framebuffer> m_renderbuffer[4]; |
|
|
|
|
|
|
|
struct postprocess |
|
|
|
{ |
|
|
|
std::shared_ptr<Shader> m_shader[2]; |
|
|
|
std::shared_ptr<VertexBuffer> m_vbo; |
|
|
|
std::shared_ptr<VertexDeclaration> m_vdecl; |
|
|
|
ShaderUniform m_buffer_uni[2][3]; |
|
|
|
ShaderAttrib m_coord[2]; |
|
|
|
} |
|
|
|
m_pp; |
|
|
|
|
|
|
|
/* Sources are shared by all scenes. |
|
|
|
* Renderers are scene-dependent. They get the primitive in the identical |
|
|
|
* slot to render with the given scene. |
|
|
|
* Primitives and renderers will be kept until: |
|
|
|
* - Updated by entity |
|
|
|
* - Marked Fire&Forget |
|
|
|
* - Scene is destroyed */ |
|
|
|
std::map<uintptr_t, array<std::shared_ptr<PrimitiveRenderer>>> m_prim_renderers; |
|
|
|
static std::map<uintptr_t, array<std::shared_ptr<PrimitiveSource>>> m_prim_sources; |
|
|
|
static mutex m_prim_mutex; |
|
|
|
|
|
|
|
Camera *m_default_cam; |
|
|
|
array<Camera *> m_camera_stack; |
|
|
|
|
|
|
|
/* Old line API <P0, P1, COLOR, TIME, MASK> */ |
|
|
|
struct line_api |
|
|
|
{ |
|
|
|
//float m_duration, m_segment_size; |
|
|
|
//vec4 m_color; |
|
|
|
array<vec3, vec3, vec4, float, int, bool, bool> m_lines; |
|
|
|
int /*m_mask,*/ m_debug_mask; |
|
|
|
std::shared_ptr<Shader> m_shader; |
|
|
|
std::shared_ptr<VertexDeclaration> m_vdecl; |
|
|
|
} |
|
|
|
m_line_api; |
|
|
|
|
|
|
|
/* The old tiles API */ |
|
|
|
struct tile_api |
|
|
|
{ |
|
|
|
int m_cam; |
|
|
|
array<Tile> m_tiles; |
|
|
|
array<Tile> m_palettes; |
|
|
|
array<Light *> m_lights; |
|
|
|
|
|
|
|
std::shared_ptr<Shader> m_shader; |
|
|
|
std::shared_ptr<Shader> m_palette_shader; |
|
|
|
|
|
|
|
std::shared_ptr<VertexDeclaration> m_vdecl; |
|
|
|
array<std::shared_ptr<VertexBuffer>> m_bufs; |
|
|
|
} |
|
|
|
m_tile_api; |
|
|
|
}; |
|
|
|
uint64_t SceneData::m_used_id = 1; |
|
|
|
std::map<uintptr_t, array<std::shared_ptr<PrimitiveSource>>> SceneData::m_prim_sources; |
|
|
|
mutex SceneData::m_prim_mutex; |
|
|
|
uint64_t Scene::g_used_id = 1; |
|
|
|
mutex Scene::g_prim_mutex; |
|
|
|
std::map<uintptr_t, array<std::shared_ptr<PrimitiveSource>>> Scene::g_prim_sources; |
|
|
|
|
|
|
|
/* |
|
|
|
* Public Scene class |
|
|
@@ -207,45 +116,49 @@ mutex SceneData::m_prim_mutex; |
|
|
|
Scene::Scene(ivec2 size) |
|
|
|
: m_size(size), |
|
|
|
m_wanted_size(size), |
|
|
|
data(std::make_unique<SceneData>()), |
|
|
|
m_renderer(std::make_shared<Renderer>(size)) |
|
|
|
{ |
|
|
|
/* TODO: FIX THAT */ |
|
|
|
ASSERT(!(g_used_id & ((uint64_t)1 << 63)), "Too many scenes !!!!"); |
|
|
|
m_mask_id = g_used_id; |
|
|
|
g_used_id = g_used_id << 1; |
|
|
|
|
|
|
|
for (int i = 0; i < 4; ++i) |
|
|
|
data->m_renderbuffer[i] = std::make_shared<Framebuffer>(m_size); |
|
|
|
data->m_pp.m_shader[0] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_blit)); |
|
|
|
data->m_pp.m_shader[1] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_postprocess)); |
|
|
|
data->m_pp.m_coord[0] = data->m_pp.m_shader[0]->GetAttribLocation(VertexUsage::Position, 0); |
|
|
|
data->m_pp.m_coord[1] = data->m_pp.m_shader[1]->GetAttribLocation(VertexUsage::Position, 0); |
|
|
|
data->m_pp.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec2>(VertexUsage::Position)); |
|
|
|
data->m_pp.m_buffer_uni[0][0] = data->m_pp.m_shader[0]->GetUniformLocation("u_buffer"); |
|
|
|
data->m_pp.m_buffer_uni[1][0] = data->m_pp.m_shader[1]->GetUniformLocation("u_buffer"); |
|
|
|
data->m_pp.m_buffer_uni[1][1] = data->m_pp.m_shader[1]->GetUniformLocation("u_prev_buffer"); |
|
|
|
data->m_pp.m_buffer_uni[1][2] = data->m_pp.m_shader[1]->GetUniformLocation("u_prev_final"); |
|
|
|
m_renderbuffer[i] = std::make_shared<Framebuffer>(m_size); |
|
|
|
m_pp.m_shader[0] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_blit)); |
|
|
|
m_pp.m_shader[1] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_postprocess)); |
|
|
|
m_pp.m_coord[0] = m_pp.m_shader[0]->GetAttribLocation(VertexUsage::Position, 0); |
|
|
|
m_pp.m_coord[1] = m_pp.m_shader[1]->GetAttribLocation(VertexUsage::Position, 0); |
|
|
|
m_pp.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec2>(VertexUsage::Position)); |
|
|
|
m_pp.m_buffer_uni[0][0] = m_pp.m_shader[0]->GetUniformLocation("u_buffer"); |
|
|
|
m_pp.m_buffer_uni[1][0] = m_pp.m_shader[1]->GetUniformLocation("u_buffer"); |
|
|
|
m_pp.m_buffer_uni[1][1] = m_pp.m_shader[1]->GetUniformLocation("u_prev_buffer"); |
|
|
|
m_pp.m_buffer_uni[1][2] = m_pp.m_shader[1]->GetUniformLocation("u_prev_final"); |
|
|
|
|
|
|
|
array<vec2> quad { vec2( 1.0, 1.0), vec2(-1.0, -1.0), vec2( 1.0, -1.0), |
|
|
|
vec2(-1.0, -1.0), vec2( 1.0, 1.0), vec2(-1.0, 1.0), }; |
|
|
|
|
|
|
|
data->m_pp.m_vbo = std::make_shared<VertexBuffer>(quad.bytes()); |
|
|
|
void *vertices = data->m_pp.m_vbo->Lock(0, 0); |
|
|
|
m_pp.m_vbo = std::make_shared<VertexBuffer>(quad.bytes()); |
|
|
|
void *vertices = m_pp.m_vbo->Lock(0, 0); |
|
|
|
memcpy(vertices, quad.data(), quad.bytes()); |
|
|
|
data->m_pp.m_vbo->Unlock(); |
|
|
|
m_pp.m_vbo->Unlock(); |
|
|
|
|
|
|
|
/* Create a default orthographic camera, in case the user doesn’t. */ |
|
|
|
data->m_default_cam = new Camera(); |
|
|
|
m_default_cam = new Camera(); |
|
|
|
mat4 proj = mat4::ortho(0.f, (float)m_size.x, 0.f, (float)m_size.y, -1000.f, 1000.f); |
|
|
|
data->m_default_cam->SetProjection(proj); |
|
|
|
PushCamera(data->m_default_cam); |
|
|
|
m_default_cam->SetProjection(proj); |
|
|
|
PushCamera(m_default_cam); |
|
|
|
|
|
|
|
data->m_tile_api.m_cam = -1; |
|
|
|
data->m_tile_api.m_shader = 0; |
|
|
|
data->m_tile_api.m_palette_shader = 0; |
|
|
|
data->m_tile_api.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec3>(VertexUsage::Position), |
|
|
|
VertexStream<vec2>(VertexUsage::TexCoord)); |
|
|
|
m_tile_api.m_cam = -1; |
|
|
|
m_tile_api.m_shader = 0; |
|
|
|
m_tile_api.m_palette_shader = 0; |
|
|
|
m_tile_api.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec3>(VertexUsage::Position), |
|
|
|
VertexStream<vec2>(VertexUsage::TexCoord)); |
|
|
|
|
|
|
|
data->m_line_api.m_shader = 0; |
|
|
|
data->m_line_api.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec4,vec4>(VertexUsage::Position, VertexUsage::Color)); |
|
|
|
m_line_api.m_shader = 0; |
|
|
|
m_line_api.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec4,vec4>(VertexUsage::Position, VertexUsage::Color)); |
|
|
|
|
|
|
|
data->m_line_api.m_debug_mask = 1; |
|
|
|
m_line_api.m_debug_mask = 1; |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::resize(ivec2 size) |
|
|
@@ -253,10 +166,9 @@ void Scene::resize(ivec2 size) |
|
|
|
m_wanted_size = size; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
Scene::~Scene() |
|
|
|
{ |
|
|
|
PopCamera(data->m_default_cam); |
|
|
|
PopCamera(m_default_cam); |
|
|
|
|
|
|
|
/* FIXME: this must be done while the GL context is still active. |
|
|
|
* Change the code architecture to make sure of that. */ |
|
|
@@ -265,7 +177,6 @@ Scene::~Scene() |
|
|
|
Reset(); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::AddNew(ivec2 size) |
|
|
|
{ |
|
|
|
Scene::g_scenes << new Scene(size); |
|
|
@@ -288,13 +199,11 @@ int Scene::GetCount() |
|
|
|
return g_scenes.count(); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
bool Scene::IsReady(int index) |
|
|
|
{ |
|
|
|
return 0 <= index && index < g_scenes.count() && !!g_scenes[index]; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
Scene& Scene::GetScene(int index) |
|
|
|
{ |
|
|
|
ASSERT(0 <= index && index < g_scenes.count() && !!g_scenes[index], |
|
|
@@ -302,51 +211,40 @@ Scene& Scene::GetScene(int index) |
|
|
|
return *g_scenes[index]; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::Link(Entity* entity) |
|
|
|
{ |
|
|
|
entity->m_scene_mask |= data->m_mask_id; |
|
|
|
entity->m_scene_mask |= m_mask_id; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
bool Scene::IsRelevant(Entity* entity) |
|
|
|
{ |
|
|
|
return !!(entity->m_scene_mask & data->m_mask_id); |
|
|
|
return !!(entity->m_scene_mask & m_mask_id); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
Camera* Scene::GetCamera(int cam_idx) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
return (0 <= cam_idx && cam_idx < data->m_camera_stack.count()) ? |
|
|
|
data->m_camera_stack[cam_idx] : |
|
|
|
data->m_camera_stack.last(); |
|
|
|
return (0 <= cam_idx && cam_idx < m_camera_stack.count()) ? |
|
|
|
m_camera_stack[cam_idx] : |
|
|
|
m_camera_stack.last(); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
int Scene::PushCamera(Camera *cam) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
Ticker::Ref(cam); |
|
|
|
data->m_camera_stack.push(cam); |
|
|
|
return (int)data->m_camera_stack.count() - 1; |
|
|
|
m_camera_stack.push(cam); |
|
|
|
return (int)m_camera_stack.count() - 1; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::PopCamera(Camera *cam) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
/* Parse from the end because that’s probably where we’ll find |
|
|
|
* our camera first. */ |
|
|
|
for (int i = data->m_camera_stack.count(); i--;) |
|
|
|
for (int i = m_camera_stack.count(); i--;) |
|
|
|
{ |
|
|
|
if (data->m_camera_stack[i] == cam) |
|
|
|
if (m_camera_stack[i] == cam) |
|
|
|
{ |
|
|
|
Ticker::Unref(cam); |
|
|
|
data->m_camera_stack.remove(i); |
|
|
|
m_camera_stack.remove(i); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@@ -354,52 +252,49 @@ void Scene::PopCamera(Camera *cam) |
|
|
|
ASSERT(false, "trying to pop a nonexistent camera from the scene"); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::SetTileCam(int cam_idx) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
data->m_tile_api.m_cam = cam_idx; |
|
|
|
m_tile_api.m_cam = cam_idx; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::Reset() |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
/* New scenegraph: Release fire&forget primitives */ |
|
|
|
for (uintptr_t key : keys(data->m_prim_renderers)) |
|
|
|
for (uintptr_t key : keys(m_prim_renderers)) |
|
|
|
{ |
|
|
|
for (int idx = 0; idx < data->m_prim_renderers[key].count(); ++idx) |
|
|
|
if (data->m_prim_renderers[key][idx]->m_fire_and_forget) |
|
|
|
for (int idx = 0; idx < m_prim_renderers[key].count(); ++idx) |
|
|
|
if (m_prim_renderers[key][idx]->m_fire_and_forget) |
|
|
|
ReleasePrimitiveRenderer(idx--, key); |
|
|
|
} |
|
|
|
|
|
|
|
data->m_tile_api.m_bufs.clear(); |
|
|
|
data->m_tile_api.m_lights.clear(); |
|
|
|
m_tile_api.m_bufs.clear(); |
|
|
|
m_tile_api.m_lights.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
//---- Primitive source stuff ------------------------------------------------- |
|
|
|
// |
|
|
|
// Primitive source stuff |
|
|
|
// |
|
|
|
|
|
|
|
int Scene::HasPrimitiveSource(uintptr_t key) |
|
|
|
{ |
|
|
|
int count; |
|
|
|
SceneData::m_prim_mutex.lock(); |
|
|
|
g_prim_mutex.lock(); |
|
|
|
{ |
|
|
|
count = SceneData::m_prim_sources[key].count(); |
|
|
|
count = g_prim_sources[key].count(); |
|
|
|
} |
|
|
|
SceneData::m_prim_mutex.unlock(); |
|
|
|
g_prim_mutex.unlock(); |
|
|
|
return count; |
|
|
|
} |
|
|
|
|
|
|
|
int Scene::AddPrimitiveSource(uintptr_t key, std::shared_ptr<PrimitiveSource> source) |
|
|
|
{ |
|
|
|
int count; |
|
|
|
SceneData::m_prim_mutex.lock(); |
|
|
|
g_prim_mutex.lock(); |
|
|
|
{ |
|
|
|
count = SceneData::m_prim_sources[key].count(); |
|
|
|
SceneData::m_prim_sources[key].push(source); |
|
|
|
count = g_prim_sources[key].count(); |
|
|
|
g_prim_sources[key].push(source); |
|
|
|
} |
|
|
|
SceneData::m_prim_mutex.unlock(); |
|
|
|
g_prim_mutex.unlock(); |
|
|
|
return count; |
|
|
|
} |
|
|
|
|
|
|
@@ -411,27 +306,27 @@ void Scene::SetPrimitiveSource(int index, uintptr_t key, std::shared_ptr<Primiti |
|
|
|
// Keep reference to old source until AFTER we release the lock |
|
|
|
std::shared_ptr<PrimitiveSource> old; |
|
|
|
|
|
|
|
SceneData::m_prim_mutex.lock(); |
|
|
|
g_prim_mutex.lock(); |
|
|
|
{ |
|
|
|
if (index < SceneData::m_prim_sources[key].count()) |
|
|
|
old = SceneData::m_prim_sources[key][index]; |
|
|
|
if (index < g_prim_sources[key].count()) |
|
|
|
old = g_prim_sources[key][index]; |
|
|
|
else |
|
|
|
SceneData::m_prim_sources[key].resize(index + 1); |
|
|
|
SceneData::m_prim_sources[key][index] = source; |
|
|
|
g_prim_sources[key].resize(index + 1); |
|
|
|
g_prim_sources[key][index] = source; |
|
|
|
} |
|
|
|
SceneData::m_prim_mutex.unlock(); |
|
|
|
g_prim_mutex.unlock(); |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::ReleasePrimitiveSource(int index, uintptr_t key) |
|
|
|
{ |
|
|
|
std::shared_ptr<PrimitiveSource> old; |
|
|
|
SceneData::m_prim_mutex.lock(); |
|
|
|
g_prim_mutex.lock(); |
|
|
|
{ |
|
|
|
ASSERT(0 <= index && index < SceneData::m_prim_sources[key].count()); |
|
|
|
old = SceneData::m_prim_sources[key][index]; |
|
|
|
SceneData::m_prim_sources[key].remove(index); |
|
|
|
ASSERT(0 <= index && index < g_prim_sources[key].count()); |
|
|
|
old = g_prim_sources[key][index]; |
|
|
|
g_prim_sources[key].remove(index); |
|
|
|
} |
|
|
|
SceneData::m_prim_mutex.unlock(); |
|
|
|
g_prim_mutex.unlock(); |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::ReleaseAllPrimitiveSources(uintptr_t key) |
|
|
@@ -439,26 +334,29 @@ void Scene::ReleaseAllPrimitiveSources(uintptr_t key) |
|
|
|
// Delete oldies AFTER having released the lock |
|
|
|
array<std::shared_ptr<PrimitiveSource>> oldies; |
|
|
|
|
|
|
|
SceneData::m_prim_mutex.lock(); |
|
|
|
g_prim_mutex.lock(); |
|
|
|
{ |
|
|
|
oldies.reserve(SceneData::m_prim_sources[key].count()); |
|
|
|
for (auto source : SceneData::m_prim_sources[key]) |
|
|
|
oldies.reserve(g_prim_sources[key].count()); |
|
|
|
for (auto source : g_prim_sources[key]) |
|
|
|
oldies << source; |
|
|
|
SceneData::m_prim_sources[key].clear(); |
|
|
|
g_prim_sources[key].clear(); |
|
|
|
} |
|
|
|
SceneData::m_prim_mutex.unlock(); |
|
|
|
g_prim_mutex.unlock(); |
|
|
|
} |
|
|
|
|
|
|
|
//---- Primitive renderer stuff ----------------------------------------------- |
|
|
|
// |
|
|
|
// Primitive renderer stuff |
|
|
|
// |
|
|
|
|
|
|
|
int Scene::HasPrimitiveRenderer(uintptr_t key) |
|
|
|
{ |
|
|
|
return data->m_prim_renderers[key].count(); |
|
|
|
return m_prim_renderers[key].count(); |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::AddPrimitiveRenderer(uintptr_t key, std::shared_ptr<PrimitiveRenderer> renderer) |
|
|
|
{ |
|
|
|
renderer->m_fire_and_forget = true; |
|
|
|
data->m_prim_renderers[key].push(renderer); |
|
|
|
m_prim_renderers[key].push(renderer); |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr<PrimitiveRenderer> renderer) |
|
|
@@ -466,24 +364,23 @@ void Scene::SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr<Primi |
|
|
|
ASSERT(renderer); |
|
|
|
ASSERT(index >= 0); |
|
|
|
|
|
|
|
if (index >= data->m_prim_renderers[key].count()) |
|
|
|
data->m_prim_renderers[key].resize(index + 1); |
|
|
|
data->m_prim_renderers[key][index] = renderer; |
|
|
|
if (index >= m_prim_renderers[key].count()) |
|
|
|
m_prim_renderers[key].resize(index + 1); |
|
|
|
m_prim_renderers[key][index] = renderer; |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::ReleasePrimitiveRenderer(int index, uintptr_t key) |
|
|
|
{ |
|
|
|
ASSERT(0 <= index && index < data->m_prim_renderers[key].count()); |
|
|
|
ASSERT(0 <= index && index < m_prim_renderers[key].count()); |
|
|
|
|
|
|
|
data->m_prim_renderers[key].remove(index); |
|
|
|
m_prim_renderers[key].remove(index); |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::ReleaseAllPrimitiveRenderers(uintptr_t key) |
|
|
|
{ |
|
|
|
data->m_prim_renderers[key].clear(); |
|
|
|
m_prim_renderers[key].clear(); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::AddTile(TileSet *tileset, int id, vec3 pos, vec2 scale, float radians) |
|
|
|
{ |
|
|
|
ASSERT(id < tileset->GetTileCount()); |
|
|
@@ -508,62 +405,48 @@ void Scene::AddTile(TileSet *tileset, int id, mat4 model) |
|
|
|
t.m_id = id; |
|
|
|
|
|
|
|
if (tileset->GetPalette()) |
|
|
|
data->m_tile_api.m_palettes.push(t); |
|
|
|
m_tile_api.m_palettes.push(t); |
|
|
|
else |
|
|
|
data->m_tile_api.m_tiles.push(t); |
|
|
|
m_tile_api.m_tiles.push(t); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::AddLine(vec3 a, vec3 b, vec4 color) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
data->m_line_api.m_lines.push(a, b, color, -1.f, 0xFFFFFFFF, false, false); |
|
|
|
m_line_api.m_lines.push(a, b, color, -1.f, 0xFFFFFFFF, false, false); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::AddLine(vec3 a, vec3 b, vec4 color, float duration, int mask) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
data->m_line_api.m_lines.push(a, b, color, duration, mask, false, false); |
|
|
|
m_line_api.m_lines.push(a, b, color, duration, mask, false, false); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::AddLight(Light *l) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
data->m_tile_api.m_lights.push(l); |
|
|
|
m_tile_api.m_lights.push(l); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
array<Light *> const &Scene::GetLights() |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
return data->m_tile_api.m_lights; |
|
|
|
return m_tile_api.m_lights; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::SetDisplay(SceneDisplay* display) |
|
|
|
{ |
|
|
|
data->m_display = display; |
|
|
|
m_display = display; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::EnableDisplay() |
|
|
|
{ |
|
|
|
// If no display has been set, use the default one |
|
|
|
if (!data->m_display) |
|
|
|
if (!m_display) |
|
|
|
SetDisplay(SceneDisplay::GetDisplay()); |
|
|
|
data->m_display->Enable(); |
|
|
|
m_display->Enable(); |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::DisableDisplay() |
|
|
|
{ |
|
|
|
ASSERT(data->m_display); |
|
|
|
data->m_display->Disable(); |
|
|
|
ASSERT(m_display); |
|
|
|
m_display->Disable(); |
|
|
|
} |
|
|
|
|
|
|
|
static bool do_pp = true; |
|
|
@@ -577,16 +460,16 @@ void Scene::pre_render(float) |
|
|
|
{ |
|
|
|
m_size = m_wanted_size; |
|
|
|
for (int i = 0; i < 4; ++i) |
|
|
|
data->m_renderbuffer[i] = std::make_shared<Framebuffer>(m_size); |
|
|
|
m_renderbuffer[i] = std::make_shared<Framebuffer>(m_size); |
|
|
|
|
|
|
|
mat4 proj = mat4::ortho(0.f, (float)m_size.x, 0.f, (float)m_size.y, -1000.f, 1000.f); |
|
|
|
data->m_default_cam->SetProjection(proj); |
|
|
|
m_default_cam->SetProjection(proj); |
|
|
|
} |
|
|
|
|
|
|
|
/* First render into the offline buffer */ |
|
|
|
if (do_pp) |
|
|
|
{ |
|
|
|
data->m_renderbuffer[0]->Bind(); |
|
|
|
m_renderbuffer[0]->Bind(); |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
@@ -618,11 +501,11 @@ void Scene::post_render(float) |
|
|
|
|
|
|
|
if (do_pp) |
|
|
|
{ |
|
|
|
data->m_renderbuffer[0]->Unbind(); |
|
|
|
m_renderbuffer[0]->Unbind(); |
|
|
|
|
|
|
|
gpu_marker("PostProcess"); |
|
|
|
|
|
|
|
data->m_renderbuffer[3]->Bind(); |
|
|
|
m_renderbuffer[3]->Bind(); |
|
|
|
|
|
|
|
render_context rc(m_renderer); |
|
|
|
rc.clear_color(vec4(0.f, 0.f, 0.f, 1.f)); |
|
|
@@ -630,23 +513,23 @@ void Scene::post_render(float) |
|
|
|
m_renderer->Clear(ClearMask::Color | ClearMask::Depth); |
|
|
|
|
|
|
|
/* Execute post process */ |
|
|
|
data->m_pp.m_shader[1]->Bind(); |
|
|
|
data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][0], data->m_renderbuffer[0]->GetTextureUniform(), 0); |
|
|
|
data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][1], data->m_renderbuffer[1]->GetTextureUniform(), 1); |
|
|
|
data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][2], data->m_renderbuffer[2]->GetTextureUniform(), 2); |
|
|
|
data->m_pp.m_vdecl->SetStream(data->m_pp.m_vbo, data->m_pp.m_coord[1]); |
|
|
|
data->m_pp.m_vdecl->Bind(); |
|
|
|
data->m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); |
|
|
|
data->m_pp.m_vdecl->Unbind(); |
|
|
|
data->m_pp.m_shader[1]->Unbind(); |
|
|
|
data->m_renderbuffer[3]->Unbind(); |
|
|
|
m_pp.m_shader[1]->Bind(); |
|
|
|
m_pp.m_shader[1]->SetUniform(m_pp.m_buffer_uni[1][0], m_renderbuffer[0]->GetTextureUniform(), 0); |
|
|
|
m_pp.m_shader[1]->SetUniform(m_pp.m_buffer_uni[1][1], m_renderbuffer[1]->GetTextureUniform(), 1); |
|
|
|
m_pp.m_shader[1]->SetUniform(m_pp.m_buffer_uni[1][2], m_renderbuffer[2]->GetTextureUniform(), 2); |
|
|
|
m_pp.m_vdecl->SetStream(m_pp.m_vbo, m_pp.m_coord[1]); |
|
|
|
m_pp.m_vdecl->Bind(); |
|
|
|
m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); |
|
|
|
m_pp.m_vdecl->Unbind(); |
|
|
|
m_pp.m_shader[1]->Unbind(); |
|
|
|
m_renderbuffer[3]->Unbind(); |
|
|
|
} |
|
|
|
|
|
|
|
if (do_pp) |
|
|
|
{ |
|
|
|
gpu_marker("Blit frame"); |
|
|
|
|
|
|
|
data->m_pp.m_shader[0]->Bind(); |
|
|
|
m_pp.m_shader[0]->Bind(); |
|
|
|
|
|
|
|
render_context rc(m_renderer); |
|
|
|
rc.clear_color(vec4(0.f, 0.f, 0.f, 1.f)); |
|
|
@@ -654,57 +537,51 @@ void Scene::post_render(float) |
|
|
|
m_renderer->Clear(ClearMask::Color | ClearMask::Depth); |
|
|
|
|
|
|
|
/* Blit final image to screen */ |
|
|
|
data->m_pp.m_shader[0]->SetUniform(data->m_pp.m_buffer_uni[0][0], data->m_renderbuffer[3]->GetTextureUniform(), 3); |
|
|
|
data->m_pp.m_vdecl->SetStream(data->m_pp.m_vbo, data->m_pp.m_coord[0]); |
|
|
|
data->m_pp.m_vdecl->Bind(); |
|
|
|
data->m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); |
|
|
|
data->m_pp.m_vdecl->Unbind(); |
|
|
|
data->m_pp.m_shader[0]->Unbind(); |
|
|
|
m_pp.m_shader[0]->SetUniform(m_pp.m_buffer_uni[0][0], m_renderbuffer[3]->GetTextureUniform(), 3); |
|
|
|
m_pp.m_vdecl->SetStream(m_pp.m_vbo, m_pp.m_coord[0]); |
|
|
|
m_pp.m_vdecl->Bind(); |
|
|
|
m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); |
|
|
|
m_pp.m_vdecl->Unbind(); |
|
|
|
m_pp.m_shader[0]->Unbind(); |
|
|
|
} |
|
|
|
|
|
|
|
if (do_pp) |
|
|
|
{ |
|
|
|
/* Swap back buffers */ |
|
|
|
std::swap(data->m_renderbuffer[0], data->m_renderbuffer[1]); |
|
|
|
std::swap(data->m_renderbuffer[2], data->m_renderbuffer[3]); |
|
|
|
std::swap(m_renderbuffer[0], m_renderbuffer[1]); |
|
|
|
std::swap(m_renderbuffer[2], m_renderbuffer[3]); |
|
|
|
} |
|
|
|
|
|
|
|
gpu_marker("End Render"); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::render_primitives() |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
/* FIXME: Temp fix for mesh having no render context*/ |
|
|
|
render_context rc(m_renderer); |
|
|
|
rc.cull_mode(CullMode::Clockwise); |
|
|
|
rc.depth_func(DepthFunc::LessOrEqual); |
|
|
|
|
|
|
|
/* new scenegraph */ |
|
|
|
for (uintptr_t key : keys(data->m_prim_renderers)) |
|
|
|
for (uintptr_t key : keys(m_prim_renderers)) |
|
|
|
{ |
|
|
|
for (int idx = 0; idx < data->m_prim_renderers[key].count(); ++idx) |
|
|
|
for (int idx = 0; idx < m_prim_renderers[key].count(); ++idx) |
|
|
|
{ |
|
|
|
/* TODO: Not sure if thread compliant */ |
|
|
|
std::shared_ptr<PrimitiveSource> source; |
|
|
|
if (idx < SceneData::m_prim_sources[key].count()) |
|
|
|
source = SceneData::m_prim_sources[key][idx]; |
|
|
|
data->m_prim_renderers[key][idx]->Render(*this, source); |
|
|
|
if (idx < g_prim_sources[key].count()) |
|
|
|
source = g_prim_sources[key][idx]; |
|
|
|
m_prim_renderers[key][idx]->Render(*this, source); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
void Scene::render_tiles() // XXX: rename to Blit() |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
render_context rc(m_renderer); |
|
|
|
|
|
|
|
/* Early test if nothing needs to be rendered */ |
|
|
|
if (!data->m_tile_api.m_tiles.count() && !data->m_tile_api.m_palettes.count()) |
|
|
|
if (!m_tile_api.m_tiles.count() && !m_tile_api.m_palettes.count()) |
|
|
|
return; |
|
|
|
|
|
|
|
/* FIXME: we disable culling for now because we don’t have a reliable |
|
|
@@ -720,15 +597,15 @@ void Scene::render_tiles() // XXX: rename to Blit() |
|
|
|
glEnable(GL_TEXTURE_2D); |
|
|
|
#endif |
|
|
|
|
|
|
|
if (!data->m_tile_api.m_shader) |
|
|
|
data->m_tile_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_tile)); |
|
|
|
if (!data->m_tile_api.m_palette_shader && data->m_tile_api.m_palettes.count()) |
|
|
|
data->m_tile_api.m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_palette)); |
|
|
|
if (!m_tile_api.m_shader) |
|
|
|
m_tile_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_tile)); |
|
|
|
if (!m_tile_api.m_palette_shader && m_tile_api.m_palettes.count()) |
|
|
|
m_tile_api.m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_palette)); |
|
|
|
|
|
|
|
for (int p = 0; p < 2; p++) |
|
|
|
{ |
|
|
|
auto shader = (p == 0) ? data->m_tile_api.m_shader : data->m_tile_api.m_palette_shader; |
|
|
|
auto &tiles = (p == 0) ? data->m_tile_api.m_tiles : data->m_tile_api.m_palettes; |
|
|
|
auto shader = (p == 0) ? m_tile_api.m_shader : m_tile_api.m_palette_shader; |
|
|
|
auto &tiles = (p == 0) ? m_tile_api.m_tiles : m_tile_api.m_palettes; |
|
|
|
|
|
|
|
if (tiles.count() == 0) |
|
|
|
continue; |
|
|
@@ -741,14 +618,14 @@ void Scene::render_tiles() // XXX: rename to Blit() |
|
|
|
shader->Bind(); |
|
|
|
|
|
|
|
uni_mat = shader->GetUniformLocation("u_projection"); |
|
|
|
shader->SetUniform(uni_mat, GetCamera(data->m_tile_api.m_cam)->GetProjection()); |
|
|
|
shader->SetUniform(uni_mat, GetCamera(m_tile_api.m_cam)->GetProjection()); |
|
|
|
uni_mat = shader->GetUniformLocation("u_view"); |
|
|
|
shader->SetUniform(uni_mat, GetCamera(data->m_tile_api.m_cam)->GetView()); |
|
|
|
shader->SetUniform(uni_mat, GetCamera(m_tile_api.m_cam)->GetView()); |
|
|
|
uni_mat = shader->GetUniformLocation("u_model"); |
|
|
|
shader->SetUniform(uni_mat, mat4(1.f)); |
|
|
|
|
|
|
|
uni_tex = shader->GetUniformLocation("u_texture"); |
|
|
|
uni_pal = data->m_tile_api.m_palette_shader ? data->m_tile_api.m_palette_shader->GetUniformLocation("u_palette") : ShaderUniform(); |
|
|
|
uni_pal = m_tile_api.m_palette_shader ? m_tile_api.m_palette_shader->GetUniformLocation("u_palette") : ShaderUniform(); |
|
|
|
uni_texsize = shader->GetUniformLocation("u_texsize"); |
|
|
|
|
|
|
|
for (int buf = 0, i = 0, n; i < tiles.count(); i = n, buf += 2) |
|
|
@@ -764,8 +641,8 @@ void Scene::render_tiles() // XXX: rename to Blit() |
|
|
|
auto vb2 = std::make_shared<VertexBuffer>(6 * (n - i) * sizeof(vec2)); |
|
|
|
vec2 *texture = (vec2 *)vb2->Lock(0, 0); |
|
|
|
|
|
|
|
data->m_tile_api.m_bufs.push(vb1); |
|
|
|
data->m_tile_api.m_bufs.push(vb2); |
|
|
|
m_tile_api.m_bufs.push(vb1); |
|
|
|
m_tile_api.m_bufs.push(vb2); |
|
|
|
|
|
|
|
for (int j = i; j < n; j++) |
|
|
|
{ |
|
|
@@ -795,13 +672,13 @@ void Scene::render_tiles() // XXX: rename to Blit() |
|
|
|
(vec2)tiles[i].m_tileset->GetTextureSize()); |
|
|
|
|
|
|
|
/* Bind vertex and texture coordinate buffers */ |
|
|
|
data->m_tile_api.m_vdecl->Bind(); |
|
|
|
data->m_tile_api.m_vdecl->SetStream(vb1, attr_pos); |
|
|
|
data->m_tile_api.m_vdecl->SetStream(vb2, attr_tex); |
|
|
|
m_tile_api.m_vdecl->Bind(); |
|
|
|
m_tile_api.m_vdecl->SetStream(vb1, attr_pos); |
|
|
|
m_tile_api.m_vdecl->SetStream(vb2, attr_tex); |
|
|
|
|
|
|
|
/* Draw arrays */ |
|
|
|
data->m_tile_api.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); |
|
|
|
data->m_tile_api.m_vdecl->Unbind(); |
|
|
|
m_tile_api.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); |
|
|
|
m_tile_api.m_vdecl->Unbind(); |
|
|
|
tiles[i].m_tileset->Unbind(); |
|
|
|
} |
|
|
|
|
|
|
@@ -809,7 +686,7 @@ void Scene::render_tiles() // XXX: rename to Blit() |
|
|
|
|
|
|
|
shader->Unbind(); |
|
|
|
|
|
|
|
if (!data->m_tile_api.m_palette_shader) |
|
|
|
if (!m_tile_api.m_palette_shader) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@@ -818,16 +695,13 @@ void Scene::render_tiles() // XXX: rename to Blit() |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
// FIXME: get rid of the delta time argument |
|
|
|
// XXX: rename to Blit() |
|
|
|
void Scene::render_lines(float seconds) |
|
|
|
{ |
|
|
|
ASSERT(!!data, "Trying to access a non-ready scene"); |
|
|
|
|
|
|
|
render_context rc(m_renderer); |
|
|
|
|
|
|
|
if (!data->m_line_api.m_lines.count()) |
|
|
|
if (!m_line_api.m_lines.count()) |
|
|
|
return; |
|
|
|
|
|
|
|
rc.depth_func(DepthFunc::LessOrEqual); |
|
|
@@ -835,10 +709,10 @@ void Scene::render_lines(float seconds) |
|
|
|
rc.blend_equation(BlendEquation::Add, BlendEquation::Max); |
|
|
|
rc.alpha_func(AlphaFunc::GreaterOrEqual, 0.01f); |
|
|
|
|
|
|
|
int linecount = (int)data->m_line_api.m_lines.count(); |
|
|
|
int linecount = (int)m_line_api.m_lines.count(); |
|
|
|
|
|
|
|
if (!data->m_line_api.m_shader) |
|
|
|
data->m_line_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_line)); |
|
|
|
if (!m_line_api.m_shader) |
|
|
|
m_line_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_line)); |
|
|
|
|
|
|
|
array<vec4, vec4, vec4, vec4> buff; |
|
|
|
buff.resize(linecount); |
|
|
@@ -846,18 +720,18 @@ void Scene::render_lines(float seconds) |
|
|
|
mat4 const inv_view_proj = inverse(GetCamera()->GetProjection() * GetCamera()->GetView()); |
|
|
|
for (int i = 0; i < linecount; i++) |
|
|
|
{ |
|
|
|
if (data->m_line_api.m_lines[i].m5 & data->m_line_api.m_debug_mask) |
|
|
|
if (m_line_api.m_lines[i].m5 & m_line_api.m_debug_mask) |
|
|
|
{ |
|
|
|
buff[real_linecount].m1 = vec4(data->m_line_api.m_lines[i].m1, (float)data->m_line_api.m_lines[i].m6); |
|
|
|
buff[real_linecount].m2 = data->m_line_api.m_lines[i].m3; |
|
|
|
buff[real_linecount].m3 = vec4(data->m_line_api.m_lines[i].m2, (float)data->m_line_api.m_lines[i].m7); |
|
|
|
buff[real_linecount].m4 = data->m_line_api.m_lines[i].m3; |
|
|
|
buff[real_linecount].m1 = vec4(m_line_api.m_lines[i].m1, (float)m_line_api.m_lines[i].m6); |
|
|
|
buff[real_linecount].m2 = m_line_api.m_lines[i].m3; |
|
|
|
buff[real_linecount].m3 = vec4(m_line_api.m_lines[i].m2, (float)m_line_api.m_lines[i].m7); |
|
|
|
buff[real_linecount].m4 = m_line_api.m_lines[i].m3; |
|
|
|
real_linecount++; |
|
|
|
} |
|
|
|
data->m_line_api.m_lines[i].m4 -= seconds; |
|
|
|
if (data->m_line_api.m_lines[i].m4 < 0.f) |
|
|
|
m_line_api.m_lines[i].m4 -= seconds; |
|
|
|
if (m_line_api.m_lines[i].m4 < 0.f) |
|
|
|
{ |
|
|
|
data->m_line_api.m_lines.remove_swap(i--); |
|
|
|
m_line_api.m_lines.remove_swap(i--); |
|
|
|
linecount--; |
|
|
|
} |
|
|
|
} |
|
|
@@ -866,27 +740,27 @@ void Scene::render_lines(float seconds) |
|
|
|
memcpy(vertex, buff.data(), buff.bytes()); |
|
|
|
vb->Unlock(); |
|
|
|
|
|
|
|
data->m_line_api.m_shader->Bind(); |
|
|
|
m_line_api.m_shader->Bind(); |
|
|
|
|
|
|
|
ShaderUniform uni_mat, uni_tex; |
|
|
|
ShaderAttrib attr_pos, attr_col; |
|
|
|
attr_pos = data->m_line_api.m_shader->GetAttribLocation(VertexUsage::Position, 0); |
|
|
|
attr_col = data->m_line_api.m_shader->GetAttribLocation(VertexUsage::Color, 0); |
|
|
|
attr_pos = m_line_api.m_shader->GetAttribLocation(VertexUsage::Position, 0); |
|
|
|
attr_col = m_line_api.m_shader->GetAttribLocation(VertexUsage::Color, 0); |
|
|
|
|
|
|
|
data->m_line_api.m_shader->Bind(); |
|
|
|
m_line_api.m_shader->Bind(); |
|
|
|
|
|
|
|
uni_mat = data->m_line_api.m_shader->GetUniformLocation("u_projection"); |
|
|
|
data->m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); |
|
|
|
uni_mat = data->m_line_api.m_shader->GetUniformLocation("u_view"); |
|
|
|
data->m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetView()); |
|
|
|
uni_mat = m_line_api.m_shader->GetUniformLocation("u_projection"); |
|
|
|
m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); |
|
|
|
uni_mat = m_line_api.m_shader->GetUniformLocation("u_view"); |
|
|
|
m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetView()); |
|
|
|
|
|
|
|
data->m_line_api.m_vdecl->Bind(); |
|
|
|
data->m_line_api.m_vdecl->SetStream(vb, attr_pos, attr_col); |
|
|
|
data->m_line_api.m_vdecl->DrawElements(MeshPrimitive::Lines, 0, 2 * real_linecount); |
|
|
|
data->m_line_api.m_vdecl->Unbind(); |
|
|
|
data->m_line_api.m_shader->Unbind(); |
|
|
|
m_line_api.m_vdecl->Bind(); |
|
|
|
m_line_api.m_vdecl->SetStream(vb, attr_pos, attr_col); |
|
|
|
m_line_api.m_vdecl->DrawElements(MeshPrimitive::Lines, 0, 2 * real_linecount); |
|
|
|
m_line_api.m_vdecl->Unbind(); |
|
|
|
m_line_api.m_shader->Unbind(); |
|
|
|
|
|
|
|
//data->m_line_api.m_lines.clear(); |
|
|
|
//m_line_api.m_lines.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
} /* namespace lol */ |
|
|
|