mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-14 05:12:25 +08:00
Initial video support without audio (#14)
* Adds FFmpeg to CMake * Refactors to allow support for other wallpaper types * Updates README.md for compilation requirements * Initial video support without audio * Properly support different wallpapers * Fixes videos not rendering * Nitpicks * Moves code related to rendering from Core::CVideo to Render::CVideo
This commit is contained in:
parent
98e245b4cb
commit
5d5ce361fe
@ -15,8 +15,9 @@ find_package(Irrlicht REQUIRED)
|
||||
find_package(SDL REQUIRED)
|
||||
find_package(SDL_mixer REQUIRED)
|
||||
find_package(LZ4 REQUIRED)
|
||||
find_package(FFmpeg REQUIRED)
|
||||
|
||||
include_directories(${X11_INCLUDE_DIR} ${XRANDR_INCLUDE_DIR} ${IRRLICHT_INCLUDE_DIR} ${LZ4_INCLUDE_DIR} ${SDL_INCLUDE_DIRS} ${SDL_MIXER_INCLUDE_DIRS} src include)
|
||||
include_directories(${X11_INCLUDE_DIR} ${XRANDR_INCLUDE_DIR} ${IRRLICHT_INCLUDE_DIR} ${LZ4_INCLUDE_DIR} ${SDL_INCLUDE_DIRS} ${SDL_MIXER_INCLUDE_DIRS} ${FFMPEG_INCLUDE_DIR} src include)
|
||||
|
||||
add_executable(
|
||||
wallengine
|
||||
@ -46,8 +47,12 @@ add_executable(
|
||||
src/WallpaperEngine/Render/Shaders/Compiler.h
|
||||
src/WallpaperEngine/Render/Shaders/Compiler.cpp
|
||||
|
||||
src/WallpaperEngine/Render/CWallpaper.h
|
||||
src/WallpaperEngine/Render/CWallpaper.cpp
|
||||
src/WallpaperEngine/Render/CScene.h
|
||||
src/WallpaperEngine/Render/CScene.cpp
|
||||
src/WallpaperEngine/Render/CVideo.h
|
||||
src/WallpaperEngine/Render/CVideo.cpp
|
||||
src/WallpaperEngine/Render/CCamera.h
|
||||
src/WallpaperEngine/Render/CCamera.cpp
|
||||
src/WallpaperEngine/Render/CObject.h
|
||||
@ -83,8 +88,12 @@ add_executable(
|
||||
|
||||
src/WallpaperEngine/Core/CProject.cpp
|
||||
src/WallpaperEngine/Core/CProject.h
|
||||
src/WallpaperEngine/Core/CWallpaper.cpp
|
||||
src/WallpaperEngine/Core/CWallpaper.h
|
||||
src/WallpaperEngine/Core/CScene.cpp
|
||||
src/WallpaperEngine/Core/CScene.h
|
||||
src/WallpaperEngine/Core/CVideo.cpp
|
||||
src/WallpaperEngine/Core/CVideo.h
|
||||
src/WallpaperEngine/Core/CObject.cpp
|
||||
src/WallpaperEngine/Core/CObject.h
|
||||
|
||||
@ -150,4 +159,4 @@ add_executable(
|
||||
src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h
|
||||
)
|
||||
|
||||
target_link_libraries(wallengine ${X11_LIBRARIES} ${XRANDR_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY} ${LZ4_LIBRARY} ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES})
|
||||
target_link_libraries(wallengine ${X11_LIBRARIES} ${XRANDR_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY} ${LZ4_LIBRARY} ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES} ${FFMPEG_LIBRARIES})
|
110
CMakeModules/FindFFmpeg.cmake
Normal file
110
CMakeModules/FindFFmpeg.cmake
Normal file
@ -0,0 +1,110 @@
|
||||
# - Try to find ffmpeg libraries (libavcodec, libavformat, libavutil and libswscale)
|
||||
# Once done this will define
|
||||
#
|
||||
# FFMPEG_FOUND - system has ffmpeg or libav
|
||||
# FFMPEG_INCLUDE_DIR - the ffmpeg include directory
|
||||
# FFMPEG_LIBRARIES - Link these to use ffmpeg
|
||||
# FFMPEG_LIBAVCODEC
|
||||
# FFMPEG_LIBAVFORMAT
|
||||
# FFMPEG_LIBAVUTIL
|
||||
# FFMPEG_LIBSWSCALE
|
||||
#
|
||||
# Copyright (c) 2008 Andreas Schneider <mail@cynapses.org>
|
||||
# Modified for other libraries by Lasse Kärkkäinen <tronic>
|
||||
# Modified for Hedgewars by Stepik777
|
||||
# Modified for FFmpeg-example Tuukka Pasanen 2018
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
#
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(FFMPEG
|
||||
FOUND_VAR FFMPEG_FOUND
|
||||
REQUIRED_VARS
|
||||
FFMPEG_LIBRARY
|
||||
FFMPEG_INCLUDE_DIR
|
||||
VERSION_VAR FFMPEG_VERSION
|
||||
)
|
||||
|
||||
if(FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
|
||||
# in cache already
|
||||
set(FFMPEG_FOUND TRUE)
|
||||
else()
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
find_package(PkgConfig)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_FFMPEG_AVCODEC libavcodec)
|
||||
pkg_check_modules(_FFMPEG_AVFORMAT libavformat)
|
||||
pkg_check_modules(_FFMPEG_AVUTIL libavutil)
|
||||
pkg_check_modules(_FFMPEG_SWSCALE libswscale)
|
||||
endif()
|
||||
|
||||
find_path(FFMPEG_AVCODEC_INCLUDE_DIR
|
||||
NAMES libavcodec/avcodec.h
|
||||
PATHS ${_FFMPEG_AVCODEC_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES ffmpeg libav)
|
||||
|
||||
find_library(FFMPEG_LIBAVCODEC
|
||||
NAMES avcodec
|
||||
PATHS ${_FFMPEG_AVCODEC_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib)
|
||||
|
||||
find_library(FFMPEG_LIBAVFORMAT
|
||||
NAMES avformat
|
||||
PATHS ${_FFMPEG_AVFORMAT_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib)
|
||||
|
||||
find_library(FFMPEG_LIBAVUTIL
|
||||
NAMES avutil
|
||||
PATHS ${_FFMPEG_AVUTIL_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib)
|
||||
|
||||
find_library(FFMPEG_LIBSWSCALE
|
||||
NAMES swscale
|
||||
PATHS ${_FFMPEG_SWSCALE_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib)
|
||||
|
||||
if(FFMPEG_LIBAVCODEC AND FFMPEG_LIBAVFORMAT)
|
||||
set(FFMPEG_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
if(FFMPEG_FOUND)
|
||||
set(FFMPEG_INCLUDE_DIR ${FFMPEG_AVCODEC_INCLUDE_DIR})
|
||||
set(FFMPEG_LIBRARIES
|
||||
${FFMPEG_LIBAVCODEC}
|
||||
${FFMPEG_LIBAVFORMAT}
|
||||
${FFMPEG_LIBAVUTIL}
|
||||
${FFMPEG_LIBSWSCALE})
|
||||
endif()
|
||||
|
||||
if(FFMPEG_FOUND)
|
||||
if(NOT FFMPEG_FIND_QUIETLY)
|
||||
message(STATUS
|
||||
"Found FFMPEG or Libav: ${FFMPEG_LIBRARIES}, ${FFMPEG_INCLUDE_DIR}")
|
||||
endif()
|
||||
else()
|
||||
if(FFMPEG_FIND_REQUIRED)
|
||||
message(FATAL_ERROR
|
||||
"Could not find libavcodec or libavformat or libavutil or libswscale")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
@ -15,6 +15,7 @@ Wallpaper Engine is a software designed by [Kristjan Skutta](https://store.steam
|
||||
- ZLIB
|
||||
- SDL
|
||||
- SDL_mixer
|
||||
- FFmpeg
|
||||
- X11
|
||||
- Xrandr
|
||||
|
||||
|
28
main.cpp
28
main.cpp
@ -6,7 +6,9 @@
|
||||
|
||||
#include "WallpaperEngine/Core/CProject.h"
|
||||
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||
#include "WallpaperEngine/Render/CScene.h"
|
||||
#include "WallpaperEngine/Render/CVideo.h"
|
||||
|
||||
enum BACKGROUND_RUN_MODE
|
||||
{
|
||||
@ -161,14 +163,32 @@ int main (int argc, char* argv[])
|
||||
}
|
||||
|
||||
WallpaperEngine::Core::CProject* project = WallpaperEngine::Core::CProject::fromFile (project_path);
|
||||
WallpaperEngine::Render::CScene* scene = new WallpaperEngine::Render::CScene (project, IrrlichtContext);
|
||||
WallpaperEngine::Render::CWallpaper* wallpaper;
|
||||
|
||||
if (project->getType () == "scene")
|
||||
{
|
||||
WallpaperEngine::Core::CScene* scene = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ();
|
||||
wallpaper = new WallpaperEngine::Render::CScene (scene, IrrlichtContext);
|
||||
IrrlichtContext->getDevice ()->getSceneManager ()->setAmbientLight (
|
||||
scene->getAmbientColor ().toSColor ()
|
||||
);
|
||||
}
|
||||
else if (project->getType () == "video")
|
||||
{
|
||||
wallpaper = new WallpaperEngine::Render::CVideo (
|
||||
project->getWallpaper ()->as <WallpaperEngine::Core::CVideo> (),
|
||||
IrrlichtContext
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error ("Unsupported wallpaper type");
|
||||
}
|
||||
|
||||
irr::u32 minimumTime = 1000 / maximumFPS;
|
||||
irr::u32 startTime = 0;
|
||||
irr::u32 endTime = 0;
|
||||
|
||||
IrrlichtContext->getDevice ()->getSceneManager ()->setAmbientLight (scene->getScene ()->getAmbientColor ().toSColor ());
|
||||
|
||||
while (IrrlichtContext && IrrlichtContext->getDevice () && IrrlichtContext->getDevice ()->run ())
|
||||
{
|
||||
if (IrrlichtContext->getDevice ()->getVideoDriver () == nullptr)
|
||||
@ -176,7 +196,7 @@ int main (int argc, char* argv[])
|
||||
|
||||
startTime = IrrlichtContext->getDevice ()->getTimer ()->getTime ();
|
||||
|
||||
IrrlichtContext->renderFrame (scene);
|
||||
IrrlichtContext->renderFrame (wallpaper);
|
||||
|
||||
endTime = IrrlichtContext->getDevice ()->getTimer ()->getTime ();
|
||||
|
||||
|
@ -1,15 +1,17 @@
|
||||
#include <WallpaperEngine/FileSystem/FileSystem.h>
|
||||
|
||||
#include "CProject.h"
|
||||
#include "CScene.h"
|
||||
#include "CVideo.h"
|
||||
|
||||
using namespace WallpaperEngine::Core;
|
||||
|
||||
CProject::CProject (std::string title, std::string type, CScene *scene) :
|
||||
CProject::CProject (std::string title, std::string type, CWallpaper* wallpaper) :
|
||||
m_title (std::move (title)),
|
||||
m_type (std::move (type)),
|
||||
m_scene (scene)
|
||||
m_wallpaper (wallpaper)
|
||||
{
|
||||
this->m_scene->setProject (this);
|
||||
this->m_wallpaper->setProject (this);
|
||||
}
|
||||
|
||||
CProject* CProject::fromFile (const irr::io::path& filename)
|
||||
@ -20,11 +22,23 @@ CProject* CProject::fromFile (const irr::io::path& filename)
|
||||
auto type = jsonFindRequired (content, "type", "Project type missing");
|
||||
auto file = jsonFindRequired (content, "file", "Project's main file missing");
|
||||
auto general = content.find ("general");
|
||||
CWallpaper* wallpaper;
|
||||
|
||||
if (strcmp ((*type).get <std::string> ().c_str (), "scene") == 0)
|
||||
{
|
||||
wallpaper = CScene::fromFile ((*file).get <std::string> ().c_str ());
|
||||
}
|
||||
else if (strcmp ((*type).get <std::string> ().c_str (), "video") == 0)
|
||||
{
|
||||
wallpaper = new CVideo ((*file).get <std::string> ().c_str ());
|
||||
}
|
||||
else
|
||||
throw std::runtime_error ("Unsupported wallpaper type");
|
||||
|
||||
CProject* project = new CProject (
|
||||
*title,
|
||||
*type,
|
||||
CScene::fromFile ((*file).get <std::string> ().c_str ())
|
||||
wallpaper
|
||||
);
|
||||
|
||||
if (general != content.end ())
|
||||
@ -48,9 +62,9 @@ CProject* CProject::fromFile (const irr::io::path& filename)
|
||||
return project;
|
||||
}
|
||||
|
||||
const CScene* CProject::getScene () const
|
||||
CWallpaper* CProject::getWallpaper () const
|
||||
{
|
||||
return this->m_scene;
|
||||
return this->m_wallpaper;
|
||||
}
|
||||
|
||||
const std::string& CProject::getTitle () const
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
|
||||
#include "CScene.h"
|
||||
#include "CWallpaper.h"
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/Projects/CProperty.h"
|
||||
|
||||
@ -10,21 +10,21 @@ namespace WallpaperEngine::Core
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class CScene;
|
||||
class CWallpaper;
|
||||
|
||||
class CProject
|
||||
{
|
||||
public:
|
||||
static CProject* fromFile (const irr::io::path& filename);
|
||||
|
||||
const CScene* getScene () const;
|
||||
CWallpaper* getWallpaper () const;
|
||||
|
||||
const std::string& getTitle () const;
|
||||
const std::string& getType () const;
|
||||
const std::vector<Projects::CProperty*>& getProperties () const;
|
||||
|
||||
protected:
|
||||
CProject (std::string title, std::string type, CScene* scene);
|
||||
CProject (std::string title, std::string type, CWallpaper* wallpaper);
|
||||
|
||||
void insertProperty (Projects::CProperty* property);
|
||||
private:
|
||||
@ -32,7 +32,6 @@ namespace WallpaperEngine::Core
|
||||
|
||||
std::string m_title;
|
||||
std::string m_type;
|
||||
CScene* m_scene;
|
||||
CWallpaper* m_wallpaper;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -24,6 +24,7 @@ CScene::CScene (
|
||||
irr::video::SColorf clearColor,
|
||||
Scenes::CProjection* orthogonalProjection,
|
||||
irr::video::SColorf skylightColor) :
|
||||
CWallpaper (Type),
|
||||
m_camera (camera),
|
||||
m_ambientColor (ambientColor),
|
||||
m_bloom (bloom),
|
||||
@ -105,7 +106,6 @@ CScene* CScene::fromFile (const irr::io::path& filename)
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<CObject*>& CScene::getObjects () const
|
||||
{
|
||||
return this->m_objects;
|
||||
@ -116,16 +116,6 @@ void CScene::insertObject (CObject* object)
|
||||
this->m_objects.push_back (object);
|
||||
}
|
||||
|
||||
CProject* CScene::getProject ()
|
||||
{
|
||||
return this->m_project;
|
||||
}
|
||||
|
||||
void CScene::setProject (CProject* project)
|
||||
{
|
||||
this->m_project = project;
|
||||
}
|
||||
|
||||
const Scenes::CCamera* CScene::getCamera () const
|
||||
{
|
||||
return this->m_camera;
|
||||
@ -215,3 +205,5 @@ const irr::video::SColorf& CScene::getSkylightColor () const
|
||||
{
|
||||
return this->m_skylightColor;
|
||||
}
|
||||
|
||||
const std::string CScene::Type = "scene";
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
|
||||
#include "CProject.h"
|
||||
#include "CObject.h"
|
||||
#include "CWallpaper.h"
|
||||
|
||||
#include "Core.h"
|
||||
|
||||
@ -14,15 +14,13 @@ namespace WallpaperEngine::Core
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class CProject;
|
||||
class CObject;
|
||||
|
||||
class CScene
|
||||
class CScene : public CWallpaper
|
||||
{
|
||||
public:
|
||||
static CScene* fromFile (const irr::io::path& filename);
|
||||
|
||||
CProject* getProject ();
|
||||
const std::vector<CObject*>& getObjects () const;
|
||||
|
||||
const irr::video::SColorf& getAmbientColor() const;
|
||||
@ -45,9 +43,7 @@ namespace WallpaperEngine::Core
|
||||
const Scenes::CCamera* getCamera () const;
|
||||
|
||||
protected:
|
||||
friend class CProject;
|
||||
|
||||
void setProject (CProject* project);
|
||||
friend class CWallpaper;
|
||||
|
||||
CScene (
|
||||
Scenes::CCamera* camera,
|
||||
@ -70,9 +66,10 @@ namespace WallpaperEngine::Core
|
||||
irr::video::SColorf skylightColor
|
||||
);
|
||||
|
||||
static const std::string Type;
|
||||
|
||||
void insertObject (CObject* object);
|
||||
private:
|
||||
CProject* m_project;
|
||||
Scenes::CCamera* m_camera;
|
||||
|
||||
// data from general section on the json
|
||||
|
17
src/WallpaperEngine/Core/CVideo.cpp
Normal file
17
src/WallpaperEngine/Core/CVideo.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "CVideo.h"
|
||||
|
||||
using namespace WallpaperEngine::Core;
|
||||
|
||||
CVideo::CVideo (
|
||||
const irr::io::path& filename) :
|
||||
CWallpaper (Type),
|
||||
m_filename (filename)
|
||||
{
|
||||
}
|
||||
|
||||
const irr::io::path CVideo::getFilename ()
|
||||
{
|
||||
return this->m_filename;
|
||||
}
|
||||
|
||||
const std::string CVideo::Type = "video";
|
36
src/WallpaperEngine/Core/CVideo.h
Normal file
36
src/WallpaperEngine/Core/CVideo.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
|
||||
#include "Core.h"
|
||||
#include "CWallpaper.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
class CVideo : public CWallpaper
|
||||
{
|
||||
public:
|
||||
CVideo (
|
||||
const irr::io::path& filename
|
||||
);
|
||||
|
||||
const irr::io::path getFilename ();
|
||||
|
||||
protected:
|
||||
friend class CWallpaper;
|
||||
|
||||
const irr::io::path m_filename;
|
||||
|
||||
static const std::string Type;
|
||||
|
||||
private:
|
||||
};
|
||||
};
|
18
src/WallpaperEngine/Core/CWallpaper.cpp
Normal file
18
src/WallpaperEngine/Core/CWallpaper.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "CWallpaper.h"
|
||||
|
||||
using namespace WallpaperEngine::Core;
|
||||
|
||||
CWallpaper::CWallpaper (std::string type) :
|
||||
m_type (type)
|
||||
{
|
||||
}
|
||||
|
||||
CProject* CWallpaper::getProject ()
|
||||
{
|
||||
return this->m_project;
|
||||
}
|
||||
|
||||
void CWallpaper::setProject (CProject* project)
|
||||
{
|
||||
this->m_project = project;
|
||||
}
|
33
src/WallpaperEngine/Core/CWallpaper.h
Normal file
33
src/WallpaperEngine/Core/CWallpaper.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "CProject.h"
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
class CProject;
|
||||
|
||||
class CWallpaper
|
||||
{
|
||||
public:
|
||||
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
|
||||
template<class T> T* as () { assert (is <T> ()); return (T*) this; }
|
||||
|
||||
template<class T> bool is () { return this->m_type == T::Type; }
|
||||
|
||||
CWallpaper (std::string type);
|
||||
|
||||
CProject* getProject ();
|
||||
|
||||
protected:
|
||||
friend class CProject;
|
||||
|
||||
void setProject (CProject* project);
|
||||
|
||||
private:
|
||||
CProject* m_project;
|
||||
|
||||
std::string m_type;
|
||||
};
|
||||
}
|
@ -162,7 +162,7 @@ void CContext::initializeViewports (irr::SIrrlichtCreationParameters &irrlichtCr
|
||||
irrlichtCreationParameters.WindowId = reinterpret_cast<void*> (DefaultRootWindow (display));
|
||||
}
|
||||
|
||||
void CContext::renderFrame (Render::CScene* scene)
|
||||
void CContext::renderFrame (Render::CWallpaper* wallpaper)
|
||||
{
|
||||
this->m_time = this->getDevice ()->getTimer ()->getTime () / 1000.0f;
|
||||
this->m_pointerPosition.X = this->m_eventReceiver->getPosition ().X / (irr::f32) this->getDevice ()->getVideoDriver ()->getScreenSize ().Width;
|
||||
@ -170,7 +170,7 @@ void CContext::renderFrame (Render::CScene* scene)
|
||||
|
||||
if (this->m_viewports.empty () == true)
|
||||
{
|
||||
this->drawScene (scene, true);
|
||||
this->drawWallpaper (wallpaper, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -181,14 +181,15 @@ void CContext::renderFrame (Render::CScene* scene)
|
||||
{
|
||||
// change viewport to render to the correct portion of the display
|
||||
this->getDevice ()->getVideoDriver ()->setViewPort (*cur);
|
||||
this->drawScene (scene, false);
|
||||
this->drawWallpaper (wallpaper, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CContext::drawScene (Render::CScene* scene, bool backBuffer)
|
||||
void CContext::drawWallpaper (Render::CWallpaper* wallpaper, bool backBuffer)
|
||||
{
|
||||
this->getDevice ()->getVideoDriver ()->beginScene (backBuffer, true, scene->getScene ()->getClearColor ().toSColor());
|
||||
// TODO: Get scene clear color
|
||||
this->getDevice ()->getVideoDriver ()->beginScene (backBuffer, true);
|
||||
this->getDevice ()->getSceneManager ()->drawAll ();
|
||||
this->getDevice ()->getVideoDriver ()->endScene ();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
|
||||
#include "WallpaperEngine/Render/CScene.h"
|
||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||
|
||||
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
namespace WallpaperEngine::Render
|
||||
{
|
||||
class CScene;
|
||||
class CWallpaper;
|
||||
};
|
||||
|
||||
namespace WallpaperEngine::Irrlicht
|
||||
@ -29,7 +29,7 @@ namespace WallpaperEngine::Irrlicht
|
||||
void insertShaderVariable (Render::Shaders::Variables::CShaderVariable* variable);
|
||||
const std::vector<Render::Shaders::Variables::CShaderVariable*>& getShaderVariables () const;
|
||||
|
||||
void renderFrame (Render::CScene* scene);
|
||||
void renderFrame (Render::CWallpaper* wallpaper);
|
||||
|
||||
irr::IrrlichtDevice* getDevice ();
|
||||
irr::io::path resolveMaterials (const std::string& materialName);
|
||||
@ -38,7 +38,7 @@ namespace WallpaperEngine::Irrlicht
|
||||
irr::io::path resolveIncludeShader (const std::string& includeShader);
|
||||
private:
|
||||
void initializeViewports (irr::SIrrlichtCreationParameters& irrlichtCreationParameters);
|
||||
void drawScene (Render::CScene* scene, bool backBuffer);
|
||||
void drawWallpaper (Render::CWallpaper* wallpaper, bool backBuffer);
|
||||
|
||||
irr::io::path resolveFile (const irr::io::path& file);
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||
|
||||
#include "WallpaperEngine/Core/Objects/CImage.h"
|
||||
#include "WallpaperEngine/Core/Objects/CSound.h"
|
||||
|
||||
@ -11,23 +9,17 @@
|
||||
using namespace WallpaperEngine;
|
||||
using namespace WallpaperEngine::Render;
|
||||
|
||||
CScene::CScene (const Core::CProject* project, Irrlicht::CContext* context) :
|
||||
irr::scene::ISceneNode (
|
||||
context->getDevice ()->getSceneManager ()->getRootSceneNode (),
|
||||
context->getDevice ()->getSceneManager ()
|
||||
),
|
||||
m_project (project),
|
||||
m_scene (project->getScene ()),
|
||||
m_context (context)
|
||||
CScene::CScene (Core::CScene* scene, Irrlicht::CContext* context) :
|
||||
CWallpaper (scene, Type, context)
|
||||
{
|
||||
this->m_camera = new CCamera (this, this->m_project->getScene ()->getCamera ());
|
||||
this->m_camera = new CCamera (this, scene->getCamera ());
|
||||
this->m_camera->setOrthogonalProjection (
|
||||
this->m_scene->getOrthogonalProjection ()->getWidth (),
|
||||
this->m_scene->getOrthogonalProjection ()->getHeight ()
|
||||
scene->getOrthogonalProjection ()->getWidth (),
|
||||
scene->getOrthogonalProjection ()->getHeight ()
|
||||
);
|
||||
|
||||
auto cur = this->m_scene->getObjects ().begin ();
|
||||
auto end = this->m_scene->getObjects ().end ();
|
||||
auto cur = scene->getObjects ().begin ();
|
||||
auto end = scene->getObjects ().end ();
|
||||
|
||||
int highestId = 0;
|
||||
|
||||
@ -48,21 +40,6 @@ CScene::CScene (const Core::CProject* project, Irrlicht::CContext* context) :
|
||||
|
||||
this->m_nextId = ++highestId;
|
||||
this->setAutomaticCulling (irr::scene::EAC_OFF);
|
||||
this->m_boundingBox = irr::core::aabbox3d<irr::f32>(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
CScene::~CScene ()
|
||||
{
|
||||
}
|
||||
|
||||
Irrlicht::CContext* CScene::getContext ()
|
||||
{
|
||||
return this->m_context;
|
||||
}
|
||||
|
||||
const Core::CScene* CScene::getScene () const
|
||||
{
|
||||
return this->m_scene;
|
||||
}
|
||||
|
||||
CCamera* CScene::getCamera () const
|
||||
@ -79,13 +56,9 @@ void CScene::render ()
|
||||
{
|
||||
}
|
||||
|
||||
const irr::core::aabbox3d<irr::f32>& CScene::getBoundingBox () const
|
||||
Core::CScene* CScene::getScene ()
|
||||
{
|
||||
return this->m_boundingBox;
|
||||
return this->getWallpaperData ()->as<Core::CScene> ();
|
||||
}
|
||||
void CScene::OnRegisterSceneNode ()
|
||||
{
|
||||
SceneManager->registerNodeForRendering (this);
|
||||
|
||||
ISceneNode::OnRegisterSceneNode ();
|
||||
}
|
||||
const std::string CScene::Type = "scene";
|
||||
|
@ -2,40 +2,35 @@
|
||||
|
||||
#include "CCamera.h"
|
||||
|
||||
#include "WallpaperEngine/Core/CProject.h"
|
||||
#include "WallpaperEngine/Core/CScene.h"
|
||||
|
||||
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||
|
||||
namespace WallpaperEngine::Irrlicht
|
||||
{
|
||||
class CContext;
|
||||
};
|
||||
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||
|
||||
namespace WallpaperEngine::Render
|
||||
{
|
||||
class CCamera;
|
||||
|
||||
class CScene : public irr::scene::ISceneNode
|
||||
class CScene : public CWallpaper
|
||||
{
|
||||
public:
|
||||
CScene (const Core::CProject* project, Irrlicht::CContext* context);
|
||||
~CScene () override;
|
||||
CScene (Core::CScene* scene, WallpaperEngine::Irrlicht::CContext* context);
|
||||
|
||||
Irrlicht::CContext* getContext ();
|
||||
const Core::CScene* getScene () const;
|
||||
CCamera* getCamera () const;
|
||||
int nextId ();
|
||||
|
||||
void render () override;
|
||||
const irr::core::aabbox3d<irr::f32>& getBoundingBox() const override;
|
||||
void OnRegisterSceneNode () override;
|
||||
|
||||
Core::CScene* getScene ();
|
||||
|
||||
protected:
|
||||
friend class CWallpaper;
|
||||
|
||||
static const std::string Type;
|
||||
|
||||
private:
|
||||
const Core::CProject* m_project;
|
||||
const Core::CScene* m_scene;
|
||||
CCamera* m_camera;
|
||||
Irrlicht::CContext* m_context;
|
||||
irr::u32 m_nextId;
|
||||
irr::core::aabbox3d<irr::f32> m_boundingBox;
|
||||
};
|
||||
}
|
||||
|
165
src/WallpaperEngine/Render/CVideo.cpp
Normal file
165
src/WallpaperEngine/Render/CVideo.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
#include "CVideo.h"
|
||||
|
||||
using namespace WallpaperEngine;
|
||||
|
||||
using namespace WallpaperEngine::Render;
|
||||
|
||||
CVideo::CVideo (Core::CVideo* video, WallpaperEngine::Irrlicht::CContext* context) :
|
||||
CWallpaper (video, Type, context)
|
||||
{
|
||||
if (avformat_open_input (&m_formatCtx, video->getFilename ().c_str (), NULL, NULL) < 0)
|
||||
throw std::runtime_error ("Failed to open video file");
|
||||
|
||||
if (avformat_find_stream_info (m_formatCtx, NULL) < 0)
|
||||
throw std::runtime_error ("Failed to get stream info");
|
||||
|
||||
// Find first video stream
|
||||
for (int i = 0; i < m_formatCtx->nb_streams; i++)
|
||||
{
|
||||
if (m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
{
|
||||
m_videoStream = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find first audio stream
|
||||
for (int i = 0; i < m_formatCtx->nb_streams; i++)
|
||||
{
|
||||
if (m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
{
|
||||
m_audioStream = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only video stream is required
|
||||
if (m_videoStream == -1)
|
||||
throw std::runtime_error ("Failed to find video stream");
|
||||
|
||||
AVCodec* codec = avcodec_find_decoder (m_formatCtx->streams[m_videoStream]->codecpar->codec_id);
|
||||
if (codec == nullptr)
|
||||
throw std::runtime_error ("Failed to find codec");
|
||||
|
||||
m_codecCtx = avcodec_alloc_context3 (codec);
|
||||
if (avcodec_parameters_to_context (m_codecCtx, m_formatCtx->streams[m_videoStream]->codecpar))
|
||||
throw std::runtime_error ("Failed to copy codec parameters");
|
||||
|
||||
if (avcodec_open2 (m_codecCtx, codec, NULL) < 0)
|
||||
throw std::runtime_error ("Failed to open codec");
|
||||
|
||||
m_videoFrame = av_frame_alloc ();
|
||||
m_videoFrameRGB = av_frame_alloc ();
|
||||
if (m_videoFrameRGB == nullptr)
|
||||
throw std::runtime_error ("Failed to allocate video frame");
|
||||
}
|
||||
|
||||
void CVideo::setSize (int width, int height)
|
||||
{
|
||||
if (m_buffer != nullptr)
|
||||
av_free (m_buffer);
|
||||
|
||||
if (m_swsCtx != nullptr)
|
||||
sws_freeContext (m_swsCtx);
|
||||
|
||||
int numBytes = av_image_get_buffer_size (AV_PIX_FMT_RGB24, width, height, 1);
|
||||
m_buffer = (uint8_t*)av_malloc (numBytes * sizeof (uint8_t));
|
||||
|
||||
av_image_fill_arrays (m_videoFrameRGB->data, m_videoFrameRGB->linesize, m_buffer, AV_PIX_FMT_RGB24, width, height, 1);
|
||||
|
||||
m_swsCtx = sws_getContext (m_codecCtx->width, m_codecCtx->height,
|
||||
m_codecCtx->pix_fmt,
|
||||
width, height,
|
||||
AV_PIX_FMT_RGB24,
|
||||
SWS_BILINEAR, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void CVideo::render ()
|
||||
{
|
||||
irr::video::IVideoDriver* driver = m_context->getDevice ()->getVideoDriver ();
|
||||
int width = driver->getScreenSize ().Width;
|
||||
int height = driver->getScreenSize ().Height;
|
||||
|
||||
m_frameImage = m_context->getDevice ()->getVideoDriver ()->createImage (irr::video::ECOLOR_FORMAT::ECF_R8G8B8,
|
||||
irr::core::dimension2du(width, height));
|
||||
|
||||
setSize (width, height);
|
||||
getNextFrame ();
|
||||
writeFrameToImage ();
|
||||
|
||||
driver->removeTexture (m_frameTexture);
|
||||
m_frameTexture = driver->addTexture ("frameTexture", m_frameImage);
|
||||
m_frameImage->drop ();
|
||||
|
||||
driver->draw2DImage (m_frameTexture, irr::core::vector2di(0));
|
||||
}
|
||||
|
||||
void CVideo::getNextFrame ()
|
||||
{
|
||||
bool eof = false;
|
||||
AVPacket packet;
|
||||
packet.data = nullptr;
|
||||
|
||||
// Find video streams packet
|
||||
do
|
||||
{
|
||||
if (packet.data != nullptr)
|
||||
av_packet_unref (&packet);
|
||||
|
||||
int readError = av_read_frame (m_formatCtx, &packet);
|
||||
if (readError == AVERROR_EOF)
|
||||
{
|
||||
eof = true;
|
||||
break;
|
||||
}
|
||||
else if (readError < 0)
|
||||
{
|
||||
char err[AV_ERROR_MAX_STRING_SIZE];
|
||||
throw std::runtime_error (av_make_error_string (err, AV_ERROR_MAX_STRING_SIZE, readError));
|
||||
}
|
||||
|
||||
} while (packet.stream_index != m_videoStream);
|
||||
|
||||
// Send video stream packet to codec
|
||||
if (avcodec_send_packet (m_codecCtx, &packet) < 0)
|
||||
return;
|
||||
|
||||
// Receive frame from codec
|
||||
if (avcodec_receive_frame (m_codecCtx, m_videoFrame) < 0)
|
||||
return;
|
||||
|
||||
sws_scale (m_swsCtx, (uint8_t const* const*)m_videoFrame->data, m_videoFrame->linesize,
|
||||
0, m_codecCtx->height, m_videoFrameRGB->data, m_videoFrameRGB->linesize);
|
||||
|
||||
av_packet_unref (&packet);
|
||||
|
||||
if (eof)
|
||||
restartStream ();
|
||||
}
|
||||
|
||||
void CVideo::writeFrameToImage ()
|
||||
{
|
||||
uint8_t* frameData = m_videoFrameRGB->data[0];
|
||||
if (frameData == nullptr)
|
||||
return;
|
||||
|
||||
irr::u32 imgWidth = m_frameImage->getDimension().Width;
|
||||
irr::u32 imgHeight = m_frameImage->getDimension().Height;
|
||||
|
||||
unsigned char* data = (unsigned char*)m_frameImage->lock ();
|
||||
memcpy (data, frameData, imgWidth * imgHeight * 3);
|
||||
m_frameImage->unlock ();
|
||||
}
|
||||
|
||||
void CVideo::restartStream ()
|
||||
{
|
||||
av_seek_frame (m_formatCtx, m_videoStream, 0, AVSEEK_FLAG_FRAME);
|
||||
avcodec_flush_buffers (m_codecCtx);
|
||||
}
|
||||
|
||||
Core::CVideo* CVideo::getVideo ()
|
||||
{
|
||||
return this->getWallpaperData ()->as<Core::CVideo> ();
|
||||
}
|
||||
|
||||
const std::string CVideo::Type = "video";
|
52
src/WallpaperEngine/Render/CVideo.h
Normal file
52
src/WallpaperEngine/Render/CVideo.h
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
|
||||
#include "WallpaperEngine/Core/CVideo.h"
|
||||
|
||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||
|
||||
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Render
|
||||
{
|
||||
class CVideo : public CWallpaper
|
||||
{
|
||||
public:
|
||||
CVideo (Core::CVideo* video, WallpaperEngine::Irrlicht::CContext* context);
|
||||
|
||||
void render () override;
|
||||
|
||||
Core::CVideo* getVideo ();
|
||||
|
||||
protected:
|
||||
friend class CWallpaper;
|
||||
|
||||
static const std::string Type;
|
||||
|
||||
private:
|
||||
void setSize (int width, int height);
|
||||
void restartStream ();
|
||||
void getNextFrame ();
|
||||
void writeFrameToImage ();
|
||||
|
||||
AVFormatContext* m_formatCtx = nullptr;
|
||||
AVCodecContext* m_codecCtx = nullptr;
|
||||
AVFrame* m_videoFrame = nullptr;
|
||||
AVFrame* m_videoFrameRGB = nullptr;
|
||||
SwsContext* m_swsCtx = nullptr;
|
||||
uint8_t* m_buffer = nullptr;
|
||||
int m_videoStream = -1, m_audioStream = -1;
|
||||
|
||||
irr::video::IImage* m_frameImage;
|
||||
irr::video::ITexture* m_frameTexture;
|
||||
};
|
||||
};
|
40
src/WallpaperEngine/Render/CWallpaper.cpp
Normal file
40
src/WallpaperEngine/Render/CWallpaper.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "CWallpaper.h"
|
||||
|
||||
using namespace WallpaperEngine::Render;
|
||||
|
||||
CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, WallpaperEngine::Irrlicht::CContext* context) :
|
||||
irr::scene::ISceneNode (
|
||||
context->getDevice ()->getSceneManager ()->getRootSceneNode (),
|
||||
context->getDevice ()->getSceneManager ()
|
||||
),
|
||||
m_context (context),
|
||||
m_wallpaperData (wallpaperData),
|
||||
m_type (type)
|
||||
{
|
||||
}
|
||||
|
||||
CWallpaper::~CWallpaper ()
|
||||
{
|
||||
}
|
||||
|
||||
void CWallpaper::OnRegisterSceneNode ()
|
||||
{
|
||||
SceneManager->registerNodeForRendering (this);
|
||||
|
||||
ISceneNode::OnRegisterSceneNode ();
|
||||
}
|
||||
|
||||
WallpaperEngine::Irrlicht::CContext* CWallpaper::getContext () const
|
||||
{
|
||||
return this->m_context;
|
||||
}
|
||||
|
||||
const irr::core::aabbox3d<irr::f32>& CWallpaper::getBoundingBox () const
|
||||
{
|
||||
return this->m_boundingBox;
|
||||
}
|
||||
|
||||
WallpaperEngine::Core::CWallpaper* CWallpaper::getWallpaperData ()
|
||||
{
|
||||
return this->m_wallpaperData;
|
||||
}
|
45
src/WallpaperEngine/Render/CWallpaper.h
Normal file
45
src/WallpaperEngine/Render/CWallpaper.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
|
||||
#include "WallpaperEngine/Core/CWallpaper.h"
|
||||
#include "WallpaperEngine/Core/CScene.h"
|
||||
#include "WallpaperEngine/Core/CVideo.h"
|
||||
|
||||
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||
|
||||
namespace WallpaperEngine::Irrlicht
|
||||
{
|
||||
class CContext;
|
||||
};
|
||||
|
||||
namespace WallpaperEngine::Render
|
||||
{
|
||||
class CWallpaper : public irr::scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
template<class T> const T* as () const { assert (is<T> ()); return (const T*) this; }
|
||||
template<class T> T* as () { assert (is<T> ()); return (T*) this; }
|
||||
|
||||
template<class T> bool is () { return this->m_type == T::Type; }
|
||||
|
||||
CWallpaper (Core::CWallpaper* wallpaperData, std::string type, WallpaperEngine::Irrlicht::CContext* context);
|
||||
~CWallpaper () override;
|
||||
|
||||
void OnRegisterSceneNode () override;
|
||||
|
||||
WallpaperEngine::Irrlicht::CContext* getContext () const;
|
||||
const irr::core::aabbox3d<irr::f32>& getBoundingBox () const override;
|
||||
|
||||
protected:
|
||||
WallpaperEngine::Irrlicht::CContext* m_context;
|
||||
Core::CWallpaper* m_wallpaperData;
|
||||
|
||||
Core::CWallpaper* getWallpaperData ();
|
||||
|
||||
private:
|
||||
irr::core::aabbox3d<irr::f32> m_boundingBox = irr::core::aabbox3d<irr::f32> (0, 0, 0, 0, 0, 0);
|
||||
|
||||
std::string m_type;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user