mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-23 07:46:36 +08:00
feat(gltf): support sharing the background environment across multiple objects (#9009)
This commit is contained in:
@@ -73,8 +73,8 @@ For complete implementation details, see :ref:`OpenGL driver <opengl_driver>`.
|
||||
3D/glTF Support
|
||||
===============
|
||||
|
||||
The glTF extension provides support for loading and rendering 3D models using the glTF 2.0 specification within LVGL applications.
|
||||
This extension requires OpenGL ES 3.0 and provides comprehensive 3D rendering capabilities including PBR materials,
|
||||
The glTF module provides support for loading and rendering 3D models using the glTF 2.0 specification within LVGL applications.
|
||||
This support requires OpenGL ES 2.0 with some extra extensions and provides comprehensive 3D rendering capabilities including PBR materials,
|
||||
animations, and interactive camera controls for embedded 3D visualization.
|
||||
|
||||
For complete implementation details, see :ref:`glTF <gltf>`.
|
||||
|
||||
+155
-76
@@ -10,64 +10,7 @@ The glTF extension in LVGL provides 3D model loading, rendering, and animation c
|
||||
|
||||
For a detailed introduction to glTF, see: https://www.khronos.org/gltf/
|
||||
|
||||
Features
|
||||
********
|
||||
|
||||
LVGL's glTF implementation provides comprehensive 3D rendering capabilities:
|
||||
|
||||
**File Format Support:**
|
||||
|
||||
* Loading glTF (.gltf) and binary GLB (.glb) files from local filesystem
|
||||
* Support for hex-encoded bytes in source include files when filesystem is not available
|
||||
* JPG, PNG, and WebP compressed texture support
|
||||
* External texture files or textures embedded within the glTF source
|
||||
|
||||
**Rendering & Lighting:**
|
||||
|
||||
* Image-Based Lighting (IBL) for realistic environmental lighting
|
||||
* Punctual lighting support with animated light sources
|
||||
* Physically Based Rendering (PBR) materials with full texture support:
|
||||
|
||||
* Diffuse/albedo textures
|
||||
* Roughness and metallic workflow textures
|
||||
* Normal maps for surface detail
|
||||
* Ambient occlusion textures
|
||||
|
||||
**Advanced Materials:**
|
||||
|
||||
* Emissive materials for glowing effects and self-illuminated surfaces
|
||||
* Refractive materials with realistic distortion effects revealing geometry behind surfaces
|
||||
* Clearcoat material support for multi-layer surface effects (like automotive paint finishes)
|
||||
* Full transparency support with alpha blending
|
||||
|
||||
**Animation System:**
|
||||
|
||||
* Keyframe-based animations for object transformations
|
||||
* Single-skeleton skinned character animations
|
||||
* Animated punctual lights with dynamic lighting effects
|
||||
* Parameter binding for real-time monitoring and control of object properties (position, rotation, scale)
|
||||
* Dynamic parameter override from host application
|
||||
|
||||
**Camera & Viewport:**
|
||||
|
||||
* Programmatic viewport control with full camera manipulation
|
||||
* Support for cameras defined within 3D editor software
|
||||
* Multiple camera switching for different scene perspectives
|
||||
* Orthographic and perspective projection modes
|
||||
|
||||
**Rendering Quality:**
|
||||
|
||||
* Configurable antialiasing with multiple modes:
|
||||
|
||||
* Always-on for consistent quality
|
||||
* Always-off for maximum performance
|
||||
* Auto-on that activates when scene movement stops
|
||||
|
||||
* Flexible background rendering:
|
||||
|
||||
* Environment-based backgrounds using IBL
|
||||
* Solid color backgrounds
|
||||
* Transparent backgrounds for overlay effects
|
||||
|
||||
What is glTF?
|
||||
*************
|
||||
@@ -85,19 +28,25 @@ glTF files can be stored as:
|
||||
- **.gltf**: JSON format with external binary and image files
|
||||
- **.glb**: Binary format with all assets embedded in a single file
|
||||
|
||||
|
||||
|
||||
Features
|
||||
********
|
||||
|
||||
LVGL's glTF implementation provides comprehensive 3D rendering capabilities:
|
||||
|
||||
**File Format Support:**
|
||||
|
||||
File Format Support
|
||||
-------------------
|
||||
|
||||
* Loading glTF (.gltf) and binary GLB (.glb) files from local filesystem
|
||||
* Support for hex-encoded bytes in source include files when filesystem is not available
|
||||
* JPG, PNG, and WebP compressed texture support
|
||||
* External texture files or textures embedded within the glTF source
|
||||
|
||||
**Rendering & Lighting:**
|
||||
|
||||
Rendering & Lighting
|
||||
---------------------
|
||||
|
||||
* Image-Based Lighting (IBL) for realistic environmental lighting
|
||||
* Punctual lighting support with animated light sources
|
||||
@@ -108,14 +57,18 @@ LVGL's glTF implementation provides comprehensive 3D rendering capabilities:
|
||||
* Normal maps for surface detail
|
||||
* Ambient occlusion textures
|
||||
|
||||
**Advanced Materials:**
|
||||
|
||||
Advanced Materials
|
||||
------------------
|
||||
|
||||
* Emissive materials for glowing effects and self-illuminated surfaces
|
||||
* Refractive materials with realistic distortion effects revealing geometry behind surfaces
|
||||
* Clearcoat material support for multi-layer surface effects (like automotive paint finishes)
|
||||
* Full transparency support with alpha blending
|
||||
|
||||
**Animation System:**
|
||||
|
||||
Animation System
|
||||
----------------
|
||||
|
||||
* Keyframe-based animations for object transformations
|
||||
* Single-skeleton skinned character animations
|
||||
@@ -123,14 +76,18 @@ LVGL's glTF implementation provides comprehensive 3D rendering capabilities:
|
||||
* Parameter binding for real-time monitoring and control of object properties (position, rotation, scale)
|
||||
* Dynamic parameter override from host application
|
||||
|
||||
**Camera & Viewport:**
|
||||
|
||||
Camera & Viewport
|
||||
-----------------
|
||||
|
||||
* Programmatic viewport control with full camera manipulation
|
||||
* Support for cameras defined within 3D editor software
|
||||
* Multiple camera switching for different scene perspectives
|
||||
* Orthographic and perspective projection modes
|
||||
|
||||
**Rendering Quality:**
|
||||
|
||||
Rendering Quality
|
||||
-----------------
|
||||
|
||||
* Configurable antialiasing with multiple modes:
|
||||
|
||||
@@ -144,13 +101,18 @@ LVGL's glTF implementation provides comprehensive 3D rendering capabilities:
|
||||
* Solid color backgrounds
|
||||
* Transparent backgrounds for overlay effects
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
The glTF extension relies on **OpenGL ES 3.0** for 3D rendering. LVGL includes built-in support for OpenGL ES through the GLFW driver, which provides cross-platform window management and OpenGL context creation.
|
||||
The glTF extension relies on **OpenGL ES 2.0** with some extension support for 3D rendering. LVGL includes built-in support for OpenGL ES through the GLFW driver, which provides cross-platform window management and OpenGL context creation.
|
||||
|
||||
The renderer uses OpenGL ES 3.0 shaders (GLSL version 300 es) to provide modern PBR (Physically Based Rendering) capabilities.
|
||||
|
||||
The full list of extensions required can be found `here <https://gen.glad.sh/#generator=c&api=egl%3D1.5%2Cgles2%3D2.0&profile=gl%3Dcompatibility%2Cgles1%3Dcommon&extensions=EGL_EXT_image_dma_buf_import%2CEGL_EXT_image_dma_buf_import_modifiers%2CEGL_EXT_platform_base%2CEGL_EXT_platform_wayland%2CEGL_KHR_fence_sync%2CEGL_KHR_image_base%2CEGL_KHR_platform_gbm%2CEGL_KHR_platform_wayland%2CGL_APPLE_texture_max_level%2CGL_ARM_rgba8%2CGL_EXT_color_buffer_float%2CGL_EXT_color_buffer_half_float%2CGL_EXT_texture_format_BGRA8888%2CGL_EXT_texture_storage%2CGL_EXT_unpack_subimage%2CGL_OES_depth24%2CGL_OES_mapbuffer%2CGL_OES_rgb8_rgba8%2CGL_OES_texture_float%2CGL_OES_texture_half_float%2CGL_OES_texture_storage_multisample_2d_array%2CGL_OES_vertex_array_object&options=ALIAS>`__.
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
@@ -159,12 +121,15 @@ The glTF extension requires the following external libraries:
|
||||
:fastgltf: A C++20 library for parsing glTF files (https://github.com/spnda/fastgltf)
|
||||
:libwebp: WebP image format support for textures (https://github.com/webmproject/libwebp)
|
||||
|
||||
|
||||
|
||||
Setup
|
||||
*****
|
||||
|
||||
1. **Install Dependencies with CMake**
|
||||
Install Dependencies with CMake
|
||||
--------------------------------
|
||||
|
||||
The recommended way to integrate the required libraries is using CMake's FetchContent:
|
||||
The recommended way to integrate the required libraries is using CMake's FetchContent:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
@@ -195,21 +160,27 @@ Setup
|
||||
# Link libraries to LVGL
|
||||
target_link_libraries(lvgl PUBLIC webp fastgltf)
|
||||
|
||||
2. **Enable glTF Support**
|
||||
|
||||
Set :c:macro:`LV_USE_GLTF` to ``1`` in ``lv_conf.h``.
|
||||
Enable glTF Support
|
||||
-------------------
|
||||
|
||||
Also enable other required dependencies by setting the following defines to ``1``:
|
||||
Set :c:macro:`LV_USE_GLTF` to ``1`` in ``lv_conf.h``.
|
||||
|
||||
- :c:macro:`LV_USE_OPENGLES`
|
||||
- :c:macro:`LV_USE_DRAW_OPENGLES`
|
||||
- :c:macro:`LV_USE_3DTEXTURE`
|
||||
Also enable other required dependencies by setting the following defines to ``1``:
|
||||
|
||||
3. **Setup OpenGL ES Driver**
|
||||
- :c:macro:`LV_USE_OPENGLES`
|
||||
- :c:macro:`LV_USE_DRAW_OPENGLES`
|
||||
- :c:macro:`LV_USE_3DTEXTURE`
|
||||
|
||||
Follow the OpenGL ES driver setup documentation (:ref:`opengl_driver`) to configure GLFW and OpenGL ES support for your platform.
|
||||
|
||||
4. **Basic Setup Example**
|
||||
Setup OpenGL ES Driver
|
||||
-----------------------
|
||||
|
||||
Follow the OpenGL ES driver setup documentation (:ref:`opengl_driver`) to configure GLFW and OpenGL ES support for your platform.
|
||||
|
||||
|
||||
Basic Setup Example
|
||||
-------------------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -237,6 +208,8 @@ Setup
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
*****
|
||||
|
||||
@@ -257,8 +230,9 @@ This demo creates an interactive 3D viewer with:
|
||||
- Camera switching
|
||||
- Visual settings adjustment
|
||||
|
||||
|
||||
Basic glTF Viewer Creation
|
||||
--------------------------
|
||||
---------------------------
|
||||
|
||||
Here's how to create a basic glTF viewer and load a model:
|
||||
|
||||
@@ -276,6 +250,7 @@ Here's how to create a basic glTF viewer and load a model:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Camera Controls
|
||||
---------------
|
||||
|
||||
@@ -301,6 +276,7 @@ The glTF viewer provides comprehensive camera controls:
|
||||
/* Recenter camera on model */
|
||||
lv_gltf_recenter(gltf, model);
|
||||
|
||||
|
||||
Animation Control
|
||||
-----------------
|
||||
|
||||
@@ -321,6 +297,7 @@ Control model animations with these functions:
|
||||
lv_gltf_model_pause_animation(model);
|
||||
bool is_paused = lv_gltf_model_is_animation_paused(model);
|
||||
|
||||
|
||||
Visual Settings
|
||||
---------------
|
||||
|
||||
@@ -339,6 +316,100 @@ Customize the visual appearance of your 3D scene:
|
||||
/* Anti-aliasing */
|
||||
lv_gltf_set_antialiasing_mode(gltf, LV_GLTF_AA_DYNAMIC);
|
||||
|
||||
|
||||
Image-Based Lighting (IBL)
|
||||
---------------------------
|
||||
|
||||
IBL (Image-Based Lighting) uses 360° panoramic images to light and shade 3D models, creating realistic reflections and environmental effects.
|
||||
Unlike traditional mathematical lighting (where light sources are calculated with approximation functions),
|
||||
IBL captures the entire lighting environment in an image, producing natural-looking results with:
|
||||
|
||||
- **Realistic reflections** on shiny surfaces that mirror the environment
|
||||
- **Ambient lighting** from all directions with proper color tinting
|
||||
- **Subtle lighting effects** like under-lighting and color variation based on viewing angle
|
||||
- **Visual cohesiveness** that makes models appear naturally placed in their environment
|
||||
|
||||
For example, using an High-Dynamic-Range (HDR) image of a forest will make your 3D model appear to be sitting in a forest.
|
||||
|
||||
Default Behavior
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
By default, each glTF viewer automatically creates an environment using an embedded default image with a cube map resolution of 128.
|
||||
This provides good visual quality for most use cases without any setup.
|
||||
|
||||
Custom Environments
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For more control over lighting quality, to use custom HDR images, or to share environments across multiple viewers, you can create and manage environments manually:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* Create an IBL sampler with custom resolution */
|
||||
lv_gltf_ibl_sampler_t * sampler = lv_gltf_ibl_sampler_create();
|
||||
|
||||
/* Set a custom cube map resolution. Higher resolution produces sharper results at a cost of longer setup time */
|
||||
lv_gltf_ibl_sampler_set_cube_map_pixel_resolution(256);
|
||||
|
||||
/* Create environment from custom HDR/JPEG image (or NULL for default) */
|
||||
lv_gltf_environment_t * env = lv_gltf_environment_create(sampler, "/path/to/environment.hdr");
|
||||
|
||||
/* Sampler can be deleted after environment creation */
|
||||
lv_gltf_ibl_sampler_delete(sampler);
|
||||
|
||||
/* Apply environment to viewer */
|
||||
lv_gltf_set_environment(gltf, env);
|
||||
|
||||
/* Optionally rotate the environment lighting */
|
||||
lv_gltf_environment_set_angle(env, 45.0f);
|
||||
|
||||
|
||||
Sharing Environments
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The same environment can be shared across multiple glTF viewers for consistent lighting and reduced memory usage:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
lv_obj_t * gltf1 = lv_gltf_create(lv_screen_active());
|
||||
lv_obj_t * gltf2 = lv_gltf_create(lv_screen_active());
|
||||
|
||||
/* Create shared environment */
|
||||
lv_gltf_ibl_sampler_t * sampler = lv_gltf_ibl_sampler_create();
|
||||
lv_gltf_environment_t * env = lv_gltf_environment_create(sampler, NULL);
|
||||
lv_gltf_ibl_sampler_delete(sampler);
|
||||
|
||||
/* Apply to multiple viewers */
|
||||
/* Note that the user owns the environment and is responsible for deleting it when
|
||||
all glTF objects are deleted */
|
||||
lv_gltf_set_environment(gltf1, env);
|
||||
lv_gltf_set_environment(gltf2, env);
|
||||
|
||||
|
||||
Environment Images
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Use equirectangular (360°) panoramic images in HDR or JPEG format
|
||||
- Source images are converted to cube map format at the sampler's cube map resolution
|
||||
- Higher resolution values (256-512) provide better quality but use more memory
|
||||
- Lower resolution values (64-128) are more suitable for embedded systems
|
||||
- Free HDR environment maps are widely available online. Choose environments that match the "look" you want (outdoor, studio, warehouse, etc.)
|
||||
|
||||
|
||||
How It Works
|
||||
~~~~~~~~~~~~
|
||||
|
||||
When an environment is created, the source image is processed into a cube map format (6 images representing each face of a cube).
|
||||
During rendering, for each pixel of your 3D model, the renderer samples the appropriate point from this cube map data to determine lighting color and intensity.
|
||||
The processing cost is paid once during environment creation.
|
||||
|
||||
|
||||
Performance Notes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Environment creation processes the source image into cube map data, which takes more time with larger resolution values
|
||||
- Processing time increases with both source image resolution and cube map resolution
|
||||
|
||||
|
||||
Multi-Model Support
|
||||
-------------------
|
||||
|
||||
@@ -355,6 +426,7 @@ Load and manage multiple glTF models in a single viewer:
|
||||
lv_gltf_model_t * primary = lv_gltf_get_primary_model(gltf);
|
||||
lv_gltf_model_t * specific = lv_gltf_get_model_by_index(gltf, 1);
|
||||
|
||||
|
||||
Model Inspection
|
||||
----------------
|
||||
|
||||
@@ -371,6 +443,8 @@ Query model properties to understand its structure:
|
||||
size_t scene_count = lv_gltf_model_get_scene_count(model);
|
||||
size_t camera_count = lv_gltf_model_get_camera_count(model);
|
||||
|
||||
|
||||
|
||||
Widget Architecture
|
||||
*******************
|
||||
|
||||
@@ -379,6 +453,7 @@ The glTF widget extends the ``lv_3dtexture`` widget, which means:
|
||||
- All standard ``lv_obj`` functions work with glTF widgets (positioning, sizing, styling, etc.)
|
||||
- All ``lv_3dtexture`` functions are also available for advanced 3D texture management
|
||||
|
||||
|
||||
Animation Speed System
|
||||
----------------------
|
||||
|
||||
@@ -389,6 +464,8 @@ Animation speeds use integer values to avoid floating-point arithmetic:
|
||||
- Values greater than 1000 speed up animations (e.g., 2000 = 2.0x speed)
|
||||
- Values less than 1000 slow down animations (e.g., 500 = 0.5x speed)
|
||||
|
||||
|
||||
|
||||
.. _gltf_example:
|
||||
|
||||
Examples
|
||||
@@ -396,6 +473,8 @@ Examples
|
||||
|
||||
.. include:: ../../examples/libs/gltf/index.rst
|
||||
|
||||
|
||||
|
||||
.. _gltf_api:
|
||||
|
||||
API
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Open a GLTF from a file and make it spin forever like a platter
|
||||
Open a glTF from a file and make it spin forever like a platter
|
||||
---------------------------------------------------------------
|
||||
|
||||
.. lv_example:: libs/gltf/lv_example_gltf_1
|
||||
:language: c
|
||||
|
||||
|
||||
Open a GLTF from a file and iterate through each camera
|
||||
Open a glTF from a file and iterate through each camera
|
||||
-------------------------------------------------------
|
||||
|
||||
.. lv_example:: libs/gltf/lv_example_gltf_2
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* @file lv_gltf_environment.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GLTF_ENVIRONMENT_H
|
||||
#define LV_GLTF_ENVIRONMENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GLTF
|
||||
|
||||
#include "../../../misc/lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_GLTF_DEFAULT_CUBE_MAP_RESOLUTION 128
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an IBL sampler for processing environment images
|
||||
* @return pointer to the created sampler, or NULL on failure
|
||||
* @note Can be safely deleted after environments are created
|
||||
*/
|
||||
lv_gltf_ibl_sampler_t * lv_gltf_ibl_sampler_create(void);
|
||||
|
||||
/**
|
||||
* Set the resolution for each cubemap face
|
||||
* @param pointer to a sampler
|
||||
* @param resolution of each cube map face in pixels (recommended: 64-512 for embedded)
|
||||
*/
|
||||
void lv_gltf_ibl_sampler_set_cube_map_pixel_resolution(lv_gltf_ibl_sampler_t * sampler, uint32_t resolution);
|
||||
|
||||
/**
|
||||
* Delete an IBL sampler
|
||||
* @param sampler pointer to the sampler to delete
|
||||
*/
|
||||
void lv_gltf_ibl_sampler_delete(lv_gltf_ibl_sampler_t * sampler);
|
||||
|
||||
/**
|
||||
* Create an environment from an HDR or JPEG panoramic image for IBL rendering
|
||||
* @param sampler IBL sampler defining output resolution (can be deleted after this call)
|
||||
* @param file_path path to equirectangular environment image, or NULL to use default embedded image
|
||||
* @return pointer to the created environment, or NULL on failure
|
||||
*
|
||||
* @note The source image will be downsampled to the sampler's texture_size
|
||||
* @note The environment can be shared across multiple glTF objects
|
||||
*/
|
||||
lv_gltf_environment_t * lv_gltf_environment_create(lv_gltf_ibl_sampler_t * sampler, const char * file_path);
|
||||
|
||||
/**
|
||||
* Set the rotation angle of the environment map
|
||||
* @param env pointer to the environment
|
||||
* @param angle rotation angle in degrees
|
||||
*/
|
||||
void lv_gltf_environment_set_angle(lv_gltf_environment_t * env, float angle);
|
||||
|
||||
/**
|
||||
* Delete an environment
|
||||
* @param environment pointer to the environment to delete
|
||||
*/
|
||||
void lv_gltf_environment_delete(lv_gltf_environment_t * environment);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GLTF*/
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_GLTF_ENVIRONMENT_H*/
|
||||
|
||||
|
||||
+26
-16
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @file lv_gltf_ibl_sampler.h
|
||||
* @file lv_gltf_environment_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GLTF_IBL_SAMPLER_H
|
||||
#define LV_GLTF_IBL_SAMPLER_H
|
||||
#ifndef LV_GLTF_ENVIRONMENT_PRIVATE_H
|
||||
#define LV_GLTF_ENVIRONMENT_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -13,12 +13,12 @@ extern "C" {
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../../lv_conf_internal.h"
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_GLTF
|
||||
#include "../../../../misc/lv_types.h"
|
||||
#include "../../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h"
|
||||
#include "../lv_gltf_view_internal.h"
|
||||
|
||||
#include "lv_gltf_environment.h"
|
||||
#include "../../../misc/lv_types.h"
|
||||
#include "../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -28,12 +28,12 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
uint32_t texture_size;
|
||||
struct _lv_gltf_ibl_sampler {
|
||||
uint32_t cube_map_resolution;
|
||||
float lod_bias;
|
||||
uint32_t lowest_mip_level;
|
||||
uint32_t input_texture_id;
|
||||
uint32_t cubemap_texture_id;
|
||||
uint32_t cube_map_texture_id;
|
||||
uint32_t framebuffer;
|
||||
uint32_t mipmap_count;
|
||||
|
||||
@@ -61,7 +61,7 @@ typedef struct {
|
||||
uint32_t fullscreen_vertex_buffer;
|
||||
uint32_t fullscreen_tex_coord_buffer;
|
||||
|
||||
} lv_gltf_ibl_sampler_t;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t * data;
|
||||
@@ -77,20 +77,30 @@ typedef struct {
|
||||
uint32_t height;
|
||||
} lv_gltf_ibl_image_t;
|
||||
|
||||
struct _lv_gltf_environment {
|
||||
uint32_t diffuse;
|
||||
uint32_t specular;
|
||||
uint32_t sheen;
|
||||
uint32_t ggxLut;
|
||||
uint32_t charlie_lut;
|
||||
uint32_t mip_count;
|
||||
float ibl_intensity_scale;
|
||||
float angle;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_gltf_ibl_generate_env_textures(lv_gltf_view_env_textures_t * env, const char * env_file_path,
|
||||
float env_rotation);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GLTF*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_GLTF_IBL_SAMPLER_H*/
|
||||
#endif /*LV_GLTF_ENVIRONMENT_PRIVATE_H*/
|
||||
|
||||
+117
-62
@@ -7,22 +7,22 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_gltf_ibl_sampler.h"
|
||||
#include "lv_gltf_environment_private.h"
|
||||
|
||||
#if LV_USE_GLTF
|
||||
|
||||
#include "../../../../misc/lv_math.h"
|
||||
#include "../../../../misc/lv_log.h"
|
||||
#include "../../../../stdlib/lv_string.h"
|
||||
#include "../../../../drivers/opengles/lv_opengles_private.h"
|
||||
#include "../../../../drivers/opengles/lv_opengles_debug.h"
|
||||
#include "../../../misc/lv_math.h"
|
||||
#include "../../../misc/lv_log.h"
|
||||
#include "../../../stdlib/lv_sprintf.h"
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
#include "../../../drivers/opengles/lv_opengles_private.h"
|
||||
#include "../../../drivers/opengles/lv_opengles_debug.h"
|
||||
|
||||
#include "../../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h"
|
||||
#include "../lv_gltf_view_internal.h"
|
||||
#include "../assets/lv_gltf_view_shader.h"
|
||||
#include "../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h"
|
||||
#include "../gltf_view/assets/lv_gltf_view_shader.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "../../stb_image/stb_image.h"
|
||||
#include "../stb_image/stb_image.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -39,7 +39,6 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void ibl_sampler_init(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_sampler_load(lv_gltf_ibl_sampler_t * sampler, const char * path);
|
||||
static void ibl_sampler_filter(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_sampler_destroy(lv_gltf_ibl_sampler_t * sampler);
|
||||
@@ -47,14 +46,14 @@ static bool ibl_gl_has_extension(const char * extension);
|
||||
static void ibl_texture_from_image(lv_gltf_ibl_sampler_t * sampler, lv_gltf_ibl_texture_t * texture,
|
||||
const lv_gltf_ibl_image_t * image);
|
||||
static GLuint ibl_load_texture_hdr(lv_gltf_ibl_sampler_t * sampler, const lv_gltf_ibl_image_t * image);
|
||||
static GLuint ibl_create_cubemap_texture(const lv_gltf_ibl_sampler_t * sampler, bool with_mipmaps);
|
||||
static GLuint ibl_create_cube_map_texture(const lv_gltf_ibl_sampler_t * sampler, bool with_mipmaps);
|
||||
static uint32_t ibl_create_lut_texture(const lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_panorama_to_cubemap(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_apply_filter(lv_gltf_ibl_sampler_t * sampler, uint32_t distribution, float roughness,
|
||||
uint32_t target_mip_level, GLuint target_texture, uint32_t sample_count, float lod_bias);
|
||||
static void ibl_cubemap_to_lambertian(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_cubemap_to_ggx(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_cubemap_to_sheen(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_cube_map_to_lambertian(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_cube_map_to_ggx(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_cube_map_to_sheen(lv_gltf_ibl_sampler_t * sampler);
|
||||
static void ibl_sample_lut(lv_gltf_ibl_sampler_t * sampler, uint32_t distribution, uint32_t targetTexture,
|
||||
uint32_t currentTextureSize);
|
||||
static void ibl_sample_ggx_lut(lv_gltf_ibl_sampler_t * sampler);
|
||||
@@ -76,33 +75,16 @@ static void draw_fullscreen_quad(lv_gltf_ibl_sampler_t * sampler, GLuint program
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_gltf_ibl_generate_env_textures(lv_gltf_view_env_textures_t * env, const char * path, float env_rotation)
|
||||
lv_gltf_ibl_sampler_t * lv_gltf_ibl_sampler_create(void)
|
||||
{
|
||||
lv_gltf_ibl_sampler_t sampler;
|
||||
lv_gltf_ibl_sampler_t * sampler = lv_zalloc(sizeof(*sampler));
|
||||
LV_ASSERT_MALLOC(sampler)
|
||||
if(!sampler) {
|
||||
LV_LOG_WARN("Failed to create sampler");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ibl_sampler_init(&sampler);
|
||||
ibl_sampler_load(&sampler, path);
|
||||
ibl_sampler_filter(&sampler);
|
||||
|
||||
env->angle = env_rotation;
|
||||
env->diffuse = sampler.lambertian_texture_id;
|
||||
env->specular = sampler.ggx_texture_id;
|
||||
env->sheen = sampler.sheen_texture_id;
|
||||
env->ggxLut = sampler.ggxlut_texture_id;
|
||||
env->charlie_lut = sampler.charlielut_texture_id;
|
||||
env->mip_count = sampler.mipmap_levels;
|
||||
env->ibl_intensity_scale = sampler.scale_value;
|
||||
ibl_sampler_destroy(&sampler);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void ibl_sampler_init(lv_gltf_ibl_sampler_t * sampler)
|
||||
{
|
||||
lv_memset(sampler, 0, sizeof(*sampler));
|
||||
sampler->texture_size = 128;
|
||||
sampler->cube_map_resolution = LV_GLTF_DEFAULT_CUBE_MAP_RESOLUTION;
|
||||
sampler->ggx_sample_count = 128;
|
||||
sampler->lambertian_sample_count = 256;
|
||||
sampler->sheen_sample_count = 32;
|
||||
@@ -111,13 +93,86 @@ static void ibl_sampler_init(lv_gltf_ibl_sampler_t * sampler)
|
||||
sampler->lut_resolution = 1024;
|
||||
sampler->lut_sample_count = 64;
|
||||
sampler->scale_value = 1.0;
|
||||
|
||||
lv_opengl_shader_portions_t env_shader_portions;
|
||||
lv_gltf_view_shader_get_env(&env_shader_portions);
|
||||
lv_opengl_shader_manager_init(&sampler->shader_manager, env_shader_portions.all, env_shader_portions.count, NULL,
|
||||
NULL);
|
||||
init_fullscreen_quad(sampler);
|
||||
return sampler;
|
||||
}
|
||||
|
||||
void lv_gltf_ibl_sampler_set_cube_map_pixel_resolution(lv_gltf_ibl_sampler_t * sampler, uint32_t resolution)
|
||||
{
|
||||
if(!sampler) {
|
||||
LV_LOG_WARN("Can't set cube map resolution on a NULL sampler");
|
||||
return;
|
||||
}
|
||||
if(resolution == 0) {
|
||||
LV_LOG_WARN("Cube map resolution should be > 0");
|
||||
return;
|
||||
}
|
||||
sampler->cube_map_resolution = resolution;
|
||||
}
|
||||
|
||||
void lv_gltf_ibl_sampler_delete(lv_gltf_ibl_sampler_t * sampler)
|
||||
{
|
||||
if(!sampler) {
|
||||
LV_LOG_WARN("Can't delete a NULL sampler");
|
||||
return;
|
||||
}
|
||||
|
||||
ibl_sampler_destroy(sampler);
|
||||
lv_free(sampler);
|
||||
}
|
||||
|
||||
void lv_gltf_environment_set_angle(lv_gltf_environment_t * env, float angle)
|
||||
{
|
||||
if(!env) {
|
||||
LV_LOG_WARN("Can't set angle on a NULL environment");
|
||||
return;
|
||||
}
|
||||
env->angle = angle;
|
||||
}
|
||||
|
||||
lv_gltf_environment_t * lv_gltf_environment_create(lv_gltf_ibl_sampler_t * sampler, const char * file_path)
|
||||
{
|
||||
if(!sampler) {
|
||||
LV_LOG_WARN("Can't create an environment with a NULL sampler");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_gltf_environment_t * env = lv_zalloc(sizeof(*env));
|
||||
LV_ASSERT_MALLOC(env);
|
||||
if(!env) {
|
||||
LV_LOG_WARN("Failed to create environment");
|
||||
return NULL;
|
||||
}
|
||||
ibl_sampler_load(sampler, file_path);
|
||||
ibl_sampler_filter(sampler);
|
||||
|
||||
env->diffuse = sampler->lambertian_texture_id;
|
||||
env->specular = sampler->ggx_texture_id;
|
||||
env->sheen = sampler->sheen_texture_id;
|
||||
env->ggxLut = sampler->ggxlut_texture_id;
|
||||
env->charlie_lut = sampler->charlielut_texture_id;
|
||||
env->mip_count = sampler->mipmap_levels;
|
||||
env->ibl_intensity_scale = sampler->scale_value;
|
||||
return env;
|
||||
}
|
||||
|
||||
void lv_gltf_environment_delete(lv_gltf_environment_t * env)
|
||||
{
|
||||
const unsigned int d[3] = { env->diffuse, env->specular, env->sheen };
|
||||
GL_CALL(glDeleteTextures(3, d));
|
||||
lv_free(env);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void ibl_sampler_load(lv_gltf_ibl_sampler_t * sampler, const char * path)
|
||||
{
|
||||
// vv -- WebGL Naming
|
||||
@@ -159,16 +214,16 @@ static void ibl_sampler_load(lv_gltf_ibl_sampler_t * sampler, const char * path)
|
||||
GL_CALL(glGenFramebuffers(1, &sampler->framebuffer));
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, sampler->framebuffer));
|
||||
|
||||
sampler->cubemap_texture_id = ibl_create_cubemap_texture(sampler, true);
|
||||
sampler->lambertian_texture_id = ibl_create_cubemap_texture(sampler, false);
|
||||
sampler->ggx_texture_id = ibl_create_cubemap_texture(sampler, true);
|
||||
sampler->sheen_texture_id = ibl_create_cubemap_texture(sampler, true);
|
||||
sampler->cube_map_texture_id = ibl_create_cube_map_texture(sampler, true);
|
||||
sampler->lambertian_texture_id = ibl_create_cube_map_texture(sampler, false);
|
||||
sampler->ggx_texture_id = ibl_create_cube_map_texture(sampler, true);
|
||||
sampler->sheen_texture_id = ibl_create_cube_map_texture(sampler, true);
|
||||
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->ggx_texture_id));
|
||||
GL_CALL(glGenerateMipmap(GL_TEXTURE_CUBE_MAP));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->sheen_texture_id));
|
||||
GL_CALL(glGenerateMipmap(GL_TEXTURE_CUBE_MAP));
|
||||
sampler->mipmap_levels = ibl_count_bits(sampler->texture_size) + 1 - sampler->lowest_mip_level;
|
||||
sampler->mipmap_levels = ibl_count_bits(sampler->cube_map_resolution) + 1 - sampler->lowest_mip_level;
|
||||
}
|
||||
|
||||
static void ibl_sampler_filter(lv_gltf_ibl_sampler_t * sampler)
|
||||
@@ -179,13 +234,13 @@ static void ibl_sampler_filter(lv_gltf_ibl_sampler_t * sampler)
|
||||
ibl_panorama_to_cubemap(sampler);
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer));
|
||||
|
||||
ibl_cubemap_to_lambertian(sampler);
|
||||
ibl_cube_map_to_lambertian(sampler);
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer));
|
||||
|
||||
ibl_cubemap_to_ggx(sampler);
|
||||
ibl_cube_map_to_ggx(sampler);
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer));
|
||||
|
||||
ibl_cubemap_to_sheen(sampler);
|
||||
ibl_cube_map_to_sheen(sampler);
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer));
|
||||
|
||||
ibl_sample_ggx_lut(sampler);
|
||||
@@ -274,14 +329,14 @@ static uint32_t ibl_load_texture_hdr(lv_gltf_ibl_sampler_t * sampler, const lv_g
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
static GLuint ibl_create_cubemap_texture(const lv_gltf_ibl_sampler_t * sampler, bool with_mipmaps)
|
||||
static GLuint ibl_create_cube_map_texture(const lv_gltf_ibl_sampler_t * sampler, bool with_mipmaps)
|
||||
{
|
||||
uint32_t targetTexture;
|
||||
GL_CALL(glGenTextures(1, &targetTexture));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, targetTexture));
|
||||
for(int32_t i = 0; i < 6; ++i) {
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, INTERNAL_FORMAT, sampler->texture_size,
|
||||
sampler->texture_size, 0, GL_RGBA, TEXTURE_TARGET_TYPE, NULL));
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, INTERNAL_FORMAT, sampler->cube_map_resolution,
|
||||
sampler->cube_map_resolution, 0, GL_RGBA, TEXTURE_TARGET_TYPE, NULL));
|
||||
}
|
||||
if(with_mipmaps) {
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
|
||||
@@ -312,15 +367,15 @@ static void ibl_panorama_to_cubemap(lv_gltf_ibl_sampler_t * sampler)
|
||||
for(int32_t i = 0; i < 6; ++i) {
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, sampler->framebuffer));
|
||||
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
|
||||
sampler->cubemap_texture_id, 0));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id));
|
||||
sampler->cube_map_texture_id, 0));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cube_map_texture_id));
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
while(status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
LV_LOG_ERROR("Environnement render error not complete. Expected %d. Got %d", GL_FRAMEBUFFER_COMPLETE,
|
||||
status);
|
||||
}
|
||||
GL_CALL(glViewport(0, 0, sampler->texture_size, sampler->texture_size));
|
||||
GL_CALL(glViewport(0, 0, sampler->cube_map_resolution, sampler->cube_map_resolution));
|
||||
GL_CALL(glClearColor(1.0, 0.0, 0.0, 0.0));
|
||||
GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||
uint32_t frag_shader_hash;
|
||||
@@ -352,13 +407,13 @@ static void ibl_panorama_to_cubemap(lv_gltf_ibl_sampler_t * sampler)
|
||||
draw_fullscreen_quad(sampler, program_id);
|
||||
}
|
||||
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cube_map_texture_id));
|
||||
GL_CALL(glGenerateMipmap(GL_TEXTURE_CUBE_MAP));
|
||||
}
|
||||
static void ibl_apply_filter(lv_gltf_ibl_sampler_t * sampler, uint32_t distribution, float roughness,
|
||||
uint32_t target_mip_level, GLuint target_texture, uint32_t sample_count, float lod_bias)
|
||||
{
|
||||
uint32_t current_texture_size = sampler->texture_size >> target_mip_level;
|
||||
uint32_t current_texture_size = sampler->cube_map_resolution >> target_mip_level;
|
||||
for(uint32_t i = 0; i < 6; ++i) {
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, sampler->framebuffer));
|
||||
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
|
||||
@@ -387,7 +442,7 @@ static void ibl_apply_filter(lv_gltf_ibl_sampler_t * sampler, uint32_t distribut
|
||||
GL_CALL(glUseProgram(program_id));
|
||||
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
||||
// Bind texture ID to active texture
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cube_map_texture_id));
|
||||
// map shader uniform to texture unit (TEXTURE0)
|
||||
uint32_t location = glGetUniformLocation(program_id, "u_cubemapTexture");
|
||||
GL_CALL(glUniform1i(location, 0)); // texture unit 0
|
||||
@@ -396,7 +451,7 @@ static void ibl_apply_filter(lv_gltf_ibl_sampler_t * sampler, uint32_t distribut
|
||||
/* Software rendered mode looks better with this and horrible with below */
|
||||
/*program->update_uniform_1i(program, "u_width", current_texture_size); */
|
||||
/* Standard mode looks best with this and somewhat worse with above */
|
||||
program->update_uniform_1i(program, "u_width", sampler->texture_size);
|
||||
program->update_uniform_1i(program, "u_width", sampler->cube_map_resolution);
|
||||
program->update_uniform_1f(program, "u_lodBias", lod_bias);
|
||||
program->update_uniform_1i(program, "u_distribution", distribution);
|
||||
program->update_uniform_1i(program, "u_currentFace", i);
|
||||
@@ -407,11 +462,11 @@ static void ibl_apply_filter(lv_gltf_ibl_sampler_t * sampler, uint32_t distribut
|
||||
draw_fullscreen_quad(sampler, program_id);
|
||||
}
|
||||
}
|
||||
static void ibl_cubemap_to_lambertian(lv_gltf_ibl_sampler_t * sampler)
|
||||
static void ibl_cube_map_to_lambertian(lv_gltf_ibl_sampler_t * sampler)
|
||||
{
|
||||
ibl_apply_filter(sampler, 0, 0.0, 0, sampler->lambertian_texture_id, sampler->lambertian_sample_count, 0.0);
|
||||
}
|
||||
static void ibl_cubemap_to_ggx(lv_gltf_ibl_sampler_t * sampler)
|
||||
static void ibl_cube_map_to_ggx(lv_gltf_ibl_sampler_t * sampler)
|
||||
{
|
||||
LV_ASSERT(sampler->mipmap_levels != 1);
|
||||
for(uint32_t current_mip_level = 0; current_mip_level <= sampler->mipmap_levels; ++current_mip_level) {
|
||||
@@ -420,7 +475,7 @@ static void ibl_cubemap_to_ggx(lv_gltf_ibl_sampler_t * sampler)
|
||||
0.0);
|
||||
}
|
||||
}
|
||||
static void ibl_cubemap_to_sheen(lv_gltf_ibl_sampler_t * sampler)
|
||||
static void ibl_cube_map_to_sheen(lv_gltf_ibl_sampler_t * sampler)
|
||||
{
|
||||
LV_ASSERT(sampler->mipmap_levels != 1);
|
||||
for(uint32_t current_mip_level = 0; current_mip_level <= sampler->mipmap_levels; ++current_mip_level) {
|
||||
@@ -457,7 +512,7 @@ static void ibl_sample_lut(lv_gltf_ibl_sampler_t * sampler, uint32_t distributio
|
||||
// TEXTURE0 = active.
|
||||
GL_CALL(glActiveTexture(GL_TEXTURE0 + 0));
|
||||
// Bind texture ID to active texture
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cube_map_texture_id));
|
||||
// map shader uniform to texture unit (TEXTURE0)
|
||||
uint32_t location = glGetUniformLocation(program_id, "u_cubemapTexture");
|
||||
GL_CALL(glUniform1i(location, 0)); // texture unit 0
|
||||
@@ -70,82 +70,92 @@ typedef lv_3dplane_t lv_3dray_t;
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a GLTF viewer object
|
||||
* Create a glTF object
|
||||
* @param parent pointer to the parent object
|
||||
* @return pointer to the created GLTF viewer object
|
||||
* @return pointer to the created glTF object
|
||||
*/
|
||||
lv_obj_t * lv_gltf_create(lv_obj_t * parent);
|
||||
|
||||
/**
|
||||
* Load a GLTF model from a file into the viewer
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param path file path to the GLTF model to load
|
||||
* @return pointer to the loaded GLTF model, or NULL on failure
|
||||
* Assign an environment to a glTF object for IBL rendering
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param environment pointer to the environment to use
|
||||
* @note The environment can be shared across multiple glTF objects
|
||||
* @note If no environment is set before attempting to load a file,
|
||||
* a default one will be created for you
|
||||
*/
|
||||
void lv_gltf_set_environment(lv_obj_t * obj, lv_gltf_environment_t * environment);
|
||||
|
||||
/**
|
||||
* Load a glTF model from a file into the viewer
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param path file path to the glTF model to load
|
||||
* @return pointer to the loaded glTF model, or NULL on failure
|
||||
*/
|
||||
lv_gltf_model_t * lv_gltf_load_model_from_file(lv_obj_t * obj, const char * path);
|
||||
|
||||
/**
|
||||
* Get the number of models loaded in the GLTF viewer
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* Get the number of models loaded in the glTF viewer
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return the total number of models in the viewer
|
||||
*/
|
||||
size_t lv_gltf_get_model_count(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get a specific model by its index
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param id index of the model to retrieve (0-based)
|
||||
* @return pointer to the model at the specified index, or NULL if index is invalid
|
||||
*/
|
||||
lv_gltf_model_t * lv_gltf_get_model_by_index(lv_obj_t * obj, size_t id);
|
||||
|
||||
/**
|
||||
* Get the primary model from the GLTF viewer
|
||||
* Get the primary model from the glTF viewer
|
||||
* The primary model is the first model added to the viewer and can be used
|
||||
* for camera selection and other primary operations
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return pointer to the primary model, or NULL if no models are loaded
|
||||
*/
|
||||
lv_gltf_model_t * lv_gltf_get_primary_model(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the yaw (horizontal rotation) of the camera
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param yaw yaw angle in degrees
|
||||
*/
|
||||
void lv_gltf_set_yaw(lv_obj_t * obj, float yaw);
|
||||
|
||||
/**
|
||||
* Get the yaw (horizontal rotation) of the camera
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return yaw angle in degrees
|
||||
*/
|
||||
float lv_gltf_get_yaw(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the pitch (vertical rotation) of the camera
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param pitch pitch angle in degrees
|
||||
*/
|
||||
void lv_gltf_set_pitch(lv_obj_t * obj, float pitch);
|
||||
|
||||
/**
|
||||
* Get the pitch (vertical rotation) of the camera
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return pitch angle in degrees
|
||||
*/
|
||||
float lv_gltf_get_pitch(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the camera distance from the focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value distance value
|
||||
*/
|
||||
void lv_gltf_set_distance(lv_obj_t * obj, float value);
|
||||
|
||||
/**
|
||||
* Get the camera distance scale factor from the focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return distance scaling factor value
|
||||
*/
|
||||
float lv_gltf_get_distance(const lv_obj_t * obj);
|
||||
@@ -163,14 +173,14 @@ float lv_gltf_get_world_distance(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the field of view
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value vertical FOV in degrees. If zero, the view will be orthographic (non-perspective)
|
||||
*/
|
||||
void lv_gltf_set_fov(lv_obj_t * obj, float value);
|
||||
|
||||
/**
|
||||
* Get the field of view
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return vertical FOV in degrees
|
||||
*/
|
||||
float lv_gltf_get_fov(const lv_obj_t * obj);
|
||||
@@ -181,49 +191,49 @@ float lv_gltf_get_fov(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the X coordinate of the camera focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value X coordinate
|
||||
*/
|
||||
void lv_gltf_set_focal_x(lv_obj_t * obj, float value);
|
||||
|
||||
/**
|
||||
* Get the X coordinate of the camera focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return X coordinate
|
||||
*/
|
||||
float lv_gltf_get_focal_x(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the Y coordinate of the camera focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value Y coordinate
|
||||
*/
|
||||
void lv_gltf_set_focal_y(lv_obj_t * obj, float value);
|
||||
|
||||
/**
|
||||
* Get the Y coordinate of the camera focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return Y coordinate
|
||||
*/
|
||||
float lv_gltf_get_focal_y(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the Z coordinate of the camera focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value Z coordinate
|
||||
*/
|
||||
void lv_gltf_set_focal_z(lv_obj_t * obj, float value);
|
||||
|
||||
/**
|
||||
* Get the Z coordinate of the camera focal point
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return Z coordinate
|
||||
*/
|
||||
float lv_gltf_get_focal_z(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the focal coordinates to the center point of the model object
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param model a model attached to this viewer or NULL for the first model
|
||||
*/
|
||||
void lv_gltf_recenter(lv_obj_t * obj, lv_gltf_model_t * model);
|
||||
@@ -234,9 +244,9 @@ void lv_gltf_recenter(lv_obj_t * obj, lv_gltf_model_t * model);
|
||||
|
||||
/**
|
||||
* Set the active camera index
|
||||
* The camera is selected from the first GLTF model added to the viewer
|
||||
* The camera is selected from the first glTF model added to the viewer
|
||||
*
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value camera index (0 for default camera, 1+ for scene camera index)
|
||||
* @note Values higher than the scene's camera count will be clamped to the maximum available camera index
|
||||
*/
|
||||
@@ -244,20 +254,20 @@ void lv_gltf_set_camera(lv_obj_t * obj, uint32_t value);
|
||||
|
||||
/**
|
||||
* Get the active camera index
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return active camera index
|
||||
*/
|
||||
uint32_t lv_gltf_get_camera(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the number of cameras in the first GLTF model added to the viewer
|
||||
* Get the number of cameras in the first glTF model added to the viewer
|
||||
* This count represents the valid range for the camera index parameter
|
||||
* used with lv_gltf_set_camera()
|
||||
*
|
||||
* To get the camera count of other models, call
|
||||
* lv_gltf_model_get_camera_count(model) directly with the specific model
|
||||
*
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return number of available cameras
|
||||
*/
|
||||
uint32_t lv_gltf_get_camera_count(const lv_obj_t * obj);
|
||||
@@ -269,7 +279,7 @@ uint32_t lv_gltf_get_camera_count(const lv_obj_t * obj);
|
||||
* Values greater than LV_GLTF_ANIM_SPEED_NORMAL will speed-up the animation
|
||||
* Values less than LV_GLTF_ANIM_SPEED_NORMAL will slow down the animation
|
||||
*
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value speed-up ratio of the animation
|
||||
*/
|
||||
void lv_gltf_set_animation_speed(lv_obj_t * obj, uint32_t value);
|
||||
@@ -279,7 +289,7 @@ void lv_gltf_set_animation_speed(lv_obj_t * obj, uint32_t value);
|
||||
*
|
||||
* The actual ratio is the return value / LV_GLTF_ANIM_SPEED_NORMAL
|
||||
*
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
*/
|
||||
uint32_t lv_gltf_get_animation_speed(const lv_obj_t * obj);
|
||||
|
||||
@@ -289,56 +299,56 @@ uint32_t lv_gltf_get_animation_speed(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the background mode
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value background mode
|
||||
*/
|
||||
void lv_gltf_set_background_mode(lv_obj_t * obj, lv_gltf_bg_mode_t value);
|
||||
|
||||
/**
|
||||
* Get the background mode
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return background mode
|
||||
*/
|
||||
lv_gltf_bg_mode_t lv_gltf_get_background_mode(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the background blur amount
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value blur amount between 0 and 100
|
||||
*/
|
||||
void lv_gltf_set_background_blur(lv_obj_t * obj, uint32_t value);
|
||||
|
||||
/**
|
||||
* Get the background blur amount
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return blur amount between 0 and 100
|
||||
*/
|
||||
uint32_t lv_gltf_get_background_blur(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the environmental brightness/power
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value brightness multiplier
|
||||
*/
|
||||
void lv_gltf_set_env_brightness(lv_obj_t * obj, uint32_t value);
|
||||
|
||||
/**
|
||||
* Get the environmental brightness/power
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return brightness multiplier
|
||||
*/
|
||||
uint32_t lv_gltf_get_env_brightness(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the image exposure level
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value exposure level (1.0 is default)
|
||||
*/
|
||||
void lv_gltf_set_image_exposure(lv_obj_t * obj, float value);
|
||||
|
||||
/**
|
||||
* Get the image exposure level
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return exposure level
|
||||
*/
|
||||
float lv_gltf_get_image_exposure(const lv_obj_t * obj);
|
||||
@@ -349,14 +359,14 @@ float lv_gltf_get_image_exposure(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the anti-aliasing mode
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @param value anti-aliasing mode
|
||||
*/
|
||||
void lv_gltf_set_antialiasing_mode(lv_obj_t * obj, lv_gltf_aa_mode_t value);
|
||||
|
||||
/**
|
||||
* Get the anti-aliasing mode
|
||||
* @param obj pointer to a GLTF viewer object
|
||||
* @param obj pointer to a glTF viewer object
|
||||
* @return anti-aliasing mode
|
||||
*/
|
||||
lv_gltf_aa_mode_t lv_gltf_get_antialiasing_mode(const lv_obj_t * obj);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "../../../core/lv_obj_class_private.h"
|
||||
#include "../../../misc/lv_types.h"
|
||||
#include "../../../widgets/3dtexture/lv_3dtexture.h"
|
||||
#include "ibl/lv_gltf_ibl_sampler.h"
|
||||
#include "../gltf_environment/lv_gltf_environment.h"
|
||||
#include "assets/lv_gltf_view_shader.h"
|
||||
#include <fastgltf/math.hpp>
|
||||
#include <fastgltf/tools.hpp>
|
||||
@@ -49,10 +49,12 @@ static void lv_gltf_event(const lv_obj_class_t * class_p, lv_event_t * e);
|
||||
static void lv_gltf_view_state_init(lv_gltf_t * state);
|
||||
static void lv_gltf_view_desc_init(lv_gltf_view_desc_t * state);
|
||||
static void lv_gltf_parse_model(lv_gltf_t * viewer, lv_gltf_model_t * model);
|
||||
static void destroy_environment(lv_gltf_view_env_textures_t * env);
|
||||
static void destroy_environment(lv_gltf_environment_t * env);
|
||||
static void setup_compile_and_load_bg_shader(lv_opengl_shader_manager_t * manager);
|
||||
static void setup_background_environment(GLuint program, GLuint * vao, GLuint * indexBuffer, GLuint * vertexBuffer);
|
||||
|
||||
static lv_result_t create_default_environment(lv_gltf_t * gltf);
|
||||
|
||||
|
||||
const lv_obj_class_t lv_gltf_class = {
|
||||
&lv_3dtexture_class,
|
||||
@@ -101,6 +103,14 @@ lv_gltf_model_t * lv_gltf_load_model_from_file(lv_obj_t * obj, const char * path
|
||||
LV_ASSERT_NULL(obj);
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_gltf_t * viewer = (lv_gltf_t *)obj;
|
||||
|
||||
if(!viewer->environment) {
|
||||
lv_result_t res = create_default_environment(viewer);
|
||||
if(res != LV_RESULT_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lv_gltf_model_t * model = lv_gltf_data_load_from_file(path, &viewer->shader_manager);
|
||||
return lv_gltf_add_model(viewer, model);
|
||||
}
|
||||
@@ -110,9 +120,33 @@ lv_gltf_model_t * lv_gltf_load_model_from_bytes(lv_obj_t * obj, const uint8_t *
|
||||
LV_ASSERT_NULL(obj);
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_gltf_t * viewer = (lv_gltf_t *)obj;
|
||||
|
||||
if(!viewer->environment) {
|
||||
lv_result_t res = create_default_environment(viewer);
|
||||
if(res != LV_RESULT_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lv_gltf_model_t * model = lv_gltf_data_load_from_bytes(bytes, len, &viewer->shader_manager);
|
||||
return lv_gltf_add_model(viewer, model);
|
||||
}
|
||||
void lv_gltf_set_environment(lv_obj_t * obj, lv_gltf_environment_t * env)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_gltf_t * gltf = (lv_gltf_t *)obj;
|
||||
if(env == NULL) {
|
||||
LV_LOG_WARN("Refusing to assign a NULL environment to the glTF object");
|
||||
return;
|
||||
}
|
||||
|
||||
if(gltf->environment && gltf->owns_environment) {
|
||||
lv_gltf_environment_delete(gltf->environment);
|
||||
gltf->environment = NULL;
|
||||
}
|
||||
gltf->environment = env;
|
||||
gltf->owns_environment = false;
|
||||
}
|
||||
|
||||
size_t lv_gltf_get_model_count(lv_obj_t * obj)
|
||||
{
|
||||
@@ -556,7 +590,6 @@ lv_result_t lv_gltf_world_to_screen(lv_obj_t * obj, const lv_3dpoint_t world_pos
|
||||
|
||||
static lv_gltf_model_t * lv_gltf_add_model(lv_gltf_t * viewer, lv_gltf_model_t * model)
|
||||
{
|
||||
|
||||
if(!model) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -575,6 +608,18 @@ static lv_gltf_model_t * lv_gltf_add_model(lv_gltf_t * viewer, lv_gltf_model_t *
|
||||
return model;
|
||||
}
|
||||
|
||||
static lv_result_t create_default_environment(lv_gltf_t * gltf)
|
||||
{
|
||||
lv_gltf_ibl_sampler_t * sampler = lv_gltf_ibl_sampler_create();
|
||||
gltf->environment = lv_gltf_environment_create(sampler, NULL);
|
||||
lv_gltf_ibl_sampler_delete(sampler);
|
||||
if(!gltf->environment) {
|
||||
LV_LOG_WARN("Failed to create default gltf environment");
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
gltf->owns_environment = true;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
static void lv_gltf_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
{
|
||||
@@ -599,8 +644,6 @@ static void lv_gltf_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
lv_free(vertex_shader);
|
||||
lv_free(frag_shader);
|
||||
|
||||
lv_gltf_ibl_generate_env_textures(&view->env_textures, NULL, 0);
|
||||
|
||||
lv_array_init(&view->models, LV_GLTF_INITIAL_MODEL_CAPACITY, sizeof(lv_gltf_model_t *));
|
||||
|
||||
LV_TRACE_OBJ_CREATE("end");
|
||||
@@ -638,7 +681,9 @@ static void lv_gltf_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
for(size_t i = 0; i < n; ++i) {
|
||||
lv_gltf_data_destroy(*(lv_gltf_model_t **)lv_array_at(&view->models, i));
|
||||
}
|
||||
destroy_environment(&view->env_textures);
|
||||
if(view->environment && view->owns_environment) {
|
||||
lv_gltf_environment_delete(view->environment);
|
||||
}
|
||||
}
|
||||
|
||||
static void lv_gltf_view_state_init(lv_gltf_t * view)
|
||||
@@ -790,10 +835,5 @@ static void setup_background_environment(GLuint program, GLuint * vao, GLuint *
|
||||
GL_CALL(glUseProgram(0));
|
||||
}
|
||||
|
||||
static void destroy_environment(lv_gltf_view_env_textures_t * env)
|
||||
{
|
||||
const unsigned int d[3] = { env->diffuse, env->specular, env->sheen };
|
||||
GL_CALL(glDeleteTextures(3, d));
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GLTF*/
|
||||
|
||||
@@ -81,16 +81,6 @@ typedef struct {
|
||||
GLfloat clear_color[4];
|
||||
} lv_opengl_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t diffuse;
|
||||
uint32_t specular;
|
||||
uint32_t sheen;
|
||||
uint32_t ggxLut;
|
||||
uint32_t charlie_lut;
|
||||
uint32_t mip_count;
|
||||
float ibl_intensity_scale;
|
||||
float angle;
|
||||
} lv_gltf_view_env_textures_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -107,14 +97,14 @@ struct _lv_gltf_t {
|
||||
lv_gltf_view_desc_t desc;
|
||||
lv_gltf_view_desc_t last_desc;
|
||||
lv_opengl_shader_manager_t shader_manager;
|
||||
lv_gltf_view_env_textures_t env_textures;
|
||||
lv_gltf_environment_t * environment;
|
||||
fastgltf::math::fmat4x4 view_matrix;
|
||||
fastgltf::math::fmat4x4 projection_matrix;
|
||||
fastgltf::math::fmat4x4 view_projection_matrix;
|
||||
fastgltf::math::fvec3 camera_pos;
|
||||
|
||||
std::map<int32_t, std::map<fastgltf::Node *, fastgltf::math::fmat4x4>> ibm_by_skin_then_node;
|
||||
|
||||
bool owns_environment;
|
||||
};
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "../../../drivers/opengles/lv_opengles_private.h"
|
||||
#include "../../../drivers/opengles/lv_opengles_debug.h"
|
||||
#include "../math/lv_gltf_math.hpp"
|
||||
#include "../gltf_environment/lv_gltf_environment_private.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -61,12 +62,12 @@ static uint32_t render_texture(uint32_t tex_unit, uint32_t tex_name, int32_t tex
|
||||
GLint uv_transform);
|
||||
static void draw_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, fastgltf::Node & node,
|
||||
std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix,
|
||||
const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass);
|
||||
const lv_gltf_environment_t * env_tex, bool is_transmission_pass);
|
||||
|
||||
static void setup_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * gltf_data,
|
||||
fastgltf::Node & node,
|
||||
std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix,
|
||||
const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass);
|
||||
const lv_gltf_environment_t * env_tex, bool is_transmission_pass);
|
||||
|
||||
static void draw_material(lv_gltf_t * viewer, const lv_gltf_uniform_locations_t * uniforms, lv_gltf_model_t * model,
|
||||
lv_gltf_primitive_t * _prim_data, size_t materialIndex, bool is_transmission_pass, GLuint program,
|
||||
@@ -269,7 +270,7 @@ static GLuint lv_gltf_view_render_model(lv_gltf_t * viewer, lv_gltf_model_t * mo
|
||||
const auto & node_element = node_distance_pair.second;
|
||||
const auto & node = node_element.first;
|
||||
draw_primitive(node_element.second, viewer, model, *node, node->meshIndex.value(),
|
||||
lv_gltf_data_get_cached_transform(model, node), &viewer->env_textures, true);
|
||||
lv_gltf_data_get_cached_transform(model, node), viewer->environment, true);
|
||||
}
|
||||
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, vstate->opaque_render_state.texture));
|
||||
@@ -302,7 +303,7 @@ static GLuint lv_gltf_view_render_model(lv_gltf_t * viewer, lv_gltf_model_t * mo
|
||||
const auto & node_element = node_distance_pair.second;
|
||||
const auto & node = node_element.first;
|
||||
draw_primitive(node_element.second, viewer, model, *node, node->meshIndex.value(),
|
||||
lv_gltf_data_get_cached_transform(model, node), &viewer->env_textures, false);
|
||||
lv_gltf_data_get_cached_transform(model, node), viewer->environment, false);
|
||||
}
|
||||
if(opt_aa_this_frame) {
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, vstate->render_state.texture));
|
||||
@@ -328,7 +329,7 @@ static void render_materials(lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, co
|
||||
for(const auto & pair : kv.second) {
|
||||
auto node = pair.first;
|
||||
draw_primitive(pair.second, viewer, gltf_data, *node, node->meshIndex.value(),
|
||||
lv_gltf_data_get_cached_transform(gltf_data, node), &viewer->env_textures, true);
|
||||
lv_gltf_data_get_cached_transform(gltf_data, node), viewer->environment, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,7 +379,7 @@ static void render_skins(lv_gltf_t * viewer, lv_gltf_model_t * model)
|
||||
}
|
||||
static void draw_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, fastgltf::Node & node,
|
||||
std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix,
|
||||
const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass)
|
||||
const lv_gltf_environment_t * env_tex, bool is_transmission_pass)
|
||||
{
|
||||
lv_gltf_mesh_data_t * mesh = lv_gltf_data_get_mesh(gltf_data, mesh_index);
|
||||
const auto & asset = lv_gltf_data_get_asset(gltf_data);
|
||||
@@ -397,7 +398,7 @@ static void draw_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t
|
||||
}
|
||||
static void setup_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * model, fastgltf::Node & node,
|
||||
std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix,
|
||||
const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass)
|
||||
const lv_gltf_environment_t * env_tex, bool is_transmission_pass)
|
||||
{
|
||||
lv_gltf_view_desc_t * view_desc = &viewer->desc;
|
||||
lv_gltf_mesh_data_t * mesh = lv_gltf_data_get_mesh(model, mesh_index);
|
||||
@@ -437,7 +438,7 @@ static void setup_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_
|
||||
GL_CALL(glUniform1f(uniforms->exposure, view_desc->exposure));
|
||||
GL_CALL(glUniform1f(uniforms->env_intensity, view_desc->env_pow));
|
||||
GL_CALL(glUniform1i(uniforms->env_mip_count, (int32_t)env_tex->mip_count));
|
||||
setup_environment_rotation_matrix(viewer->env_textures.angle, program);
|
||||
setup_environment_rotation_matrix(viewer->environment->angle, program);
|
||||
GL_CALL(glEnable(GL_CULL_FACE));
|
||||
GL_CALL(glDisable(GL_BLEND));
|
||||
GL_CALL(glEnable(GL_DEPTH_TEST));
|
||||
@@ -1137,16 +1138,16 @@ static void setup_draw_environment_background(lv_opengl_shader_manager_t * manag
|
||||
|
||||
/* Bind the texture to the specified texture unit*/
|
||||
GL_CALL(glActiveTexture(GL_TEXTURE0 + 0));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, viewer->env_textures.specular));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, viewer->environment->specular));
|
||||
|
||||
GL_CALL(glUniform1i(glGetUniformLocation(manager->bg_program, "u_GGXEnvSampler"), 0));
|
||||
|
||||
GL_CALL(glUniform1i(glGetUniformLocation(manager->bg_program, "u_MipCount"), viewer->env_textures.mip_count));
|
||||
GL_CALL(glUniform1i(glGetUniformLocation(manager->bg_program, "u_MipCount"), viewer->environment->mip_count));
|
||||
GL_CALL(glUniform1f(glGetUniformLocation(manager->bg_program, "u_EnvBlurNormalized"), blur));
|
||||
GL_CALL(glUniform1f(glGetUniformLocation(manager->bg_program, "u_EnvIntensity"), 1.0f));
|
||||
GL_CALL(glUniform1f(glGetUniformLocation(manager->bg_program, "u_Exposure"), 1.0f));
|
||||
|
||||
setup_environment_rotation_matrix(viewer->env_textures.angle, manager->bg_program);
|
||||
setup_environment_rotation_matrix(viewer->environment->angle, manager->bg_program);
|
||||
|
||||
GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, manager->bg_index_buf));
|
||||
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, manager->bg_vertex_buf));
|
||||
|
||||
@@ -282,8 +282,14 @@ typedef struct _lv_gltf_t lv_gltf_t;
|
||||
|
||||
typedef struct _lv_gltf_model_t lv_gltf_model_t;
|
||||
|
||||
typedef struct _lv_gltf_environment lv_gltf_environment_t;
|
||||
|
||||
typedef struct _lv_gltf_ibl_sampler lv_gltf_ibl_sampler_t;
|
||||
|
||||
typedef struct _lv_subject_t lv_subject_t;
|
||||
|
||||
typedef struct _lv_observer_t lv_observer_t;
|
||||
|
||||
typedef struct _lv_subject_increment_dsc_t lv_subject_increment_dsc_t;
|
||||
|
||||
typedef struct _lv_monkey_config_t lv_monkey_config_t;
|
||||
|
||||
Reference in New Issue
Block a user