Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Le video Take 2 #22

Open
wants to merge 7 commits into
base: wip
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ apps/examples/hello_world/resources/images/earth_clouds.jpg
apps/examples/hello_world/resources/images/images.tar.gz
apps/examples/hello_world/resources/images/white.tga
apps/examples/hello_world/resources/images/world_winter.jpg
.idea/
cmake-build-*
1 change: 1 addition & 0 deletions apps/examples/hello_video/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resources/test.mp4
47 changes: 47 additions & 0 deletions apps/examples/hello_video/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
cmake_minimum_required(VERSION 3.7.2)
set(CMAKE_CXX_STANDARD 17)

add_compile_definitions(DEBUG_GENERATE_DOT_GRAPH=false)

set(PROJECT_NAME "Island-HelloVideo")

# Set global property (all targets are impacted)
# set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time")
# set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CMAKE_COMMAND} -E time")

project(${PROJECT_NAME})

# set to number of worker threads if you wish to use multi-threaded rendering
# add_compile_definitions( LE_MT=4 )

# Vulkan Validation layers are enabled by default for Debug builds.
# Uncomment the next line to disable loading Vulkan Validation Layers.
# add_compile_definitions( SHOULD_USE_VALIDATION_LAYERS=false )

# Point this to the base directory of your Island installation
set(ISLAND_BASE_DIR "${PROJECT_SOURCE_DIR}/../../../")

# Select which standard Island modules to use
set(REQUIRES_ISLAND_LOADER ON)
set(REQUIRES_ISLAND_CORE ON)

# Loads Island framework, based on selected Island modules from above
include("${ISLAND_BASE_DIR}CMakeLists.txt.island_prolog.in")

# Add application module, and (optional) any other private
# island modules which should not be part of the shared framework.
add_subdirectory(hello_video_app)

# Specify any optional modules from the standard framework here
add_island_module(le_video)

# Main application c++ file. Not much to see there,
set(SOURCES main.cpp)

# Sets up Island framework linkage and housekeeping, based on user selections
include("${ISLAND_BASE_DIR}CMakeLists.txt.island_epilog.in")

# (optional) create a link to local resources
link_resources(${PROJECT_SOURCE_DIR}/resources ${CMAKE_BINARY_DIR}/local_resources)

source_group(${PROJECT_NAME} FILES ${SOURCES})
5 changes: 5 additions & 0 deletions apps/examples/hello_video/download_assets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

pushd resources
curl -L https://test-videos.co.uk/vids/jellyfish/mp4/h264/1080/Jellyfish_1080_10s_20MB.mp4 -o test.mp4
popd
27 changes: 27 additions & 0 deletions apps/examples/hello_video/hello_video_app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
set (TARGET hello_video_app)

set (SOURCES "hello_video_app.cpp")
set (SOURCES ${SOURCES} "hello_video_app.h")

if (${PLUGINS_DYNAMIC})

add_library(${TARGET} SHARED ${SOURCES})


add_dynamic_linker_flags()

target_compile_definitions(${TARGET} PUBLIC "PLUGINS_DYNAMIC")

else()

# Adding a static library means to also add a linker dependency for our target
# to the library.
set (STATIC_LIBS ${STATIC_LIBS} ${TARGET} PARENT_SCOPE)

add_library(${TARGET} STATIC ${SOURCES})

endif()

target_link_libraries(${TARGET} PUBLIC ${LINKER_FLAGS})

source_group(${TARGET} FILES ${SOURCES})
192 changes: 192 additions & 0 deletions apps/examples/hello_video/hello_video_app/hello_video_app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#include "hello_video_app.h"

#include "le_window/le_window.h"
#include "le_renderer/le_renderer.h"
#include "le_pipeline_builder/le_pipeline_builder.h"
#include "le_ui_event/le_ui_event.h"
#include "le_video/le_video.h"
#include "le_resource_manager/le_resource_manager.h"
#include "le_log/le_log.h"

#define GLM_FORCE_DEPTH_ZERO_TO_ONE // vulkan clip space is from 0 to 1
#define GLM_FORCE_RIGHT_HANDED // glTF uses right handed coordinate system, and we're following its lead.

#include <vector>

struct hello_video_app_o {
le::Window window;
le::Renderer renderer;
uint64_t frame_counter = 0;

LeResourceManager resource_manager;

le::Video video;
};

constexpr le_resource_handle_t VIDEO_HANDLE = LE_IMG_RESOURCE( "video" );

typedef hello_video_app_o app_o;

// ----------------------------------------------------------------------

static void app_initialize() {
le::Window::init();
le::Video::init();
};

// ----------------------------------------------------------------------

static void app_terminate() {
le::Video::terminate();
le::Window::terminate();
};

// ----------------------------------------------------------------------

static app_o *app_create() {
auto app = new ( app_o );

le::Window::Settings settings;
settings
.setWidth( 1280 )
.setHeight( 720 )
.setTitle( "Island // HelloVideoApp" );

// create a new window
app->window.setup( settings );

app->renderer.setup( le::RendererInfoBuilder( app->window ).build() );

app->video.setup( app->resource_manager, VIDEO_HANDLE );
app->video.load( "./local_resources/test.mp4" );
app->video.set_loop( true );
app->video.play();

return app;
}

// ----------------------------------------------------------------------

static void pass_main_exec( le_command_buffer_encoder_o *encoder_, void *user_data ) {
auto app = static_cast<app_o *>( user_data );

le::Encoder encoder{ encoder_ };

static auto shaderVert = app->renderer.createShaderModule( "./local_resources/shaders/fullscreen.vert", le::ShaderStage::eVertex );
static auto shaderFrag = app->renderer.createShaderModule( "./local_resources/shaders/fullscreen.frag", le::ShaderStage::eFragment );

static auto video_texture = le::Renderer::produceTextureHandle( "video" );

static auto pipelineHelloVideoExample =
LeGraphicsPipelineBuilder( encoder.getPipelineManager() )
.addShaderStage( shaderVert )
.addShaderStage( shaderFrag )
.build();

encoder
.bindGraphicsPipeline( pipelineHelloVideoExample )
.setArgumentTexture( LE_ARGUMENT_NAME( "src_video" ), video_texture )
.draw( 4 );
}

// ----------------------------------------------------------------------
static void app_process_ui_events( app_o *self ) {
using namespace le_window;
uint32_t numEvents;
LeUiEvent const *pEvents;
window_i.get_ui_event_queue( self->window, &pEvents, numEvents );

std::vector<LeUiEvent> events{ pEvents, pEvents + numEvents };

bool wantsToggle = false;

for ( auto &event : events ) {
switch ( event.event ) {
case ( LeUiEvent::Type::eKey ): {
auto &e = event.key;
if ( e.action == LeUiEvent::ButtonAction::eRelease ) {

if ( e.key == LeUiEvent::NamedKey::eF11 ) {
wantsToggle ^= true;
} else if ( e.key == LeUiEvent::NamedKey::eSpace ) {
self->video.pause();
}

} // if ButtonAction == eRelease

} break;
default:
// do nothing
break;
}
}

if ( wantsToggle ) {
self->window.toggleFullscreen();
}
}

// ----------------------------------------------------------------------

static bool app_update( app_o *self ) {

// Polls events for all windows
// Use `self->window.getUIEventQueue()` to fetch events.
le::Window::pollEvents();

if ( self->window.shouldClose() ) {
return false;
}

app_process_ui_events( self );

static auto video_texture = le::Renderer::produceTextureHandle( "video" );

le::RenderModule mainModule{};
{
self->resource_manager.update( mainModule );

auto video_tex_info =
le::ImageSamplerInfoBuilder()
.withImageViewInfo()
.setImage( VIDEO_HANDLE )
.end()
.build();

auto renderPassFinal =
le::RenderPass( "root", LE_RENDER_PASS_TYPE_DRAW )
.addColorAttachment( LE_SWAPCHAIN_IMAGE_HANDLE )
.sampleTexture( video_texture, video_tex_info ) // Declare texture video
.setExecuteCallback( self, pass_main_exec ) //
;

mainModule.addRenderPass( renderPassFinal );
}

self->renderer.update( mainModule );

self->frame_counter++;

return true; // keep app alive
}

// ----------------------------------------------------------------------

static void app_destroy( app_o *self ) {

delete ( self ); // deletes camera
}

// ----------------------------------------------------------------------

LE_MODULE_REGISTER_IMPL( hello_video_app, api ) {
auto hello_video_app_api_i = static_cast<hello_video_app_api *>( api );
auto &hello_video_app_i = hello_video_app_api_i->hello_video_app_i;

hello_video_app_i.initialize = app_initialize;
hello_video_app_i.terminate = app_terminate;

hello_video_app_i.create = app_create;
hello_video_app_i.destroy = app_destroy;
hello_video_app_i.update = app_update;
}
60 changes: 60 additions & 0 deletions apps/examples/hello_video/hello_video_app/hello_video_app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef GUARD_hello_video_app_H
#define GUARD_hello_video_app_H
#endif

#include "le_core/le_core.h"

struct hello_video_app_o;

// clang-format off
struct hello_video_app_api {

struct hello_video_app_interface_t {
hello_video_app_o * ( *create )();
void ( *destroy )( hello_video_app_o *self );
bool ( *update )( hello_video_app_o *self );
void ( *initialize )(); // static methods
void ( *terminate )(); // static methods
};

hello_video_app_interface_t hello_video_app_i;
};
// clang-format on

LE_MODULE( hello_video_app );
LE_MODULE_LOAD_DEFAULT( hello_video_app );

#ifdef __cplusplus

namespace hello_video_app {
static const auto &api = hello_video_app_api_i;
static const auto &hello_video_app_i = api -> hello_video_app_i;
} // namespace hello_video_app

class HelloVideoApp : NoCopy, NoMove {

hello_video_app_o *self;

public:
HelloVideoApp()
: self( hello_video_app::hello_video_app_i.create() ) {
}

bool update() {
return hello_video_app::hello_video_app_i.update( self );
}

~HelloVideoApp() {
hello_video_app::hello_video_app_i.destroy( self );
}

static void initialize() {
hello_video_app::hello_video_app_i.initialize();
}

static void terminate() {
hello_video_app::hello_video_app_i.terminate();
}
};

#endif
33 changes: 33 additions & 0 deletions apps/examples/hello_video/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "hello_video_app/hello_video_app.h"

// ----------------------------------------------------------------------

int main( int argc, char const *argv[] ) {

HelloVideoApp::initialize();

{
// We instantiate HelloVideoApp in its own scope - so that
// it will be destroyed before HelloVideoApp::terminate
// is called.

HelloVideoApp HelloVideoApp{};

for ( ;; ) {

#ifdef PLUGINS_DYNAMIC
le_core_poll_for_module_reloads();
#endif
auto result = HelloVideoApp.update();

if ( !result ) {
break;
}
}
}

// Must only be called once last HelloVideoApp is destroyed
HelloVideoApp::terminate();

return 0;
}
Loading