diff --git a/doc/tutorial/02_cube.cpp b/doc/tutorial/02_cube.cpp index 1ad431f5..39e2822c 100644 --- a/doc/tutorial/02_cube.cpp +++ b/doc/tutorial/02_cube.cpp @@ -25,23 +25,6 @@ class Cube : public WorldEntity { public: Cube() - : m_angle(0), - m_mesh({ /* Front vertices/colors */ - { vec3(-1.0, -1.0, 1.0), vec3(1.0, 0.0, 1.0) }, - { vec3( 1.0, -1.0, 1.0), vec3(0.0, 1.0, 0.0) }, - { vec3( 1.0, 1.0, 1.0), vec3(1.0, 0.5, 0.0) }, - { vec3(-1.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0) }, - /* Back */ - { vec3(-1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0) }, - { vec3( 1.0, -1.0, -1.0), vec3(0.0, 0.5, 0.0) }, - { vec3( 1.0, 1.0, -1.0), vec3(0.0, 0.5, 1.0) }, - { vec3(-1.0, 1.0, -1.0), vec3(0.0, 0.0, 1.0) } }), - m_lines_indices({ 0, 1, 1, 2, 2, 3, 3, 0, - 4, 5, 5, 6, 6, 7, 7, 4, - 0, 4, 1, 5, 2, 6, 3, 7, }), - m_faces_indices({ 0, 1, 2, 2, 3, 0, 1, 5, 6, 6, 2, 1, - 7, 6, 5, 5, 4, 7, 4, 0, 3, 3, 7, 4, - 4, 5, 1, 1, 0, 4, 3, 2, 6, 6, 7, 3, }) { m_camera = new Camera(); m_camera->SetProjection(mat4::perspective(radians(30.f), 640.f, 480.f, .1f, 1000.f)); @@ -62,6 +45,34 @@ public: virtual bool init_draw() override { + array mesh + { + // Front vertices/colors + { vec3(-1.0, -1.0, 1.0), vec3(1.0, 0.0, 1.0) }, + { vec3( 1.0, -1.0, 1.0), vec3(0.0, 1.0, 0.0) }, + { vec3( 1.0, 1.0, 1.0), vec3(1.0, 0.5, 0.0) }, + { vec3(-1.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0) }, + // Back + { vec3(-1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0) }, + { vec3( 1.0, -1.0, -1.0), vec3(0.0, 0.5, 0.0) }, + { vec3( 1.0, 1.0, -1.0), vec3(0.0, 0.5, 1.0) }, + { vec3(-1.0, 1.0, -1.0), vec3(0.0, 0.0, 1.0) }, + }; + + array lines_indices + { + 0, 1, 1, 2, 2, 3, 3, 0, + 4, 5, 5, 6, 6, 7, 7, 4, + 0, 4, 1, 5, 2, 6, 3, 7, + }; + + array faces_indices + { + 0, 1, 2, 2, 3, 0, 1, 5, 6, 6, 2, 1, + 7, 6, 5, 5, 4, 7, 4, 0, 3, 3, 7, 4, + 4, 5, 1, 1, 0, 4, 3, 2, 6, 6, 7, 3, + }; + m_shader = Shader::Create(LOLFX_RESOURCE_NAME(02_cube)); m_mvp = m_shader->GetUniformLocation("u_matrix"); @@ -72,19 +83,19 @@ public: VertexStream(VertexUsage::Position, VertexUsage::Color)); - m_vbo = std::make_shared(m_mesh.bytes()); - void *mesh = m_vbo->Lock(0, 0); - memcpy(mesh, m_mesh.data(), m_mesh.bytes()); + m_vbo = std::make_shared(mesh.bytes()); + void *data = m_vbo->Lock(0, 0); + memcpy(data, mesh.data(), mesh.bytes()); m_vbo->Unlock(); - m_lines_ibo = std::make_shared(m_lines_indices.bytes()); - void *indices = m_lines_ibo->Lock(0, 0); - memcpy(indices, m_lines_indices.data(), m_lines_indices.bytes()); + m_lines_ibo = std::make_shared(lines_indices.bytes()); + data = m_lines_ibo->Lock(0, 0); + memcpy(data, lines_indices.data(), lines_indices.bytes()); m_lines_ibo->Unlock(); - m_faces_ibo = std::make_shared(m_faces_indices.bytes()); - indices = m_faces_ibo->Lock(0, 0); - memcpy(indices, m_faces_indices.data(), m_faces_indices.bytes()); + m_faces_ibo = std::make_shared(faces_indices.bytes()); + data = m_faces_ibo->Lock(0, 0); + memcpy(data, faces_indices.data(), faces_indices.bytes()); m_faces_ibo->Unlock(); return true; @@ -135,12 +146,12 @@ public: m_shader->SetUniform(m_mvp, m_matrix); m_lines_ibo->Bind(); - m_vdecl->DrawIndexedElements(MeshPrimitive::Lines, m_lines_indices.count()); + m_vdecl->DrawIndexedElements(MeshPrimitive::Lines, m_lines_ibo->GetSize() / sizeof(uint16_t)); m_lines_ibo->Unbind(); m_shader->SetUniform(m_mvp, m_matrix * mat4::scale(0.5f)); m_faces_ibo->Bind(); - m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, m_faces_indices.count()); + m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, m_faces_ibo->GetSize() / sizeof(uint16_t)); m_faces_ibo->Unbind(); m_vdecl->Unbind(); @@ -158,10 +169,8 @@ public: private: Camera* m_camera = nullptr; - float m_angle; + float m_angle = 0.0f; mat4 m_matrix; - array m_mesh; - array m_lines_indices, m_faces_indices; std::shared_ptr m_shader; ShaderAttrib m_coord, m_color; diff --git a/doc/tutorial/04_texture.cpp b/doc/tutorial/04_texture.cpp index c5da5c84..34accf58 100644 --- a/doc/tutorial/04_texture.cpp +++ b/doc/tutorial/04_texture.cpp @@ -26,19 +26,19 @@ LOLFX_RESOURCE_DECLARE(04_texture); class TextureDemo : public WorldEntity { public: - TextureDemo() + virtual bool init_game() override { + /* Generate a new heightmap at the beginning */ m_heightmap.resize(TEXTURE_WIDTH * 1); + memset(m_heightmap.data(), 255, m_heightmap.bytes()); + + return true; } virtual void tick_game(float seconds) override { WorldEntity::tick_game(seconds); - /* Generate a new heightmap at the beginning */ - if (m_frames == 0) - memset(m_heightmap.data(), 255, m_heightmap.bytes()); - /* Scroll left */ for (int i = 0; i < m_heightmap.count() - 1; i++) m_heightmap[i] = m_heightmap[i + 1]; diff --git a/doc/tutorial/05_easymesh.cpp b/doc/tutorial/05_easymesh.cpp index e85c315c..5e68bfd2 100644 --- a/doc/tutorial/05_easymesh.cpp +++ b/doc/tutorial/05_easymesh.cpp @@ -65,8 +65,6 @@ public: 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& scene = Scene::GetScene(); - scene.PushCamera(m_camera); /* Add a white directional light */ m_light1 = new Light(); @@ -81,14 +79,10 @@ public: m_light2->SetColor(vec4(0.4f, 0.3f, 0.2f, 1.f)); m_light2->SetType(LightType::Point); Ticker::Ref(m_light2); - - m_ready = false; } ~EasyMeshTutorial() { - Scene& scene = Scene::GetScene(); - scene.PopCamera(m_camera); Ticker::Unref(m_light1); Ticker::Unref(m_light2); } @@ -123,34 +117,42 @@ public: * mat4::rotate(m_gears[4].m3 - 80.0f, vec3(0, 1, 0)); } - virtual void tick_draw(float seconds, Scene &scene) + virtual bool init_draw() override { - WorldEntity::tick_draw(seconds, scene); - - if (!m_ready) - { - scene.get_renderer()->SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f)); + Scene& scene = Scene::GetScene(); + scene.PushCamera(m_camera); + scene.get_renderer()->SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f)); - /* Upload vertex data to GPU */ - for (int i = 0; i < m_gears.count(); i++) - m_gears[i].m1.MeshConvert(); + /* Upload vertex data to GPU */ + for (int i = 0; i < m_gears.count(); i++) + m_gears[i].m1.MeshConvert(); #if USE_CUSTOM_SHADER - /* Custom Shader: Init the shader */ - auto custom_shader = Shader::Create(LOLFX_RESOURCE_NAME(easymesh_shiny)); - // any other shader stuf here (Get uniform, mostly, and set texture) + /* Custom Shader: Init the shader */ + auto custom_shader = Shader::Create(LOLFX_RESOURCE_NAME(easymesh_shiny)); + // any other shader stuf here (Get uniform, mostly, and set texture) - for (int i = 0; i < m_gears.count(); i++) - m_gears[i].m1.SetMaterial(custom_shader); + for (int i = 0; i < m_gears.count(); i++) + m_gears[i].m1.SetMaterial(custom_shader); #endif - m_ready = true; - } + return true; + } + + virtual void tick_draw(float seconds, Scene &scene) override + { + WorldEntity::tick_draw(seconds, scene); for (int i = 0; i < m_gears.count(); i++) - { m_gears[i].m1.Render(scene, m_mat * m_gears[i].m2); - } + } + + virtual bool release_draw() override + { + Scene& scene = Scene::GetScene(); + scene.PopCamera(m_camera); + m_gears.resize(0); + return true; } private: @@ -159,8 +161,6 @@ private: mat4 m_mat; Camera *m_camera; Light *m_light1, *m_light2; - - bool m_ready; }; int main(int argc, char **argv) diff --git a/doc/tutorial/06_sprite.cpp b/doc/tutorial/06_sprite.cpp index c843a42d..7c2d32f6 100644 --- a/doc/tutorial/06_sprite.cpp +++ b/doc/tutorial/06_sprite.cpp @@ -27,8 +27,6 @@ public: m_camera = new Camera(); m_camera->SetView(mat4(1.f)); m_camera->SetProjection(mat4::ortho(0.f, 640.f, 0.f, 480.f, -100.f, 100.f)); - Scene& scene = Scene::GetScene(); - scene.PushCamera(m_camera); Ticker::Ref(m_camera); m_tileset = TileSet::create("06_sprite.png"); @@ -40,16 +38,11 @@ public: m_sprites.push(vec3((float)rand(-96, 640), (float)rand(-96, 480), 0.f), rand(0.f, 1.f)); } - - m_ready = false; } ~SpriteTutorial() { TileSet::destroy(m_tileset); - - Scene& scene = Scene::GetScene(); - scene.PopCamera(m_camera); Ticker::Unref(m_camera); } @@ -66,15 +59,17 @@ public: WorldEntity::tick_game(seconds); } - virtual void tick_draw(float seconds, Scene &scene) + virtual bool init_draw() override { - WorldEntity::tick_draw(seconds, scene); + Scene& scene = Scene::GetScene(); + scene.PushCamera(m_camera); + scene.get_renderer()->SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f)); + return true; + } - if (!m_ready) - { - scene.get_renderer()->SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f)); - m_ready = true; - } + virtual void tick_draw(float seconds, Scene &scene) override + { + WorldEntity::tick_draw(seconds, scene); for (int i = 0; i < SPRITE_COUNT; ++i) { @@ -85,6 +80,13 @@ public: } } + virtual bool release_draw() override + { + Scene& scene = Scene::GetScene(); + scene.PopCamera(m_camera); + return true; + } + private: Camera *m_camera; TileSet *m_tileset; @@ -92,8 +94,6 @@ private: static int const SPRITE_COUNT = 192; static int const FRAME_COUNT = 16; array m_sprites; - - bool m_ready; }; int main(int argc, char **argv) diff --git a/doc/tutorial/07_input.cpp b/doc/tutorial/07_input.cpp index 6316eb08..fa0f7e98 100644 --- a/doc/tutorial/07_input.cpp +++ b/doc/tutorial/07_input.cpp @@ -30,28 +30,6 @@ public: m_yaw_angle = 0; m_autorot = true; - /* Front vertices/colors */ - m_mesh.push(vec3(-1.0, -1.0, 1.0), vec3(1.0, 0.0, 1.0)); - m_mesh.push(vec3( 1.0, -1.0, 1.0), vec3(0.0, 1.0, 0.0)); - m_mesh.push(vec3( 1.0, 1.0, 1.0), vec3(1.0, 0.5, 0.0)); - m_mesh.push(vec3(-1.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0)); - /* Back */ - m_mesh.push(vec3(-1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0)); - m_mesh.push(vec3( 1.0, -1.0, -1.0), vec3(0.0, 0.5, 0.0)); - m_mesh.push(vec3( 1.0, 1.0, -1.0), vec3(0.0, 0.5, 1.0)); - m_mesh.push(vec3(-1.0, 1.0, -1.0), vec3(0.0, 0.0, 1.0)); - - m_faces_indices << 0 << 1 << 2 << 2 << 3 << 0; - m_faces_indices << 1 << 5 << 6 << 6 << 2 << 1; - m_faces_indices << 7 << 6 << 5 << 5 << 4 << 7; - m_faces_indices << 4 << 0 << 3 << 3 << 7 << 4; - m_faces_indices << 4 << 5 << 1 << 1 << 0 << 4; - m_faces_indices << 3 << 2 << 6 << 6 << 7 << 3; - - m_lines_indices << 0 << 1 << 1 << 2 << 2 << 3 << 3 << 0; - m_lines_indices << 4 << 5 << 5 << 6 << 6 << 7 << 7 << 4; - m_lines_indices << 0 << 4 << 1 << 5 << 2 << 6 << 3 << 7; - m_text = new Text("", "data/font/ascii.png"); m_text->SetPos(vec3(5, 30, 1)); Ticker::Ref(m_text); @@ -124,6 +102,34 @@ public: virtual bool init_draw() override { + array mesh + { + // Front vertices/colors + { vec3(-1.0, -1.0, 1.0), vec3(1.0, 0.0, 1.0) }, + { vec3( 1.0, -1.0, 1.0), vec3(0.0, 1.0, 0.0) }, + { vec3( 1.0, 1.0, 1.0), vec3(1.0, 0.5, 0.0) }, + { vec3(-1.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0) }, + // Back + { vec3(-1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0) }, + { vec3( 1.0, -1.0, -1.0), vec3(0.0, 0.5, 0.0) }, + { vec3( 1.0, 1.0, -1.0), vec3(0.0, 0.5, 1.0) }, + { vec3(-1.0, 1.0, -1.0), vec3(0.0, 0.0, 1.0) }, + }; + + array faces_indices + { + 0, 1, 2, 2, 3, 0, 1, 5, 6, 6, 2, 1, + 7, 6, 5, 5, 4, 7, 4, 0, 3, 3, 7, 4, + 4, 5, 1, 1, 0, 4, 3, 2, 6, 6, 7, 3, + }; + + array lines_indices + { + 0, 1, 1, 2, 2, 3, 3, 0, + 4, 5, 5, 6, 6, 7, 7, 4, + 0, 4, 1, 5, 2, 6, 3, 7, + }; + m_shader = Shader::Create(LOLFX_RESOURCE_NAME(07_input)); m_mvp = m_shader->GetUniformLocation("u_matrix"); @@ -134,19 +140,19 @@ public: VertexStream(VertexUsage::Position, VertexUsage::Color)); - m_vbo = std::make_shared(m_mesh.bytes()); - void *mesh = m_vbo->Lock(0, 0); - memcpy(mesh, &m_mesh[0], m_mesh.bytes()); + m_vbo = std::make_shared(mesh.bytes()); + void *data = m_vbo->Lock(0, 0); + memcpy(data, mesh.data(), mesh.bytes()); m_vbo->Unlock(); - m_lines_ibo = std::make_shared(m_lines_indices.bytes()); - void *indices = m_lines_ibo->Lock(0, 0); - memcpy(indices, &m_lines_indices[0], m_lines_indices.bytes()); + m_lines_ibo = std::make_shared(lines_indices.bytes()); + data = m_lines_ibo->Lock(0, 0); + memcpy(data, lines_indices.data(), lines_indices.bytes()); m_lines_ibo->Unlock(); - m_faces_ibo = std::make_shared(m_faces_indices.bytes()); - indices = m_faces_ibo->Lock(0, 0); - memcpy(indices, &m_faces_indices[0], m_faces_indices.bytes()); + m_faces_ibo = std::make_shared(faces_indices.bytes()); + data = m_faces_ibo->Lock(0, 0); + memcpy(data, faces_indices.data(), faces_indices.bytes()); m_faces_ibo->Unlock(); return WorldEntity::init_draw(); @@ -164,12 +170,12 @@ public: m_shader->SetUniform(m_mvp, m_matrix); m_lines_ibo->Bind(); - m_vdecl->DrawIndexedElements(MeshPrimitive::Lines, m_lines_indices.count()); + m_vdecl->DrawIndexedElements(MeshPrimitive::Lines, m_lines_ibo->GetSize() / sizeof(uint16_t)); m_lines_ibo->Unbind(); m_shader->SetUniform(m_mvp, m_matrix * mat4::scale(0.5f)); m_faces_ibo->Bind(); - m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, m_faces_indices.count()); + m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, m_faces_ibo->GetSize() / sizeof(uint16_t)); m_faces_ibo->Unbind(); m_vdecl->Unbind(); @@ -190,8 +196,6 @@ private: float m_pitch_angle; float m_yaw_angle; mat4 m_matrix; - array m_mesh; - array m_lines_indices, m_faces_indices; std::shared_ptr m_shader; ShaderAttrib m_coord, m_color; diff --git a/doc/tutorial/08_fbo.cpp b/doc/tutorial/08_fbo.cpp index 96b6ced1..7e27b597 100644 --- a/doc/tutorial/08_fbo.cpp +++ b/doc/tutorial/08_fbo.cpp @@ -69,16 +69,9 @@ public: m_vbo->Unlock(); m_fbo = std::make_shared(Video::GetSize()); - return true; - } - - virtual void tick_draw(float seconds, Scene &scene) override - { - WorldEntity::tick_draw(seconds, scene); - - // FIXME: this should only be done once! m_fbo->Bind(); { + Scene& scene = Scene::GetScene(); render_context rc(scene.get_renderer()); rc.clear_color(vec4(0.f, 0.f, 0.f, 1.f)); rc.clear_depth(1.f); @@ -86,6 +79,13 @@ public: } m_fbo->Unbind(); + return true; + } + + virtual void tick_draw(float seconds, Scene &scene) override + { + WorldEntity::tick_draw(seconds, scene); + /* FIXME: we should just disable depth test in the shader */ render_context rc(scene.get_renderer()); rc.depth_func(DepthFunc::Disabled); @@ -140,10 +140,9 @@ int main(int argc, char **argv) sys::init(argc, argv); Application app("Tutorial 08: Framebuffer Object", ivec2(512, 512), 60.0f); - new FBO(); - app.Run(); + return EXIT_SUCCESS; } diff --git a/doc/tutorial/09_sound.cpp b/doc/tutorial/09_sound.cpp index 4f9c1fff..4eb59de3 100644 --- a/doc/tutorial/09_sound.cpp +++ b/doc/tutorial/09_sound.cpp @@ -1,7 +1,7 @@ // // Lol Engine — Sound tutorial // -// Copyright © 2011—2016 Sam Hocevar +// Copyright © 2011—2019 Sam Hocevar // // Lol Engine is free software. It comes without any warranty, to // the extent permitted by applicable law. You can redistribute it @@ -47,7 +47,7 @@ public: switch (mode) { case 0: // sine wave - stream[i] = 400 * lol::sin(12 * i * F_TAU / bytes); + stream[i] = 400 * lol::sin(8 * i * F_TAU / bytes); break; case 1: // white noise stream[i] = lol::rand(-120, 120); @@ -56,7 +56,7 @@ public: } } - virtual void tick_game(float seconds) + virtual void tick_game(float seconds) override { WorldEntity::tick_game(seconds); @@ -85,7 +85,7 @@ public: } } - virtual void tick_draw(float seconds, Scene &scene) + virtual void tick_draw(float seconds, Scene &scene) override { WorldEntity::tick_draw(seconds, scene); } diff --git a/doc/tutorial/11_fractal.cpp b/doc/tutorial/11_fractal.cpp index e3c13ab1..1a23321b 100644 --- a/doc/tutorial/11_fractal.cpp +++ b/doc/tutorial/11_fractal.cpp @@ -31,7 +31,6 @@ class Fractal : public WorldEntity { public: Fractal(ivec2 const &size) - : m_julia(false) { /* Ensure texture size is a multiple of 16 for better aligned * data access. Store the dimensions of a texel for our shader, @@ -54,8 +53,6 @@ public: m_oldmouse = ivec2(0, 0); m_pixels.resize(m_size.x * m_size.y); - m_frame = -1; - m_slices = 4; for (int i = 0; i < 4; i++) { m_deltashift[i] = real("0"); @@ -66,8 +63,6 @@ public: m_zoom_speed = 0.0; m_view.translate = rcmplx(0.0, 0.0); m_view.radius = 5.0; - m_ready = false; - m_drag = false; for (int i = 0; i < (MAX_ITERATIONS + 1) * PALETTE_STEP; i++) { @@ -337,7 +332,7 @@ public: int jmax = jmin + MAX_LINES * 2; if (jmax > m_size.y) jmax = m_size.y; - u8vec4 *pixelstart = &m_pixels[0] + u8vec4 *pixelstart = m_pixels.data() + m_size.x * (m_size.y / 4 * m_frame + line / 4); #if USE_REAL @@ -429,11 +424,9 @@ public: } } - virtual void tick_draw(float seconds, Scene &scene) + virtual bool init_draw() override { - WorldEntity::tick_draw(seconds, scene); - - static float const vertices[] = + float const vertices[] = { 1.0f, 1.0f, -1.0f, 1.0f, @@ -443,7 +436,7 @@ public: 1.0f, 1.0f, }; - static float const texcoords[] = + float const texcoords[] = { 1.0f, 1.0f, 0.0f, 1.0f, @@ -453,43 +446,44 @@ public: 1.0f, 1.0f, }; - if (!m_ready) - { - /* Create a texture of half the width and twice the height - * so that we can upload four different subimages each frame. */ - m_texture = std::make_shared(ivec2(m_size.x / 2, m_size.y * 2), - PixelFormat::RGBA_8); - - /* Ensure the texture data is complete at least once, otherwise - * uploading subimages will not work. */ - m_texture->SetData(&m_pixels[0]); - - m_shader = Shader::Create(LOLFX_RESOURCE_NAME(11_fractal)); - - m_vertexattrib = m_shader->GetAttribLocation(VertexUsage::Position, 0); - m_texattrib = m_shader->GetAttribLocation(VertexUsage::TexCoord, 0); - m_texuni = m_shader->GetUniformLocation("u_texture"); - m_texeluni = m_shader->GetUniformLocation("u_texel_size"); - m_screenuni = m_shader->GetUniformLocation("u_screen_size"); - m_zoomuni = m_shader->GetUniformLocation("u_zoom_settings"); - - m_vdecl = std::make_shared( - VertexStream(VertexUsage::Position), - VertexStream(VertexUsage::TexCoord)); - m_vbo = std::make_shared(sizeof(vertices)); - m_tbo = std::make_shared(sizeof(texcoords)); - - void *tmp = m_vbo->Lock(0, 0); - memcpy(tmp, vertices, sizeof(vertices)); - m_vbo->Unlock(); - - tmp = m_tbo->Lock(0, 0); - memcpy(tmp, texcoords, sizeof(texcoords)); - m_tbo->Unlock(); - - /* FIXME: this object never cleans up */ - m_ready = true; - } + /* Create a texture of half the width and twice the height + * so that we can upload four different subimages each frame. */ + m_texture = std::make_shared(ivec2(m_size.x / 2, m_size.y * 2), + PixelFormat::RGBA_8); + + /* Ensure the texture data is complete at least once, otherwise + * uploading subimages will not work. */ + m_texture->SetData(m_pixels.data()); + + m_shader = Shader::Create(LOLFX_RESOURCE_NAME(11_fractal)); + + m_vertexattrib = m_shader->GetAttribLocation(VertexUsage::Position, 0); + m_texattrib = m_shader->GetAttribLocation(VertexUsage::TexCoord, 0); + m_texuni = m_shader->GetUniformLocation("u_texture"); + m_texeluni = m_shader->GetUniformLocation("u_texel_size"); + m_screenuni = m_shader->GetUniformLocation("u_screen_size"); + m_zoomuni = m_shader->GetUniformLocation("u_zoom_settings"); + + m_vdecl = std::make_shared( + VertexStream(VertexUsage::Position), + VertexStream(VertexUsage::TexCoord)); + m_vbo = std::make_shared(sizeof(vertices)); + m_tbo = std::make_shared(sizeof(texcoords)); + + void *data = m_vbo->Lock(0, 0); + memcpy(data, vertices, sizeof(vertices)); + m_vbo->Unlock(); + + data = m_tbo->Lock(0, 0); + memcpy(data, texcoords, sizeof(texcoords)); + m_tbo->Unlock(); + + return true; + } + + virtual void tick_draw(float seconds, Scene &scene) override + { + WorldEntity::tick_draw(seconds, scene); m_texture->Bind(); @@ -520,6 +514,16 @@ public: m_vdecl->Unbind(); } + virtual bool release_draw() override + { + m_shader.reset(); + m_vdecl.reset(); + m_vbo.reset(); + m_tbo.reset(); + m_texture.reset(); + return true; + } + private: static int const MAX_ITERATIONS = 400; static int const PALETTE_STEP = 32; @@ -542,8 +546,8 @@ private: std::shared_ptr m_vbo, m_tbo; std::shared_ptr m_texture; - int m_frame, m_slices, m_dirty[4]; - bool m_ready, m_drag; + int m_frame = -1, m_slices = 4, m_dirty[4]; + bool m_drag = false; struct view_settings { @@ -556,7 +560,7 @@ private: rcmplx m_deltashift[4]; real m_deltascale[4]; double m_zoom_speed; - bool m_julia; + bool m_julia = false; vec4 m_texel_settings, m_screen_settings; mat4 m_zoom_settings;