Commit for 2022.01.05 23-01-04.7z
This commit is contained in:
parent
c3d320ce1a
commit
112a061dc8
28
Makefile
28
Makefile
@ -3,7 +3,7 @@ CC = $(shell cat "./bin/exe/default.config")
|
||||
TARGET_NAME = program
|
||||
TARGET_EXTENSION = exe
|
||||
TARGET_LIB_EXTENSION = dll
|
||||
RENDERER = opengl
|
||||
RENDERER = vulkan
|
||||
|
||||
include makefiles/$(ARCH).$(CC).make
|
||||
|
||||
@ -33,9 +33,9 @@ EXT_LIB_NAME += ext
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.182.0/
|
||||
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
|
||||
|
||||
#GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin32/glslangValidator
|
||||
GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin32/glslc
|
||||
SPV_OPTIMIZER += $(VULKAN_SDK_PATH)/Bin32/spirv-opt
|
||||
#GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin/glslangValidator
|
||||
GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin/glslc
|
||||
SPV_OPTIMIZER += $(VULKAN_SDK_PATH)/Bin/spirv-opt
|
||||
# Base Engine's DLL
|
||||
INC_DIR += $(ENGINE_INC_DIR)/$(ARCH)/$(CC)
|
||||
LIB_DIR += $(ENGINE_LIB_DIR)/$(ARCH)
|
||||
@ -51,7 +51,7 @@ ifneq (,$(findstring win64,$(ARCH)))
|
||||
FLAGS +=
|
||||
DEPS += -lgdi32
|
||||
else ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
REQ_DEPS += opengl gldc json:nlohmann lua reactphysics freetype png zlib ctti ogg openal aldc # bullet meshoptimizer draco luajit ultralight-ux ncurses curl openvr discord
|
||||
REQ_DEPS += simd opengl gldc json:nlohmann lua reactphysics freetype png zlib ctti ogg openal aldc # bullet meshoptimizer draco luajit ultralight-ux ncurses curl openvr discord
|
||||
endif
|
||||
ifneq (,$(findstring vulkan,$(REQ_DEPS)))
|
||||
FLAGS += -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN
|
||||
@ -60,7 +60,8 @@ ifneq (,$(findstring vulkan,$(REQ_DEPS)))
|
||||
LIBS += -L$(VULKAN_SDK_PATH)/Lib
|
||||
endif
|
||||
ifneq (,$(findstring opengl,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_OPENGL -DUF_USE_GLEW -DUF_USE_OPENGL_FIXED_FUNCTION
|
||||
FLAGS += -DUF_USE_OPENGL -DUF_USE_OPENGL_FIXED_FUNCTION
|
||||
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
ifneq (,$(findstring gldc,$(REQ_DEPS)))
|
||||
DEPS += -lGLdc
|
||||
@ -69,7 +70,13 @@ ifneq (,$(findstring opengl,$(REQ_DEPS)))
|
||||
DEPS += -lGL
|
||||
endif
|
||||
else
|
||||
DEPS += -lglew32 -lopengl32 -lglu32
|
||||
ifneq (,$(findstring gldc,$(REQ_DEPS)))
|
||||
DEPS += -lGLdc -lSDL2
|
||||
FLAGS += -DUF_USE_OPENGL_GLDC
|
||||
else
|
||||
FLAGS += -DUF_USE_GLEW
|
||||
DEPS += -lglew32 -lopengl32 -lglu32
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
@ -159,8 +166,11 @@ ifneq (,$(findstring reactphysics,$(REQ_DEPS)))
|
||||
DEPS += -lreactphysics3d
|
||||
endif
|
||||
ifneq (,$(findstring simd,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_SIMD -DUF_MATRIX_ALIGNED #-DUF_VECTOR_ALIGNED #-march=native
|
||||
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
FLAGS += -DUF_ENV_DREAMCAST_SIMD
|
||||
else
|
||||
FLAGS += -DUF_USE_SIMD -DUF_ALIGN_FOR_SIMD -DUF_MATRIX_ALIGNED #-DUF_VECTOR_ALIGNED #-march=native
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring meshoptimizer,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_MESHOPTIMIZER
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "SS2",
|
||||
"meshes": { "interleave": false },
|
||||
"meshes": { "interleaved": false },
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"lights": {
|
||||
"max": 24,
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
"unwrap": true
|
||||
},
|
||||
"baking": {
|
||||
"enabled": false,
|
||||
"enabled": true,
|
||||
"resolution": 8192,
|
||||
"shadows": 1024,
|
||||
"trigger": { "mode": "rendered" },
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
// { "filename": "./models/tiny_msci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
{ "filename": "./models/tiny_msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
|
||||
// { "filename": "./models/micro_sci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
@ -28,6 +29,7 @@
|
||||
},
|
||||
"tags": {
|
||||
"worldspawn": { "physics": { "type": "mesh", "static": true } },
|
||||
"worldspawn_20": { "physics": { "type": "mesh", "static": true } },
|
||||
// "worldspawn": { "physics": { "type": "bounding boxes", "static": true } },
|
||||
"info_player_spawn": {
|
||||
"action": "attach",
|
||||
|
||||
@ -3,8 +3,8 @@ layout (constant_id = 0) const uint PASSES = 6;
|
||||
#include "../common/structs.h"
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec4 inColor;
|
||||
layout (location = 2) in vec2 inUv;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec4 inColor;
|
||||
layout (location = 3) in vec2 inSt;
|
||||
layout (location = 4) in vec3 inNormal;
|
||||
layout (location = 5) in vec4 inTangent;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "SS2",
|
||||
"meshes": { "interleave": false },
|
||||
"meshes": { "interleaved": false },
|
||||
"matrix": { "reverseInfinite": false },
|
||||
"lights": {
|
||||
"max": 8,
|
||||
@ -63,18 +63,12 @@
|
||||
"json": "/json.lua"
|
||||
}
|
||||
},
|
||||
"bullet": {
|
||||
"iterations": 1,
|
||||
"substeps": 6,
|
||||
"timescale": 1,
|
||||
"multithreaded": false,
|
||||
"pool size": {
|
||||
"max collision algorithm": 64,
|
||||
"max persistent manifold": 64
|
||||
},
|
||||
"reactphysics": {
|
||||
"timescale": 0.03333333333,
|
||||
"debug draw": {
|
||||
"enabled": false,
|
||||
"rate": 1.0
|
||||
// "layer": "Gui",
|
||||
"rate": 0.0125
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -109,6 +109,12 @@
|
||||
#define alignas(X)
|
||||
#endif
|
||||
|
||||
#if UF_ALIGN_FOR_SIMD
|
||||
#define ALIGN16 alignas(16)
|
||||
#else
|
||||
#define ALIGN16
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
#include "simd.h"
|
||||
#include "helpers.inl"
|
||||
@ -2,23 +2,23 @@ namespace uf {
|
||||
namespace graph {
|
||||
namespace mesh {
|
||||
struct Base {
|
||||
pod::Vector3f position;
|
||||
pod::ColorRgba color;
|
||||
pod::Vector2f uv;
|
||||
pod::Vector2f st;
|
||||
pod::Vector3f normal;
|
||||
pod::Vector3f position{};
|
||||
pod::Vector2f uv{};
|
||||
pod::ColorRgba color{ (uint8_t) ~0, (uint8_t) ~0, (uint8_t) ~0, (uint8_t) ~0 };
|
||||
pod::Vector2f st{};
|
||||
pod::Vector3f normal{};
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct Skinned {
|
||||
pod::Vector3f position;
|
||||
pod::ColorRgba color;
|
||||
pod::Vector2f uv;
|
||||
pod::Vector2f st;
|
||||
pod::Vector3f normal;
|
||||
pod::Vector3f tangent;
|
||||
pod::Vector<uint16_t, 4> joints;
|
||||
pod::Vector4f weights;
|
||||
pod::Vector3f position{};
|
||||
pod::Vector2f uv{};
|
||||
pod::ColorRgba color{ (uint8_t) ~0, (uint8_t) ~0, (uint8_t) ~0, (uint8_t) ~0 };
|
||||
pod::Vector2f st{};
|
||||
pod::Vector3f normal{};
|
||||
pod::Vector3f tangent{};
|
||||
pod::Vector<uint16_t, 4> joints{};
|
||||
pod::Vector4f weights{};
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#if UF_USE_FREETYPE
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
#include <freetype/freetype2/ft2build.h>
|
||||
#include <ft2build.h>
|
||||
#else
|
||||
#include <ft2build.h>
|
||||
#endif
|
||||
|
||||
@ -3,9 +3,15 @@
|
||||
#include <uf/config.h>
|
||||
#if UF_USE_OPENAL
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alut.h>
|
||||
#if UF_ENV_DREAMCAST && UF_USE_OPENAL_ALDC
|
||||
#include <ALdc/al.h>
|
||||
#include <ALdc/alc.h>
|
||||
#include <ALdc/alut.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alut.h>
|
||||
#endif
|
||||
|
||||
namespace ext {
|
||||
namespace al {
|
||||
|
||||
@ -3,9 +3,15 @@
|
||||
#include <uf/config.h>
|
||||
#if UF_USE_OPENAL
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alut.h>
|
||||
#if UF_ENV_DREAMCAST && UF_USE_OPENAL_ALDC
|
||||
#include <ALdc/al.h>
|
||||
#include <ALdc/alc.h>
|
||||
#include <ALdc/alut.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alut.h>
|
||||
#endif
|
||||
|
||||
namespace ext {
|
||||
namespace al {
|
||||
|
||||
@ -40,7 +40,7 @@ namespace ext {
|
||||
namespace Image {
|
||||
typedef GLenum type_t;
|
||||
typedef GLenum viewType_t;
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||
static const type_t TYPE_1D = 100;
|
||||
static const type_t TYPE_2D = GL_TEXTURE_2D;
|
||||
static const type_t TYPE_3D = 110;
|
||||
@ -75,7 +75,7 @@ namespace ext {
|
||||
}
|
||||
namespace Shader {
|
||||
typedef GLenum type_t;
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||
static const type_t VERTEX = 0x00000001;
|
||||
static const type_t TESSELLATION_CONTROL = 0x00000002;
|
||||
static const type_t TESSELLATION_EVALUATION = 0x00000003;
|
||||
@ -129,7 +129,7 @@ namespace ext {
|
||||
}
|
||||
namespace Type {
|
||||
typedef GLenum type_t;
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||
static const type_t BYTE = GL_BYTE;
|
||||
static const type_t UBYTE = GL_UNSIGNED_BYTE;
|
||||
|
||||
|
||||
@ -1,12 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#if defined(UF_ENV_WINDOWS)
|
||||
#if UF_USE_GLEW
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
#if UF_USE_OPENGL_GLDC
|
||||
#include <GLdc/gl.h>
|
||||
#include <GLdc/glu.h>
|
||||
#include <GLdc/glkos.h>
|
||||
#include <GLdc/glext.h>
|
||||
|
||||
#define GL_NONE 0
|
||||
#define GLsizeiptr GLsizei
|
||||
|
||||
#define UF_USE_OPENGL_12 1
|
||||
#define UF_USE_OPENGL_FIXED_FUNCTION 1
|
||||
#elif defined(UF_ENV_WINDOWS)
|
||||
// The Visual C++ version of gl.h uses WINGDIAPI and APIENTRY but doesn't define them
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/wglext.h>
|
||||
@ -18,22 +31,21 @@
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#elif defined(UF_ENV_DREAMCAST)
|
||||
#if UF_USE_OPENGL_GLDC
|
||||
#include <GLdc/gl.h>
|
||||
#include <GLdc/glu.h>
|
||||
#include <GLdc/glkos.h>
|
||||
#include <GLdc/glext.h>
|
||||
#else
|
||||
#include <GLkos/gl.h>
|
||||
#include <GLkos/glu.h>
|
||||
#include <GLkos/glut.h>
|
||||
#include <GLkos/glext.h>
|
||||
|
||||
#define glIsTexture(x) ( x != 0 )
|
||||
#endif
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#define glIsTexture(x) ( x != 0 )
|
||||
#define GL_NONE 0
|
||||
#define GLsizeiptr GLsizei
|
||||
|
||||
#define UF_USE_OPENGL_12 1
|
||||
#define UF_USE_OPENGL_FIXED_FUNCTION 1
|
||||
|
||||
#define glClientActiveTexture glClientActiveTextureARB
|
||||
#define glActiveTexture glActiveTextureARB
|
||||
#define glCompressedTexImage2DARB glCompressedTexImage2D
|
||||
#endif
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
@ -43,10 +43,8 @@
|
||||
#include <iomanip>
|
||||
#endif
|
||||
|
||||
// uf::iostream
|
||||
#define UF_IO_COUT std::cout
|
||||
// "\n"
|
||||
#define UF_IO_ENDL std::endl
|
||||
#define UF_IO_COUT std::cout // uf::iostream
|
||||
#define UF_IO_ENDL std::endl // "\r\n"
|
||||
|
||||
#define UF_MSG(Y, X) UF_IO_COUT << "[" << X << "] " << __FILE__ << ":" << __FUNCTION__ << "@" << __LINE__ << ": " << Y << UF_IO_ENDL;
|
||||
|
||||
|
||||
@ -2,7 +2,12 @@
|
||||
|
||||
#include "universal.h"
|
||||
|
||||
#if !UF_USE_SFML
|
||||
#if !UF_USE_OPENGL || UF_USE_OPENGL_GLDC
|
||||
#include "unknown.h"
|
||||
namespace spec {
|
||||
typedef spec::unknown::Context Context;
|
||||
}
|
||||
#else
|
||||
namespace spec {
|
||||
namespace win32 {
|
||||
class UF_API_VAR Context : public spec::uni::Context {
|
||||
|
||||
@ -21,8 +21,8 @@ namespace pod {
|
||||
|
||||
struct Viewports {
|
||||
struct Matrices{
|
||||
/*alignas(16)*/ pod::Matrix4f view;
|
||||
/*alignas(16)*/ pod::Matrix4f projection;
|
||||
pod::Matrix4f view;
|
||||
pod::Matrix4f projection;
|
||||
} matrices[uf::camera::maxViews];
|
||||
} viewport;
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@ namespace pod {
|
||||
#if UF_MATRIX_ALIGNED
|
||||
struct /*UF_API*/ alignas(16) Matrix {
|
||||
#else
|
||||
struct /*UF_API*/ /*alignas(16)*/ Matrix {
|
||||
struct /*UF_API*/ Matrix {
|
||||
#endif
|
||||
// n-dimensional/unspecialized matrix access
|
||||
T components[R*C] = {};
|
||||
|
||||
@ -47,7 +47,7 @@ const T* pod::Matrix<T,R,C>::operator[](size_t i) const {
|
||||
*/
|
||||
template<typename T>
|
||||
pod::Matrix4t<T> /*UF_API*/ uf::matrix::identity() {
|
||||
alignas(16) pod::Matrix4t<T> matrix;
|
||||
ALIGN16 pod::Matrix4t<T> matrix;
|
||||
#pragma unroll // GCC unroll 4
|
||||
for ( uint_fast8_t c = 0; c < 4; ++c )
|
||||
#pragma unroll // GCC unroll 4
|
||||
@ -57,7 +57,7 @@ pod::Matrix4t<T> /*UF_API*/ uf::matrix::identity() {
|
||||
}
|
||||
template<typename T>
|
||||
pod::Matrix4t<T> /*UF_API*/ uf::matrix::initialize( const T* list ) {
|
||||
alignas(16) pod::Matrix4t<T> matrix;
|
||||
ALIGN16 pod::Matrix4t<T> matrix;
|
||||
// memcpy(&matrix[0], list, sizeof(matrix));
|
||||
#pragma unroll // GCC unroll 16
|
||||
for ( uint_fast8_t i = 0; i < 16; ++i )
|
||||
@ -72,7 +72,7 @@ pod::Matrix4t<T> /*UF_API*/ uf::matrix::initialize( const T* list ) {
|
||||
}
|
||||
template<typename T>
|
||||
pod::Matrix4t<T> /*UF_API*/ uf::matrix::initialize( const uf::stl::vector<T>& list ) {
|
||||
alignas(16) pod::Matrix4t<T> matrix;
|
||||
ALIGN16 pod::Matrix4t<T> matrix;
|
||||
if ( list.size() != 16 ) return matrix;
|
||||
// memcpy(&matrix[0], &list[0], sizeof(matrix));
|
||||
#pragma unroll // GCC unroll 16
|
||||
@ -89,7 +89,7 @@ pod::Matrix4t<T> /*UF_API*/ uf::matrix::initialize( const uf::stl::vector<T>& li
|
||||
return matrix;
|
||||
}
|
||||
template<typename T> pod::Matrix<typename T::type_t, T::columns, T::columns> uf::matrix::identityi(){
|
||||
alignas(16) pod::Matrix<typename T::type_t, T::columns, T::columns> matrix;
|
||||
ALIGN16 pod::Matrix<typename T::type_t, T::columns, T::columns> matrix;
|
||||
|
||||
#pragma unroll // GCC unroll T::columns
|
||||
for ( uint_fast8_t c = 0; c < T::columns; ++c )
|
||||
@ -149,7 +149,7 @@ template<typename T> bool uf::matrix::equals( const T& left, const T& right ) {
|
||||
// Basic arithmetic
|
||||
// Multiplies two matrices of same type and size together
|
||||
template<typename T> pod::Matrix<T,4,4> uf::matrix::multiply( const pod::Matrix<T,4,4>& left, const pod::Matrix<T,4,4>& right ) {
|
||||
alignas(16) pod::Matrix<T,4,4> res;
|
||||
ALIGN16 pod::Matrix<T,4,4> res;
|
||||
#if UF_USE_SIMD
|
||||
auto row1 = uf::simd::load(&left[0]);
|
||||
auto row2 = uf::simd::load(&left[4]);
|
||||
@ -242,7 +242,7 @@ template<typename T> pod::Matrix<T,4,4> uf::matrix::multiply( const pod::Matrix<
|
||||
#endif
|
||||
}
|
||||
template<typename T, typename U> pod::Matrix<typename T::type_t, T::columns, T::columns> uf::matrix::multiply( const T& left, const U& right ) {
|
||||
alignas(16) pod::Matrix<typename T::type_t,T::rows,T::columns> res;
|
||||
ALIGN16 pod::Matrix<typename T::type_t,T::rows,T::columns> res;
|
||||
#if 1
|
||||
float* dstPtr = &res[0];
|
||||
const float* leftPtr = &right[0];
|
||||
@ -280,7 +280,7 @@ template<typename T, typename U> pod::Matrix<typename T::type_t, T::columns, T::
|
||||
return res;
|
||||
}
|
||||
template<typename T> T /*UF_API*/ uf::matrix::multiplyAll( const T& m, typename T::type_t scalar ) {
|
||||
alignas(16) T matrix;
|
||||
ALIGN16 T matrix;
|
||||
#pragma unroll // GCC unroll T::rows * T::columns
|
||||
for ( uint_fast8_t i = 0; i < T::rows * T::columns; ++i )
|
||||
matrix[i] = m[i] * scalar;
|
||||
@ -288,7 +288,7 @@ template<typename T> T /*UF_API*/ uf::matrix::multiplyAll( const T& m, typename
|
||||
return matrix;
|
||||
}
|
||||
template<typename T> T /*UF_API*/ uf::matrix::add( const T& lhs, const T& rhs ) {
|
||||
alignas(16) T matrix;
|
||||
ALIGN16 T matrix;
|
||||
#pragma unroll // GCC unroll T::rows * T::columns
|
||||
for ( uint_fast8_t i = 0; i < T::rows * T::columns; ++i )
|
||||
matrix[i] = lhs[i] + rhs[i];
|
||||
@ -297,7 +297,7 @@ template<typename T> T /*UF_API*/ uf::matrix::add( const T& lhs, const T& rhs )
|
||||
}
|
||||
// Transpose matrix
|
||||
template<typename T> T uf::matrix::transpose( const T& matrix ) {
|
||||
alignas(16) T transpose;
|
||||
ALIGN16 T transpose;
|
||||
|
||||
#pragma unroll // GCC unroll T::rows
|
||||
for ( typename T::type_t r = 0; r < T::rows; ++r )
|
||||
@ -313,7 +313,7 @@ template<typename T> T uf::matrix::inverse( const T& matrix ) {
|
||||
if ( T::rows != 4 || T::columns != 4 ) return matrix;
|
||||
|
||||
const typename T::type_t* m = &matrix[0];
|
||||
alignas(16) typename T::type_t inv[16];
|
||||
ALIGN16 typename T::type_t inv[16];
|
||||
typename T::type_t det;
|
||||
uint_fast8_t i;
|
||||
|
||||
@ -417,7 +417,7 @@ template<typename T> T uf::matrix::inverse( const T& matrix ) {
|
||||
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
if (det == 0) return matrix;
|
||||
det = 1.0 / det;
|
||||
alignas(16) T inverted;
|
||||
ALIGN16 T inverted;
|
||||
#pragma unroll // GCC unroll 16
|
||||
for ( i = 0; i < 16; ++i )
|
||||
inverted[i] = inv[i] * det;
|
||||
@ -435,7 +435,7 @@ template<typename T> pod::Vector4t<T> uf::matrix::multiply( const pod::Matrix4t<
|
||||
if ( div && res.w > 0 ) res /= res.w;
|
||||
return res;
|
||||
#else
|
||||
alignas(16) auto res = pod::Vector4t<T>{
|
||||
ALIGN16 auto res = pod::Vector4t<T>{
|
||||
vector[0] * mat[0] + vector[1] * mat[4] + vector[2] * mat[8] + vector[3] * mat[12],
|
||||
vector[0] * mat[1] + vector[1] * mat[5] + vector[2] * mat[9] + vector[3] * mat[13],
|
||||
vector[0] * mat[2] + vector[1] * mat[6] + vector[2] * mat[10] + vector[3] * mat[14],
|
||||
@ -492,14 +492,14 @@ template<typename T> T& uf::matrix::scale_( T& matrix, const pod::Vector3t<typen
|
||||
}
|
||||
// Complex arithmetic
|
||||
template<typename T> T uf::matrix::translate( const T& matrix, const pod::Vector3t<typename T::type_t>& vector ) {
|
||||
alignas(16) T res = matrix;
|
||||
ALIGN16 T res = matrix;
|
||||
res[12] = vector.x;
|
||||
res[13] = vector.y;
|
||||
res[14] = vector.z;
|
||||
return res;
|
||||
}
|
||||
template<typename T> T uf::matrix::rotate( const T& matrix, const pod::Vector3t<typename T::type_t>& vector ) {
|
||||
alignas(16) T res = matrix;
|
||||
ALIGN16 T res = matrix;
|
||||
if ( vector.x != 0 ) {
|
||||
res[5] = cos( vector.x );
|
||||
res[6] = sin( vector.x );
|
||||
@ -523,7 +523,7 @@ template<typename T> T uf::matrix::rotate( const T& matrix, const pod::Vector3t<
|
||||
return res;
|
||||
}
|
||||
template<typename T> T uf::matrix::scale( const T& matrix, const pod::Vector3t<typename T::type_t>& vector ) {
|
||||
alignas(16) T res = matrix;
|
||||
ALIGN16 T res = matrix;
|
||||
res[0] = vector.x;
|
||||
res[5] = vector.y;
|
||||
res[10] = vector.z;
|
||||
@ -531,7 +531,7 @@ template<typename T> T uf::matrix::scale( const T& matrix, const pod::Vector3t<t
|
||||
}
|
||||
template<typename T>
|
||||
pod::Matrix4t<T> /*UF_API*/ uf::matrix::orthographic( T l, T r, T b, T t, T f, T n ) {
|
||||
alignas(16) pod::Matrix4t<T> m = uf::matrix::identity();
|
||||
ALIGN16 pod::Matrix4t<T> m = uf::matrix::identity();
|
||||
m[0*4+0] = 2 / (r - l);
|
||||
m[1*4+1] = 2 / (t - b);
|
||||
m[2*4+2] = - 2 / (f - n);
|
||||
@ -655,7 +655,7 @@ pod::Matrix<T,R,C>& /*UF_API*/ uf::matrix::decode( const ext::json::Value& json,
|
||||
|
||||
template<typename T, size_t R, size_t C>
|
||||
pod::Matrix<T,R,C> /*UF_API*/ uf::matrix::decode( const ext::json::Value& json, const pod::Matrix<T,R,C>& _m ) {
|
||||
alignas(16) pod::Matrix<T,R,C> m = _m;
|
||||
ALIGN16 pod::Matrix<T,R,C> m = _m;
|
||||
if ( ext::json::isArray(json) )
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( uint_fast8_t i = 0; i < R*C; ++i )
|
||||
|
||||
@ -10,18 +10,18 @@ namespace pod {
|
||||
static const uint32_t LEAF = 2;
|
||||
static const uint32_t TREE = 3;
|
||||
static const uint32_t ROOT = 4;
|
||||
/*alignas(16)*/ pod::Vector4f position; // 4 * 4 = 16 bytes
|
||||
/*alignas(4)*/ uint32_t type; // 4 * 1 = 4 bytes
|
||||
pod::Vector4f position; // 4 * 4 = 16 bytes
|
||||
uint32_t type; // 4 * 1 = 4 bytes
|
||||
};
|
||||
struct UF_API Light {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
/*alignas(16)*/ pod::Vector3f color;
|
||||
pod::Vector3f position;
|
||||
pod::Vector3f color;
|
||||
};
|
||||
struct UF_API Tree {
|
||||
static const size_t TREE_SIZE = 8;
|
||||
/*alignas(16)*/ pod::Vector4f position; // 4 * 4 = 16 bytes
|
||||
/*alignas(4)*/ uint32_t type; // 4 * 1 = 4 bytes
|
||||
/*alignas(4)*/ uint32_t children[Tree::TREE_SIZE]; // 4 * 8 = 32 bytes
|
||||
pod::Vector4f position; // 4 * 4 = 16 bytes
|
||||
uint32_t type; // 4 * 1 = 4 bytes
|
||||
uint32_t children[Tree::TREE_SIZE]; // 4 * 8 = 32 bytes
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -473,7 +473,7 @@ namespace pod {
|
||||
#if UF_VECTOR_ALIGNED
|
||||
struct /*UF_API*/ alignas(16) Vector<T,4> {
|
||||
#else
|
||||
struct /*UF_API*/ /*alignas(16)*/ Vector<T,4> {
|
||||
struct /*UF_API*/ Vector<T,4> {
|
||||
#endif
|
||||
// XYZW access
|
||||
T x;
|
||||
|
||||
@ -20,7 +20,7 @@ template<typename T, size_t N>
|
||||
pod::Vector<T, N> /*UF_API*/ uf::vector::copy( const pod::Vector<T, N>& v ) { return v; }
|
||||
template<typename T, size_t N, typename U>
|
||||
pod::Vector<T, N> /*UF_API*/ uf::vector::cast( const U& from ) {
|
||||
alignas(16) pod::Vector<T, N> to;
|
||||
ALIGN16 pod::Vector<T, N> to;
|
||||
#pragma unroll // GCC unroll N
|
||||
for ( auto i = 0; i < N && i < U::size; ++i )
|
||||
to[i] = from[i];
|
||||
@ -45,7 +45,7 @@ T /*UF_API*/ uf::vector::add( const T& left, const T& right ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::add( left, right );
|
||||
#endif
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = left[i] + right[i];
|
||||
@ -56,7 +56,7 @@ T /*UF_API*/ uf::vector::add( const T& vector, /*const typename T::type_t&*/ typ
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::add( vector, scalar );
|
||||
#endif
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = vector[i] + scalar;
|
||||
@ -67,7 +67,7 @@ T /*UF_API*/ uf::vector::subtract( const T& left, const T& right ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::sub( left, right );
|
||||
#endif
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = left[i] - right[i];
|
||||
@ -78,7 +78,7 @@ T /*UF_API*/ uf::vector::subtract( const T& vector, /*const typename T::type_t&*
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::sub( vector, scalar );
|
||||
#endif
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = vector[i] - scalar;
|
||||
@ -89,7 +89,7 @@ T /*UF_API*/ uf::vector::multiply( const T& left, const T& right ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::mul( left, right );
|
||||
#endif
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = left[i] * right[i];
|
||||
@ -100,7 +100,7 @@ T /*UF_API*/ uf::vector::multiply( const T& vector, /*const typename T::type_t&*
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::mul( vector, scalar );
|
||||
#endif
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = vector[i] * scalar;
|
||||
@ -110,15 +110,14 @@ template<typename T> // Divides two vectors of same type and size
|
||||
T /*UF_API*/ uf::vector::divide( const T& left, const T& right ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::div( left, right );
|
||||
#elif UF_ENV_DREAMCAST
|
||||
alignas(16) T res;
|
||||
#elif UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = MATH_Fast_Divide(left[i], right[i]);
|
||||
return res;
|
||||
#else
|
||||
alignas(16) T res;
|
||||
scalar = 1.0 / scalar;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = left[i] * right[i];
|
||||
@ -129,14 +128,14 @@ template<typename T> // Divides this vector by a scalar
|
||||
T /*UF_API*/ uf::vector::divide( const T& vector, /*const typename T::type_t&*/ typename T::type_t scalar ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::div( vector, scalar );
|
||||
#elif UF_ENV_DREAMCAST
|
||||
alignas(16) T res;
|
||||
#elif UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = MATH_Fast_Divide(vector[i], scalar);
|
||||
return res;
|
||||
#else
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
scalar = 1.0 / scalar;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
@ -165,7 +164,7 @@ T /*UF_API*/ uf::vector::negate( const T& vector ) {
|
||||
#if UF_USE_SIMD
|
||||
return uf::simd::mul( vector, -1.f );
|
||||
#endif
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = -vector[i];
|
||||
@ -173,7 +172,7 @@ T /*UF_API*/ uf::vector::negate( const T& vector ) {
|
||||
}
|
||||
template<typename T> //
|
||||
T /*UF_API*/ uf::vector::abs( const T& vector ) {
|
||||
alignas(16) T res;
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = abs(vector[i]);
|
||||
@ -309,7 +308,7 @@ T /*UF_API*/ uf::vector::round( const T& vector ) {
|
||||
// Complex arithmetic
|
||||
template<typename T> // Compute the dot product between two vectors
|
||||
typename T::type_t /*UF_API*/ uf::vector::dot( const T& left, const T& right ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
return MATH_fipr( UF_EZ_VEC4(left, T::size), UF_EZ_VEC4(right, T::size) );
|
||||
#elif UF_USE_SIMD
|
||||
return uf::simd::dot( left, right );
|
||||
@ -324,8 +323,8 @@ template<typename T> // Linearly interpolate between two vectors
|
||||
T /*UF_API*/ uf::vector::lerp( const T& from, const T& to, double delta, bool clamp ) {
|
||||
delta = fmax( 0, fmin(1,delta) );
|
||||
// from + ( ( to - from ) * delta )
|
||||
#if UF_ENV_DREAMCAST
|
||||
alignas(16) T res;
|
||||
#if UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = MATH_Lerp( from[i], to[i], delta );
|
||||
@ -339,8 +338,8 @@ template<typename T> // Linearly interpolate between two vectors
|
||||
T /*UF_API*/ uf::vector::lerp( const T& from, const T& to, const T& delta, bool clamp ) {
|
||||
//delta = fmax( 0, fmin(1,delta) );
|
||||
// from + ( ( to - from ) * delta )
|
||||
#if UF_ENV_DREAMCAST
|
||||
alignas(16) T res;
|
||||
#if UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
ALIGN16 T res;
|
||||
#pragma unroll // GCC unroll T::size
|
||||
for ( auto i = 0; i < T::size; ++i )
|
||||
res[i] = MATH_Lerp( from[i], to[i], delta[i] );
|
||||
@ -375,18 +374,18 @@ T /*UF_API*/ uf::vector::mix( const T& x, const T& y, double a, bool clamp ) {
|
||||
}
|
||||
template<typename T> // Compute the distance between two vectors (doesn't sqrt)
|
||||
typename T::type_t /*UF_API*/ uf::vector::distanceSquared( const T& a, const T& b ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
alignas(16) T delta = uf::vector::subtract(b, a);
|
||||
#if UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
ALIGN16 T delta = uf::vector::subtract(b, a);
|
||||
return MATH_Sum_of_Squares( UF_EZ_VEC4( delta, T::size ) );
|
||||
#elif UF_USE_SIMD
|
||||
uf::simd::value<typename T::type_t> delta = uf::simd::sub( b, a );
|
||||
// return uf::vector::sum( uf::simd::vector( uf::simd::mul( delta, delta ) ) );
|
||||
return uf::simd::dot( delta, delta );
|
||||
#else
|
||||
alignas(16) T delta = uf::vector::subtract(b, a);
|
||||
ALIGN16 T delta = uf::vector::subtract(b, a);
|
||||
return uf::vector::dot( delta, delta );
|
||||
/*
|
||||
alignas(16) T delta = uf::vector::subtract(b, a);
|
||||
ALIGN16 T delta = uf::vector::subtract(b, a);
|
||||
uf::vector::multiply( delta, delta );
|
||||
return uf::vector::sum(delta);
|
||||
*/
|
||||
@ -394,7 +393,7 @@ typename T::type_t /*UF_API*/ uf::vector::distanceSquared( const T& a, const T&
|
||||
}
|
||||
template<typename T> // Compute the distance between two vectors
|
||||
typename T::type_t /*UF_API*/ uf::vector::distance( const T& a, const T& b ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
return MATH_Fast_Sqrt(uf::vector::distanceSquared(a,b));
|
||||
#endif
|
||||
return sqrt(uf::vector::distanceSquared(a,b));
|
||||
@ -405,7 +404,7 @@ typename T::type_t /*UF_API*/ uf::vector::magnitude( const T& vector ) {
|
||||
}
|
||||
template<typename T> // Compute the norm of the vector
|
||||
typename T::type_t /*UF_API*/ uf::vector::norm( const T& vector ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
return MATH_Fast_Sqrt( uf::vector::magnitude(vector) );
|
||||
#endif
|
||||
return sqrt( uf::vector::magnitude(vector) );
|
||||
@ -414,7 +413,7 @@ template<typename T> // Normalizes a vector
|
||||
T /*UF_API*/ uf::vector::normalize( const T& vector ) {
|
||||
typename T::type_t norm = uf::vector::norm(vector);
|
||||
if ( norm == 0 ) return vector;
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
return uf::vector::multiply(vector, MATH_fsrra(norm));
|
||||
#endif
|
||||
return uf::vector::divide(vector, norm);
|
||||
@ -422,8 +421,8 @@ T /*UF_API*/ uf::vector::normalize( const T& vector ) {
|
||||
template<typename T> // Normalizes a vector
|
||||
void /*UF_API*/ uf::vector::orthonormalize( T& normal, T& tangent ) {
|
||||
normal = uf::vector::normalize( normal );
|
||||
alignas(16) T norm = normal;
|
||||
alignas(16) T tan = uf::vector::normalize( tangent );
|
||||
ALIGN16 T norm = normal;
|
||||
ALIGN16 T tan = uf::vector::normalize( tangent );
|
||||
tangent = uf::vector::subtract( tan, uf::vector::multiply( norm, uf::vector::dot( norm, tan ) ) );
|
||||
tangent = uf::vector::normalize( tangent );
|
||||
}
|
||||
@ -452,15 +451,15 @@ T /*UF_API*/ uf::vector::cross( const T& a, const T& b ) {
|
||||
uf::simd::value<typename T::type_t> res = _mm_shuffle_ps(tmp2,tmp2,_MM_SHUFFLE(3,0,2,1));
|
||||
return res;
|
||||
#endif
|
||||
#elif UF_ENV_DREAMCAST
|
||||
auto res = MATH_Cross_Product( a.x, a.y, a.z, b.x, b.y, b.z );
|
||||
#elif UF_ENV_DREAMCAST && UF_ENV_DREAMCAST_SIMD
|
||||
ALIGN16 auto res = MATH_Cross_Product( a.x, a.y, a.z, b.x, b.y, b.z );
|
||||
return *((T*) &res);
|
||||
#else
|
||||
alignas(16) T res{
|
||||
ALIGN16 T res{
|
||||
a.y * b.z - b.y * a.z,
|
||||
a.z * b.x - b.z * a.x,
|
||||
a.x * b.y - b.x * a.y
|
||||
}
|
||||
};
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -271,57 +271,57 @@ namespace ext {
|
||||
|
||||
namespace pod {
|
||||
struct /*UF_API*/ Vertex_3F2F3F4F {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
/*alignas(8)*/ pod::Vector2f uv;
|
||||
/*alignas(16)*/ pod::Vector3f normal;
|
||||
/*alignas(16)*/ pod::Vector4f color;
|
||||
pod::Vector3f position;
|
||||
pod::Vector2f uv;
|
||||
pod::Vector3f normal;
|
||||
pod::Vector4f color;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct /*UF_API*/ Vertex_3F2F3F32B {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
/*alignas(8)*/ pod::Vector2f uv;
|
||||
/*alignas(16)*/ pod::Vector3f normal;
|
||||
/*alignas(16)*/ pod::Vector4t<uint8_t> color;
|
||||
pod::Vector3f position;
|
||||
pod::Vector2f uv;
|
||||
pod::Vector3f normal;
|
||||
pod::Vector4t<uint8_t> color;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct /*UF_API*/ Vertex_3F3F3F {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
/*alignas(16)*/ pod::Vector3f uv;
|
||||
/*alignas(16)*/ pod::Vector3f normal;
|
||||
pod::Vector3f position;
|
||||
pod::Vector3f uv;
|
||||
pod::Vector3f normal;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct /*UF_API*/ Vertex_3F2F3F1UI {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
/*alignas(8)*/ pod::Vector2f uv;
|
||||
/*alignas(16)*/ pod::Vector3f normal;
|
||||
/*alignas(4)*/ pod::Vector1ui id;
|
||||
pod::Vector3f position;
|
||||
pod::Vector2f uv;
|
||||
pod::Vector3f normal;
|
||||
pod::Vector1ui id;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct /*UF_API*/ Vertex_3F2F3F {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
/*alignas(8)*/ pod::Vector2f uv;
|
||||
/*alignas(16)*/ pod::Vector3f normal;
|
||||
pod::Vector3f position;
|
||||
pod::Vector2f uv;
|
||||
pod::Vector3f normal;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct /*UF_API*/ Vertex_3F2F {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
/*alignas(8)*/ pod::Vector2f uv;
|
||||
pod::Vector3f position;
|
||||
pod::Vector2f uv;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct /*UF_API*/ Vertex_2F2F {
|
||||
/*alignas(8)*/ pod::Vector2f position;
|
||||
/*alignas(8)*/ pod::Vector2f uv;
|
||||
pod::Vector2f position;
|
||||
pod::Vector2f uv;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
struct /*UF_API*/ Vertex_3F {
|
||||
/*alignas(16)*/ pod::Vector3f position;
|
||||
pod::Vector3f position;
|
||||
|
||||
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
|
||||
@ -193,8 +193,8 @@ uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, cons
|
||||
|
||||
{ "lua", uf::Asset::Type::LUA },
|
||||
|
||||
#if !UF_USE_OPENGL
|
||||
{ "glb", uf::Asset::Type::GRAPH },
|
||||
#if !UF_USE_OPENGL
|
||||
{ "gltf", uf::Asset::Type::GRAPH },
|
||||
{ "mdl", uf::Asset::Type::GRAPH },
|
||||
#endif
|
||||
|
||||
@ -188,82 +188,53 @@ namespace {
|
||||
uf::Mesh decodeMesh( ext::json::Value& json, pod::Graph& graph ) {
|
||||
uf::Mesh mesh;
|
||||
|
||||
mesh.vertex.attributes.reserve( json["inputs"]["vertex"]["attributes"].size() );
|
||||
mesh.vertex.count = json["inputs"]["vertex"]["count"].as( mesh.vertex.count );
|
||||
mesh.vertex.first = json["inputs"]["vertex"]["first"].as( mesh.vertex.first );
|
||||
mesh.vertex.stride = json["inputs"]["vertex"]["stride"].as( mesh.vertex.stride );
|
||||
mesh.vertex.offset = json["inputs"]["vertex"]["stride"].as( mesh.vertex.offset );
|
||||
mesh.vertex.interleaved = json["inputs"]["vertex"]["interleaved"].as( mesh.vertex.interleaved );
|
||||
ext::json::forEach( json["inputs"]["vertex"]["attributes"], [&]( ext::json::Value& value ){
|
||||
auto& attribute = mesh.vertex.attributes.emplace_back();
|
||||
/*
|
||||
struct Attribute {
|
||||
ext::RENDERER::AttributeDescriptor descriptor;
|
||||
int32_t buffer = -1;
|
||||
size_t offset = 0;
|
||||
|
||||
attribute.descriptor.offset = value["descriptor"]["offset"].as(attribute.descriptor.offset);
|
||||
attribute.descriptor.size = value["descriptor"]["size"].as(attribute.descriptor.size);
|
||||
attribute.descriptor.format = (uf::renderer::enums::Format::type_t) value["descriptor"]["format"].as<size_t>(attribute.descriptor.format);
|
||||
attribute.descriptor.name = value["descriptor"]["name"].as(attribute.descriptor.name);
|
||||
attribute.descriptor.type = (uf::renderer::enums::Type::type_t) value["descriptor"]["type"].as(attribute.descriptor.type);
|
||||
attribute.descriptor.components = value["descriptor"]["components"].as(attribute.descriptor.components);
|
||||
attribute.buffer = value["buffer"].as(attribute.buffer);
|
||||
attribute.offset = value["offset"].as(attribute.offset);
|
||||
attribute.stride = value["stride"].as(attribute.stride);
|
||||
});
|
||||
mesh.index.attributes.reserve( json["inputs"]["index"]["attributes"].size() );
|
||||
mesh.index.count = json["inputs"]["index"]["count"].as( mesh.index.count );
|
||||
mesh.index.first = json["inputs"]["index"]["first"].as( mesh.index.first );
|
||||
mesh.index.stride = json["inputs"]["index"]["stride"].as( mesh.index.stride );
|
||||
mesh.index.offset = json["inputs"]["index"]["stride"].as( mesh.index.offset );
|
||||
mesh.index.interleaved = json["inputs"]["index"]["interleaved"].as( mesh.index.interleaved );
|
||||
ext::json::forEach( json["inputs"]["index"]["attributes"], [&]( ext::json::Value& value ){
|
||||
auto& attribute = mesh.index.attributes.emplace_back();
|
||||
size_t stride = 0;
|
||||
size_t length = 0;
|
||||
void* pointer = NULL;
|
||||
};
|
||||
struct Input {
|
||||
uf::stl::vector<Attribute> attributes;
|
||||
size_t count = 0; // how many elements is the input using
|
||||
size_t first = 0; // base index to start from
|
||||
size_t stride = 0; // size of one element in the input's buffer
|
||||
size_t offset = 0; // bytes to offset from within the associated buffer
|
||||
int32_t interleaved = -1; // index to interleaved buffer if in bounds
|
||||
} vertex, index, instance, indirect;
|
||||
*/
|
||||
|
||||
attribute.descriptor.offset = value["descriptor"]["offset"].as(attribute.descriptor.offset);
|
||||
attribute.descriptor.size = value["descriptor"]["size"].as(attribute.descriptor.size);
|
||||
attribute.descriptor.format = (uf::renderer::enums::Format::type_t) value["descriptor"]["format"].as<size_t>(attribute.descriptor.format);
|
||||
attribute.descriptor.name = value["descriptor"]["name"].as(attribute.descriptor.name);
|
||||
attribute.descriptor.type = (uf::renderer::enums::Type::type_t) value["descriptor"]["type"].as(attribute.descriptor.type);
|
||||
attribute.descriptor.components = value["descriptor"]["components"].as(attribute.descriptor.components);
|
||||
attribute.buffer = value["buffer"].as(attribute.buffer);
|
||||
attribute.offset = value["offset"].as(attribute.offset);
|
||||
attribute.stride = value["stride"].as(attribute.stride);
|
||||
});
|
||||
mesh.instance.attributes.reserve( json["inputs"]["instance"]["attributes"].size() );
|
||||
mesh.instance.count = json["inputs"]["instance"]["count"].as( mesh.instance.count );
|
||||
mesh.instance.first = json["inputs"]["instance"]["first"].as( mesh.instance.first );
|
||||
mesh.instance.stride = json["inputs"]["instance"]["stride"].as( mesh.instance.stride );
|
||||
mesh.instance.offset = json["inputs"]["instance"]["stride"].as( mesh.instance.offset );
|
||||
mesh.instance.interleaved = json["inputs"]["instance"]["interleaved"].as( mesh.instance.interleaved );
|
||||
ext::json::forEach( json["inputs"]["instance"]["attributes"], [&]( ext::json::Value& value ){
|
||||
auto& attribute = mesh.instance.attributes.emplace_back();
|
||||
#define DESERIALIZE_MESH(N) {\
|
||||
auto& input = json["inputs"][#N];\
|
||||
mesh.N.attributes.reserve( input["attributes"].size() );\
|
||||
mesh.N.count = input["count"].as( mesh.N.count );\
|
||||
mesh.N.first = input["first"].as( mesh.N.first );\
|
||||
mesh.N.stride = input["stride"].as( mesh.N.stride );\
|
||||
mesh.N.offset = input["stride"].as( mesh.N.offset );\
|
||||
mesh.N.interleaved = input["interleaved"].as( mesh.N.interleaved );\
|
||||
ext::json::forEach( input["attributes"], [&]( ext::json::Value& value ){\
|
||||
auto& attribute = mesh.N.attributes.emplace_back();\
|
||||
attribute.descriptor.offset = value["descriptor"]["offset"].as(attribute.descriptor.offset);\
|
||||
attribute.descriptor.size = value["descriptor"]["size"].as(attribute.descriptor.size);\
|
||||
attribute.descriptor.format = (uf::renderer::enums::Format::type_t) value["descriptor"]["format"].as<size_t>(attribute.descriptor.format);\
|
||||
attribute.descriptor.name = value["descriptor"]["name"].as(attribute.descriptor.name);\
|
||||
attribute.descriptor.type = (uf::renderer::enums::Type::type_t) value["descriptor"]["type"].as(attribute.descriptor.type);\
|
||||
attribute.descriptor.components = value["descriptor"]["components"].as(attribute.descriptor.components);\
|
||||
attribute.buffer = value["buffer"].as(attribute.buffer);\
|
||||
attribute.offset = value["offset"].as(attribute.offset);\
|
||||
attribute.stride = value["stride"].as(attribute.stride);\
|
||||
attribute.length = value["length"].as(attribute.length);\
|
||||
});\
|
||||
}
|
||||
|
||||
attribute.descriptor.offset = value["descriptor"]["offset"].as(attribute.descriptor.offset);
|
||||
attribute.descriptor.size = value["descriptor"]["size"].as(attribute.descriptor.size);
|
||||
attribute.descriptor.format = (uf::renderer::enums::Format::type_t) value["descriptor"]["format"].as<size_t>(attribute.descriptor.format);
|
||||
attribute.descriptor.name = value["descriptor"]["name"].as(attribute.descriptor.name);
|
||||
attribute.descriptor.type = (uf::renderer::enums::Type::type_t) value["descriptor"]["type"].as(attribute.descriptor.type);
|
||||
attribute.descriptor.components = value["descriptor"]["components"].as(attribute.descriptor.components);
|
||||
attribute.buffer = value["buffer"].as(attribute.buffer);
|
||||
attribute.offset = value["offset"].as(attribute.offset);
|
||||
attribute.stride = value["stride"].as(attribute.stride);
|
||||
});
|
||||
mesh.indirect.attributes.reserve( json["inputs"]["indirect"]["attributes"].size() );
|
||||
mesh.indirect.count = json["inputs"]["indirect"]["count"].as( mesh.indirect.count );
|
||||
mesh.indirect.first = json["inputs"]["indirect"]["first"].as( mesh.indirect.first );
|
||||
mesh.indirect.stride = json["inputs"]["indirect"]["stride"].as( mesh.indirect.stride );
|
||||
mesh.indirect.offset = json["inputs"]["indirect"]["stride"].as( mesh.indirect.offset );
|
||||
mesh.indirect.interleaved = json["inputs"]["indirect"]["interleaved"].as( mesh.indirect.interleaved );
|
||||
ext::json::forEach( json["inputs"]["indirect"]["attributes"], [&]( ext::json::Value& value ){
|
||||
auto& attribute = mesh.indirect.attributes.emplace_back();
|
||||
|
||||
attribute.descriptor.offset = value["descriptor"]["offset"].as(attribute.descriptor.offset);
|
||||
attribute.descriptor.size = value["descriptor"]["size"].as(attribute.descriptor.size);
|
||||
attribute.descriptor.format = (uf::renderer::enums::Format::type_t) value["descriptor"]["format"].as<size_t>(attribute.descriptor.format);
|
||||
attribute.descriptor.name = value["descriptor"]["name"].as(attribute.descriptor.name);
|
||||
attribute.descriptor.type = (uf::renderer::enums::Type::type_t) value["descriptor"]["type"].as(attribute.descriptor.type);
|
||||
attribute.descriptor.components = value["descriptor"]["components"].as(attribute.descriptor.components);
|
||||
attribute.buffer = value["buffer"].as(attribute.buffer);
|
||||
attribute.offset = value["offset"].as(attribute.offset);
|
||||
attribute.stride = value["stride"].as(attribute.stride);
|
||||
});
|
||||
DESERIALIZE_MESH(vertex);
|
||||
DESERIALIZE_MESH(index);
|
||||
DESERIALIZE_MESH(instance);
|
||||
DESERIALIZE_MESH(indirect);
|
||||
|
||||
mesh.buffers.reserve( json["buffers"].size() );
|
||||
ext::json::forEach( json["buffers"], [&]( ext::json::Value& value ){
|
||||
@ -272,7 +243,9 @@ namespace {
|
||||
auto& buffer = mesh.buffers.emplace_back(uf::io::readAsBuffer( directory + "/" + filename ));
|
||||
});
|
||||
mesh.updateDescriptor();
|
||||
|
||||
return mesh;
|
||||
// return mesh.interleave();
|
||||
}
|
||||
|
||||
pod::Node decodeNode( ext::json::Value& json, pod::Graph& graph ) {
|
||||
|
||||
@ -146,6 +146,55 @@ namespace {
|
||||
uf::Serializer encode( const uf::Mesh& mesh, const EncodingSettings& settings ) {
|
||||
uf::Serializer json;
|
||||
|
||||
/*
|
||||
struct Attribute {
|
||||
ext::RENDERER::AttributeDescriptor descriptor;
|
||||
int32_t buffer = -1;
|
||||
size_t offset = 0;
|
||||
|
||||
size_t stride = 0;
|
||||
size_t length = 0;
|
||||
void* pointer = NULL;
|
||||
};
|
||||
struct Input {
|
||||
uf::stl::vector<Attribute> attributes;
|
||||
size_t count = 0; // how many elements is the input using
|
||||
size_t first = 0; // base index to start from
|
||||
size_t stride = 0; // size of one element in the input's buffer
|
||||
size_t offset = 0; // bytes to offset from within the associated buffer
|
||||
int32_t interleaved = -1; // index to interleaved buffer if in bounds
|
||||
} vertex, index, instance, indirect;
|
||||
*/
|
||||
|
||||
#define SERIALIZE_MESH(N) {\
|
||||
auto& input = json["inputs"][#N];\
|
||||
input["count"] = mesh.N.count;\
|
||||
input["first"] = mesh.N.first;\
|
||||
input["stride"] = mesh.N.stride;\
|
||||
input["offset"] = mesh.N.offset;\
|
||||
input["interleaved"] = mesh.N.interleaved;\
|
||||
ext::json::reserve( input["attributes"], mesh.N.attributes.size() );\
|
||||
for ( auto& attribute : mesh.N.attributes ) {\
|
||||
auto& a = input["attributes"].emplace_back();\
|
||||
a["descriptor"]["offset"] = attribute.descriptor.offset;\
|
||||
a["descriptor"]["size"] = attribute.descriptor.size;\
|
||||
a["descriptor"]["format"] = attribute.descriptor.format;\
|
||||
a["descriptor"]["name"] = attribute.descriptor.name;\
|
||||
a["descriptor"]["type"] = attribute.descriptor.type;\
|
||||
a["descriptor"]["components"] = attribute.descriptor.components;\
|
||||
a["buffer"] = attribute.buffer;\
|
||||
a["offset"] = attribute.offset;\
|
||||
a["stride"] = attribute.stride;\
|
||||
a["length"] = attribute.length;\
|
||||
}\
|
||||
}
|
||||
|
||||
SERIALIZE_MESH(vertex);
|
||||
SERIALIZE_MESH(index);
|
||||
SERIALIZE_MESH(instance);
|
||||
SERIALIZE_MESH(indirect);
|
||||
|
||||
/*
|
||||
json["inputs"]["vertex"]["count"] = mesh.vertex.count;
|
||||
json["inputs"]["vertex"]["first"] = mesh.vertex.first;
|
||||
json["inputs"]["vertex"]["stride"] = mesh.vertex.stride;
|
||||
@ -221,7 +270,7 @@ namespace {
|
||||
a["offset"] = attribute.offset;
|
||||
a["stride"] = attribute.stride;
|
||||
}
|
||||
|
||||
*/
|
||||
ext::json::reserve( json["buffers"], mesh.buffers.size() );
|
||||
for ( auto i = 0; i < mesh.buffers.size(); ++i ) {
|
||||
const uf::stl::string filename = settings.filename + ".buffer." + std::to_string(i) + "." + ( settings.compress ? "gz" : "bin" );
|
||||
|
||||
@ -23,15 +23,15 @@ pod::Graph::Storage uf::graph::storage;
|
||||
|
||||
UF_VERTEX_DESCRIPTOR(uf::graph::mesh::Base,
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R32G32B32_SFLOAT, position)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R8G8B8A8_UNORM, color)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R32G32_SFLOAT, uv)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R8G8B8A8_UNORM, color)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R32G32_SFLOAT, st)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R32G32B32_SFLOAT, normal)
|
||||
);
|
||||
UF_VERTEX_DESCRIPTOR(uf::graph::mesh::Skinned,
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32B32_SFLOAT, position)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R8G8B8A8_UNORM, color)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32_SFLOAT, uv)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R8G8B8A8_UNORM, color)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32_SFLOAT, st)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32B32_SFLOAT, normal)
|
||||
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32B32_SFLOAT, tangent)
|
||||
|
||||
@ -131,7 +131,7 @@ void uf::GraphBehavior::tick( uf::Object& self ) {
|
||||
shader.updateBuffer( (const void*) instances.data(), instances.size() * sizeof(pod::Matrix4f), graph.buffers.instance /*storageBuffer*/ );
|
||||
} else {
|
||||
struct UniformDescriptor {
|
||||
/*alignas(16)*/ pod::Matrix4f model;
|
||||
pod::Matrix4f model;
|
||||
};
|
||||
#if UF_UNIFORMS_REUSE
|
||||
auto& uniform = shader.getUniform("UBO");
|
||||
|
||||
@ -49,7 +49,7 @@ void uf::RenderBehavior::tick( uf::Object& self ) {
|
||||
shader.updateUniform("UBO", uniforms );
|
||||
#else
|
||||
struct UniformDescriptor {
|
||||
/*alignas(16)*/ pod::Matrix4f model;
|
||||
pod::Matrix4f model;
|
||||
};
|
||||
#if UF_UNIFORMS_REUSE
|
||||
auto& uniforms = uniform.get<UniformDescriptor>();
|
||||
|
||||
@ -117,11 +117,6 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
return uf::graph::load( filename, metadata );
|
||||
}
|
||||
|
||||
#if UF_USE_OPENGL
|
||||
UF_EXCEPTION("glTF loading is highly discouraged on this platform:" << filename);
|
||||
return {};
|
||||
#endif
|
||||
|
||||
tinygltf::Model model;
|
||||
tinygltf::TinyGLTF loader;
|
||||
|
||||
@ -238,7 +233,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
auto& primitives = /*graph.storage*/uf::graph::storage.primitives[keyName];
|
||||
auto& mesh = /*graph.storage*/uf::graph::storage.meshes[keyName];
|
||||
mesh.bindIndirect<pod::DrawCommand>();
|
||||
#if UF_USE_VULKAN
|
||||
#if 0 || UF_USE_VULKAN
|
||||
bool full = true;
|
||||
#else
|
||||
bool full = graph.metadata["flags"]["SKINNED"].as<bool>();
|
||||
@ -247,343 +242,14 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
mesh.bind<uf::graph::mesh::Skinned, uint32_t>();
|
||||
uf::stl::vector<uf::graph::mesh::Skinned> vertices;
|
||||
uf::stl::vector<uint32_t> indices;
|
||||
for ( auto& p : m.primitives ) {
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
auto& primitive = primitives.emplace_back();
|
||||
|
||||
struct Attribute {
|
||||
uf::stl::string name = "";
|
||||
size_t components = 0;
|
||||
size_t length = 0;
|
||||
size_t stride = 0;
|
||||
uint8_t* buffer = NULL;
|
||||
|
||||
uf::stl::vector<float> floats;
|
||||
uf::stl::vector<uint8_t> int8s;
|
||||
uf::stl::vector<uint16_t> int16s;
|
||||
uf::stl::vector<uint32_t> int32s;
|
||||
};
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, Attribute> attributes = {
|
||||
{"POSITION", {}},
|
||||
{"TEXCOORD_0", {}},
|
||||
{"NORMAL", {}},
|
||||
{"TANGENT", {}},
|
||||
{"JOINTS_0", {}},
|
||||
{"WEIGHTS_0", {}},
|
||||
};
|
||||
|
||||
for ( auto& kv : attributes ) {
|
||||
auto& attribute = kv.second;
|
||||
attribute.name = kv.first;
|
||||
auto it = p.attributes.find(attribute.name);
|
||||
if ( it == p.attributes.end() ) continue;
|
||||
|
||||
auto& accessor = model.accessors[it->second];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if ( attribute.name == "POSITION" ) {
|
||||
vertices.resize(accessor.count);
|
||||
primitive.instance.bounds.min = pod::Vector3f{ accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
primitive.instance.bounds.max = pod::Vector3f{ accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
primitive.instance.bounds.min.x = -primitive.instance.bounds.min.x;
|
||||
primitive.instance.bounds.max.x = -primitive.instance.bounds.max.x;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( accessor.componentType ) {
|
||||
case TINYGLTF_COMPONENT_TYPE_BYTE:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buffer = reinterpret_cast<const uint8_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint8_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int8s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_SHORT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buffer = reinterpret_cast<const uint16_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint16_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int16s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_INT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: {
|
||||
auto* buffer = reinterpret_cast<const uint32_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint32_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int32s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
||||
auto* buffer = reinterpret_cast<const float*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(float);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.floats.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
default: UF_MSG_ERROR("Unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < vertices.size(); ++i ) {
|
||||
#if 0
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
memcpy( &vertex.member[0], &attributes[name].buffer[i * attributes[name].components], attributes[name].stride );
|
||||
#else
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
if ( !attributes[name].int8s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int8s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int16s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int16s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int32s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int32s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].floats.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].floats[i * attributes[name].components + j];\
|
||||
}
|
||||
#endif
|
||||
|
||||
auto& vertex = vertices[i];
|
||||
ITERATE_ATTRIBUTE("POSITION", position);
|
||||
ITERATE_ATTRIBUTE("TEXCOORD_0", uv);
|
||||
ITERATE_ATTRIBUTE("NORMAL", normal);
|
||||
ITERATE_ATTRIBUTE("TANGENT", tangent);
|
||||
ITERATE_ATTRIBUTE("JOINTS_0", joints);
|
||||
ITERATE_ATTRIBUTE("WEIGHTS_0", weights);
|
||||
|
||||
#undef ITERATE_ATTRIBUTE
|
||||
|
||||
// required due to reverse-Z projection matrix flipping the X axis as well
|
||||
// default is to proceed with this
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
vertex.position.x = -vertex.position.x;
|
||||
vertex.normal.x = -vertex.normal.x;
|
||||
vertex.tangent.x = -vertex.tangent.x;
|
||||
}
|
||||
}
|
||||
|
||||
if ( p.indices > -1 ) {
|
||||
auto& accessor = model.accessors[p.indices];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
auto& buffer = model.buffers[view.buffer];
|
||||
|
||||
indices.reserve( static_cast<uint32_t>(accessor.count) );
|
||||
|
||||
#define COPY_INDICES() for (size_t index = 0; index < accessor.count; index++) indices.emplace_back(buf[index]);
|
||||
|
||||
const void* pointer = &(buffer.data[accessor.byteOffset + view.byteOffset]);
|
||||
switch (accessor.componentType) {
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: {
|
||||
auto* buf = static_cast<const uint32_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buf = static_cast<const uint16_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buf = static_cast<const uint8_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef COPY_INDICES
|
||||
}
|
||||
|
||||
primitive.instance.materialID = p.material;
|
||||
primitive.instance.primitiveID = primitives.size() - 1;
|
||||
primitive.instance.meshID = meshID;
|
||||
primitive.instance.objectID = 0;
|
||||
|
||||
primitive.drawCommand.indices = indices.size();
|
||||
primitive.drawCommand.instances = 1;
|
||||
primitive.drawCommand.indexID = 0;
|
||||
primitive.drawCommand.vertexID = 0;
|
||||
primitive.drawCommand.instanceID = 0;
|
||||
primitive.drawCommand.vertices = vertices.size();
|
||||
|
||||
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = mesh.index.count,
|
||||
.vertexID = mesh.vertex.count,
|
||||
.instanceID = 0,
|
||||
|
||||
|
||||
.vertices = vertices.size(),
|
||||
});
|
||||
|
||||
mesh.insertVertices(vertices);
|
||||
mesh.insertIndices(indices);
|
||||
}
|
||||
#define UF_GRAPH_PROCESS_PRIMITIVES_FULL 1
|
||||
#include "processPrimitives.inl"
|
||||
#undef UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
} else {
|
||||
mesh.bind<uf::graph::mesh::Base, uint32_t>();
|
||||
uf::stl::vector<uf::graph::mesh::Base> vertices;
|
||||
uf::stl::vector<uint32_t> indices;
|
||||
for ( auto& p : m.primitives ) {
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
auto& primitive = primitives.emplace_back();
|
||||
|
||||
struct Attribute {
|
||||
uf::stl::string name = "";
|
||||
size_t components = 1;
|
||||
uf::stl::vector<float> floats;
|
||||
uf::stl::vector<uint8_t> int8s;
|
||||
uf::stl::vector<uint16_t> int16s;
|
||||
uf::stl::vector<uint32_t> int32s;
|
||||
};
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, Attribute> attributes = {
|
||||
{"POSITION", {}},
|
||||
{"TEXCOORD_0", {}},
|
||||
{"NORMAL", {}},
|
||||
};
|
||||
|
||||
for ( auto& kv : attributes ) {
|
||||
auto& attribute = kv.second;
|
||||
attribute.name = kv.first;
|
||||
auto it = p.attributes.find(attribute.name);
|
||||
if ( it == p.attributes.end() ) continue;
|
||||
|
||||
auto& accessor = model.accessors[it->second];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if ( attribute.name == "POSITION" ) {
|
||||
vertices.resize(accessor.count);
|
||||
primitive.instance.bounds.min = pod::Vector3f{ accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
primitive.instance.bounds.max = pod::Vector3f{ accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
primitive.instance.bounds.min.x = -primitive.instance.bounds.min.x;
|
||||
primitive.instance.bounds.max.x = -primitive.instance.bounds.max.x;
|
||||
}
|
||||
}
|
||||
switch ( accessor.componentType ) {
|
||||
case TINYGLTF_COMPONENT_TYPE_BYTE:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buffer = reinterpret_cast<const uint8_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint8_t);
|
||||
size_t len = accessor.count * attribute.components;
|
||||
attribute.int8s.assign( &buffer[0], &buffer[len] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_SHORT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buffer = reinterpret_cast<const uint16_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint16_t);
|
||||
size_t len = accessor.count * attribute.components;
|
||||
attribute.int16s.assign( &buffer[0], &buffer[len] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_INT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: {
|
||||
auto* buffer = reinterpret_cast<const uint32_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint32_t);
|
||||
size_t len = accessor.count * attribute.components;
|
||||
attribute.int32s.assign( &buffer[0], &buffer[len] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
||||
auto* buffer = reinterpret_cast<const float*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(float);
|
||||
size_t len = accessor.count * attribute.components;
|
||||
attribute.floats.assign( &buffer[0], &buffer[len] );
|
||||
} break;
|
||||
default: UF_MSG_ERROR("Unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < vertices.size(); ++i ) {
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
if ( !attributes[name].int8s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int8s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int16s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int16s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int32s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int32s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].floats.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].floats[i * attributes[name].components + j];\
|
||||
}
|
||||
|
||||
auto& vertex = vertices[i];
|
||||
ITERATE_ATTRIBUTE("POSITION", position);
|
||||
ITERATE_ATTRIBUTE("TEXCOORD_0", uv);
|
||||
ITERATE_ATTRIBUTE("NORMAL", normal);
|
||||
|
||||
#undef ITERATE_ATTRIBUTE
|
||||
|
||||
// required due to reverse-Z projection matrix flipping the X axis as well
|
||||
// default is to proceed with this
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
vertex.position.x = -vertex.position.x;
|
||||
vertex.normal.x = -vertex.normal.x;
|
||||
}
|
||||
}
|
||||
|
||||
if ( p.indices > -1 ) {
|
||||
auto& accessor = model.accessors[p.indices];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
auto& buffer = model.buffers[view.buffer];
|
||||
|
||||
indices.reserve( static_cast<uint32_t>(accessor.count) );
|
||||
|
||||
#define COPY_INDICES() for (size_t index = 0; index < accessor.count; index++) indices.emplace_back(buf[index]);
|
||||
|
||||
const void* pointer = &(buffer.data[accessor.byteOffset + view.byteOffset]);
|
||||
switch (accessor.componentType) {
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: {
|
||||
auto* buf = static_cast<const uint32_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buf = static_cast<const uint16_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buf = static_cast<const uint8_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef COPY_INDICES
|
||||
}
|
||||
|
||||
primitive.instance.materialID = p.material;
|
||||
primitive.instance.primitiveID = primitives.size() - 1;
|
||||
primitive.instance.meshID = meshID;
|
||||
primitive.instance.objectID = 0;
|
||||
|
||||
primitive.drawCommand.indices = indices.size();
|
||||
primitive.drawCommand.instances = 1;
|
||||
primitive.drawCommand.indexID = 0;
|
||||
primitive.drawCommand.vertexID = 0;
|
||||
primitive.drawCommand.instanceID = 0;
|
||||
primitive.drawCommand.vertices = vertices.size();
|
||||
|
||||
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = mesh.index.count,
|
||||
.vertexID = mesh.vertex.count,
|
||||
.instanceID = 0,
|
||||
|
||||
|
||||
.vertices = vertices.size(),
|
||||
});
|
||||
|
||||
mesh.insertVertices(vertices);
|
||||
mesh.insertIndices(indices);
|
||||
}
|
||||
#include "processPrimitives.inl"
|
||||
}
|
||||
mesh.insertIndirects(drawCommands);
|
||||
mesh.updateDescriptor();
|
||||
|
||||
183
engine/src/ext/gltf/processPrimitives.inl
Normal file
183
engine/src/ext/gltf/processPrimitives.inl
Normal file
@ -0,0 +1,183 @@
|
||||
for ( auto& p : m.primitives ) {
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
auto& primitive = primitives.emplace_back();
|
||||
|
||||
struct Attribute {
|
||||
uf::stl::string name = "";
|
||||
size_t components = 0;
|
||||
size_t length = 0;
|
||||
size_t stride = 0;
|
||||
uint8_t* buffer = NULL;
|
||||
|
||||
uf::stl::vector<float> floats;
|
||||
uf::stl::vector<uint8_t> int8s;
|
||||
uf::stl::vector<uint16_t> int16s;
|
||||
uf::stl::vector<uint32_t> int32s;
|
||||
};
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, Attribute> attributes = {
|
||||
{"POSITION", {}},
|
||||
{"TEXCOORD_0", {}},
|
||||
{"COLOR_0", {}},
|
||||
{"NORMAL", {}},
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
{"TANGENT", {}},
|
||||
{"JOINTS_0", {}},
|
||||
{"WEIGHTS_0", {}},
|
||||
#endif
|
||||
};
|
||||
|
||||
for ( auto& kv : attributes ) {
|
||||
auto& attribute = kv.second;
|
||||
attribute.name = kv.first;
|
||||
auto it = p.attributes.find(attribute.name);
|
||||
if ( it == p.attributes.end() ) continue;
|
||||
|
||||
auto& accessor = model.accessors[it->second];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if ( attribute.name == "POSITION" ) {
|
||||
vertices.resize(accessor.count);
|
||||
primitive.instance.bounds.min = pod::Vector3f{ accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
primitive.instance.bounds.max = pod::Vector3f{ accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
primitive.instance.bounds.min.x = -primitive.instance.bounds.min.x;
|
||||
primitive.instance.bounds.max.x = -primitive.instance.bounds.max.x;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( accessor.componentType ) {
|
||||
case TINYGLTF_COMPONENT_TYPE_BYTE:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buffer = reinterpret_cast<const uint8_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint8_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int8s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_SHORT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buffer = reinterpret_cast<const uint16_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint16_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int16s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_INT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: {
|
||||
auto* buffer = reinterpret_cast<const uint32_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint32_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int32s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
||||
auto* buffer = reinterpret_cast<const float*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(float);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.floats.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
default: UF_MSG_ERROR("Unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < vertices.size(); ++i ) {
|
||||
#if 0
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
memcpy( &vertex.member[0], &attributes[name].buffer[i * attributes[name].components], attributes[name].stride );
|
||||
#else
|
||||
#define ITERATE_ATTRIBUTE( name, member, floatScale )\
|
||||
if ( !attributes[name].int8s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int8s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int16s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int16s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int32s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int32s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].floats.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].floats[i * attributes[name].components + j] * floatScale;\
|
||||
}
|
||||
#endif
|
||||
|
||||
auto& vertex = vertices[i];
|
||||
ITERATE_ATTRIBUTE("POSITION", position, 1);
|
||||
ITERATE_ATTRIBUTE("TEXCOORD_0", uv, 1);
|
||||
ITERATE_ATTRIBUTE("COLOR_0", color, 255.0f);
|
||||
ITERATE_ATTRIBUTE("NORMAL", normal, 1);
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
ITERATE_ATTRIBUTE("TANGENT", tangent, 1);
|
||||
ITERATE_ATTRIBUTE("JOINTS_0", joints, 1);
|
||||
ITERATE_ATTRIBUTE("WEIGHTS_0", weights, 1);
|
||||
#endif
|
||||
|
||||
#undef ITERATE_ATTRIBUTE
|
||||
|
||||
// required due to reverse-Z projection matrix flipping the X axis as well
|
||||
// default is to proceed with this
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
vertex.position.x = -vertex.position.x;
|
||||
vertex.normal.x = -vertex.normal.x;
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
vertex.tangent.x = -vertex.tangent.x;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ( p.indices > -1 ) {
|
||||
auto& accessor = model.accessors[p.indices];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
auto& buffer = model.buffers[view.buffer];
|
||||
|
||||
indices.reserve( static_cast<uint32_t>(accessor.count) );
|
||||
|
||||
#define COPY_INDICES() for (size_t index = 0; index < accessor.count; index++) indices.emplace_back(buf[index]);
|
||||
|
||||
const void* pointer = &(buffer.data[accessor.byteOffset + view.byteOffset]);
|
||||
switch (accessor.componentType) {
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: {
|
||||
auto* buf = static_cast<const uint32_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buf = static_cast<const uint16_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buf = static_cast<const uint8_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef COPY_INDICES
|
||||
}
|
||||
|
||||
primitive.instance.materialID = p.material;
|
||||
primitive.instance.primitiveID = primitives.size() - 1;
|
||||
primitive.instance.meshID = meshID;
|
||||
primitive.instance.objectID = 0;
|
||||
|
||||
primitive.drawCommand.indices = indices.size();
|
||||
primitive.drawCommand.instances = 1;
|
||||
primitive.drawCommand.indexID = 0;
|
||||
primitive.drawCommand.vertexID = 0;
|
||||
primitive.drawCommand.instanceID = 0;
|
||||
primitive.drawCommand.vertices = vertices.size();
|
||||
|
||||
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = mesh.index.count,
|
||||
.vertexID = mesh.vertex.count,
|
||||
.instanceID = 0,
|
||||
|
||||
|
||||
.vertices = vertices.size(),
|
||||
});
|
||||
|
||||
mesh.insertVertices(vertices);
|
||||
mesh.insertIndices(indices);
|
||||
}
|
||||
@ -163,7 +163,7 @@ pod::Matrix4f ext::opengl::CommandBuffer::bindUniform( const ext::opengl::Buffer
|
||||
namespace {
|
||||
bool inside( const pod::Instance& instance, const pod::Matrix4f& mat ) {
|
||||
bool visible = false;
|
||||
#if 1
|
||||
#if 0
|
||||
pod::Vector4f corners[8] = {
|
||||
pod::Vector4f{ instance.bounds.min.x, instance.bounds.min.y, instance.bounds.min.z, 1.0f },
|
||||
pod::Vector4f{ instance.bounds.max.x, instance.bounds.min.y, instance.bounds.min.z, 1.0f },
|
||||
@ -175,7 +175,7 @@ namespace {
|
||||
pod::Vector4f{ instance.bounds.max.x, instance.bounds.max.y, instance.bounds.max.z, 1.0f },
|
||||
pod::Vector4f{ instance.bounds.min.x, instance.bounds.max.y, instance.bounds.max.z, 1.0f },
|
||||
};
|
||||
//#pragma unroll
|
||||
#pragma unroll
|
||||
for ( uint p = 0; p < 8; ++p ) {
|
||||
pod::Vector4f t = uf::matrix::multiply( mat, corners[p] );
|
||||
float w = t.w * 1.25f;
|
||||
@ -183,9 +183,9 @@ namespace {
|
||||
}
|
||||
#else
|
||||
pod::Vector4f planes[6]; {
|
||||
//#pragma unroll
|
||||
#pragma unroll
|
||||
for ( auto i = 0; i < 3; ++i )
|
||||
//#pragma unroll
|
||||
#pragma unroll
|
||||
for ( auto j = 0; j < 2; ++j) {
|
||||
float x = mat[4*0+3] + (j == 0 ? mat[4*0+i] : -mat[4*0+i]);
|
||||
float y = mat[4*1+3] + (j == 0 ? mat[4*1+i] : -mat[4*1+i]);
|
||||
@ -196,11 +196,11 @@ namespace {
|
||||
planes[i*2+j] = pod::Vector4f{ x * length, y * length, z * length, w * length };
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
//#pragma unroll
|
||||
#if 1
|
||||
#pragma unroll
|
||||
for ( auto p = 0; p < 6; ++p ) {
|
||||
float d = std::max(instance.bounds.min.x * planes[p].x, instance.bounds.max.x * planes[p].x)
|
||||
+ std::max(instance.bounds.min.y * planes[p].y, instance.bounds.max.y * planes[p].y);
|
||||
+ std::max(instance.bounds.min.y * planes[p].y, instance.bounds.max.y * planes[p].y)
|
||||
+ std::max(instance.bounds.min.z * planes[p].z, instance.bounds.max.z * planes[p].z);
|
||||
if ( d > -planes[p].w ) return true;
|
||||
}
|
||||
@ -216,14 +216,12 @@ namespace {
|
||||
pod::Vector4f{ instance.bounds.max.x, instance.bounds.max.y, instance.bounds.max.z, 1.0f },
|
||||
pod::Vector4f{ instance.bounds.min.x, instance.bounds.max.y, instance.bounds.max.z, 1.0f },
|
||||
};
|
||||
//#pragma unroll
|
||||
#pragma unroll
|
||||
for ( uint p = 0; p < 8; ++p ) corners[p] = uf::matrix::multiply( mat, corners[p] );
|
||||
//#pragma unroll
|
||||
#pragma unroll
|
||||
for ( uint p = 0; p < 6; ++p ) {
|
||||
//#pragma unroll
|
||||
for ( uint q = 0; q < 8; ++q ) {
|
||||
if ( uf::vector::dot( corners[q], planes[p] ) > 0 ) return true;
|
||||
}
|
||||
#pragma unroll
|
||||
for ( uint q = 0; q < 8; ++q ) if ( uf::vector::dot( corners[q], planes[p] ) > 0 ) return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -277,7 +275,6 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
// CPU-buffer based command dispatching
|
||||
if ( drawInfo.attributes.normal.pointer ) GL_ERROR_CHECK(glEnableClientState(GL_NORMAL_ARRAY));
|
||||
if ( drawInfo.attributes.color.pointer ) GL_ERROR_CHECK(glEnableClientState(GL_COLOR_ARRAY));
|
||||
if ( drawInfo.attributes.uv.pointer ) GL_ERROR_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
GL_ERROR_CHECK(glEnableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
GLenum indicesType = GL_UNSIGNED_INT;
|
||||
@ -287,10 +284,14 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
case sizeof(uint8_t): indicesType = GL_UNSIGNED_BYTE; break;
|
||||
}
|
||||
|
||||
GLboolean blending = glIsEnabled(GL_BLEND);
|
||||
|
||||
if ( drawInfo.textures.primary.image && drawInfo.attributes.uv.pointer ) {
|
||||
// static GLuint previous = 0;
|
||||
// if ( previous != drawInfo.textures.primary.image ) previous = drawInfo.textures.primary.image;
|
||||
|
||||
GL_ERROR_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
|
||||
GL_ERROR_CHECK(glClientActiveTexture(GL_TEXTURE0));
|
||||
GL_ERROR_CHECK(glActiveTexture(GL_TEXTURE0));
|
||||
GL_ERROR_CHECK(glEnable(drawInfo.textures.primary.viewType));
|
||||
@ -298,28 +299,36 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
GL_ERROR_CHECK(glBindTexture(drawInfo.textures.primary.viewType, drawInfo.textures.primary.image));
|
||||
GL_ERROR_CHECK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE));
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, GL_FLOAT, drawInfo.attributes.uv.stride, drawInfo.attributes.uv.pointer));
|
||||
}
|
||||
if ( drawInfo.textures.secondary.image && drawInfo.attributes.st.pointer ) {
|
||||
// static GLuint previous = 0;
|
||||
// if ( previous != drawInfo.textures.secondary.image ) previous = drawInfo.textures.secondary.image;
|
||||
|
||||
GL_ERROR_CHECK(glClientActiveTexture(GL_TEXTURE1));
|
||||
GL_ERROR_CHECK(glActiveTexture(GL_TEXTURE1));
|
||||
GL_ERROR_CHECK(glEnable(drawInfo.textures.secondary.viewType));
|
||||
GL_ERROR_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
GL_ERROR_CHECK(glBindTexture(drawInfo.textures.secondary.viewType, drawInfo.textures.secondary.image));
|
||||
GL_ERROR_CHECK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, GL_FLOAT, drawInfo.attributes.st.stride, drawInfo.attributes.st.pointer));
|
||||
#if UF_ENV_DREAMCAST
|
||||
GL_ERROR_CHECK(glDisable(GL_BLEND));
|
||||
#endif
|
||||
if ( drawInfo.textures.secondary.image && drawInfo.attributes.st.pointer ) {
|
||||
// static GLuint previous = 0;
|
||||
// if ( previous != drawInfo.textures.secondary.image ) previous = drawInfo.textures.secondary.image;
|
||||
|
||||
GL_ERROR_CHECK(glClientActiveTexture(GL_TEXTURE1));
|
||||
GL_ERROR_CHECK(glActiveTexture(GL_TEXTURE1));
|
||||
GL_ERROR_CHECK(glEnable(drawInfo.textures.secondary.viewType));
|
||||
GL_ERROR_CHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
GL_ERROR_CHECK(glBindTexture(drawInfo.textures.secondary.viewType, drawInfo.textures.secondary.image));
|
||||
GL_ERROR_CHECK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
|
||||
#if UF_ENV_DREAMCAST
|
||||
if ( blending ) GL_ERROR_CHECK(glDisable(GL_BLEND));
|
||||
#endif
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, GL_FLOAT, drawInfo.attributes.st.stride, drawInfo.attributes.st.pointer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( drawInfo.attributes.normal.pointer ) GL_ERROR_CHECK(glNormalPointer(GL_FLOAT, drawInfo.attributes.normal.stride, drawInfo.attributes.normal.pointer));
|
||||
if ( drawInfo.attributes.color.pointer ) GL_ERROR_CHECK(glColorPointer(4, GL_UNSIGNED_BYTE, drawInfo.attributes.color.stride, drawInfo.attributes.color.pointer));
|
||||
GL_ERROR_CHECK(glVertexPointer(3, GL_FLOAT, drawInfo.attributes.position.stride, drawInfo.attributes.position.pointer));
|
||||
GL_ERROR_CHECK(glDrawElements(GL_TRIANGLES, drawInfo.attributes.index.length, indicesType, drawInfo.attributes.index.pointer));
|
||||
|
||||
if ( drawInfo.textures.secondary.image ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
if ( blending ) GL_ERROR_CHECK(glEnable(GL_BLEND));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( drawInfo.textures.secondary.image ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
|
||||
@ -36,7 +36,7 @@ void ext::opengl::Device::HandlePool::allocate( size_t count ) {
|
||||
available.resize(initial + count);
|
||||
switch ( type ) {
|
||||
case enums::Command::GENERATE_TEXTURE: GL_ERROR_CHECK(glGenTextures(count, &available[initial])); break;
|
||||
#if !UF_ENV_DREAMCAST
|
||||
#if !UF_USE_OPENGL_FIXED_FUNCTION
|
||||
case enums::Command::GENERATE_BUFFER: GL_ERROR_CHECK(glGenBuffers(count, &available[initial])); break;
|
||||
#endif
|
||||
}
|
||||
@ -44,7 +44,7 @@ void ext::opengl::Device::HandlePool::allocate( size_t count ) {
|
||||
void ext::opengl::Device::HandlePool::clear() {
|
||||
switch ( type ) {
|
||||
case enums::Command::GENERATE_TEXTURE: GL_ERROR_CHECK(glDeleteTextures(available.size(), &available[0])); break;
|
||||
#if !UF_ENV_DREAMCAST
|
||||
#if !UF_USE_OPENGL_FIXED_FUNCTION
|
||||
case enums::Command::GENERATE_BUFFER: GL_ERROR_CHECK(glDeleteBuffers(available.size(), &available[0])); break;
|
||||
#endif
|
||||
}
|
||||
@ -57,7 +57,7 @@ bool ext::opengl::Device::HandlePool::used( ext::opengl::Device::HandlePool::han
|
||||
size_t ext::opengl::Device::HandlePool::alloc( ext::opengl::Device::HandlePool::handle_t& target ) {
|
||||
switch ( type ) {
|
||||
case enums::Command::GENERATE_TEXTURE: if ( glIsTexture(target) ) return SIZE_MAX; break;
|
||||
#if !UF_ENV_DREAMCAST
|
||||
#if !UF_USE_OPENGL_FIXED_FUNCTION
|
||||
case enums::Command::GENERATE_BUFFER: if ( glIsBuffer(target) ) return SIZE_MAX; break;
|
||||
#endif
|
||||
}
|
||||
@ -79,7 +79,7 @@ void ext::opengl::Device::HandlePool::free( ext::opengl::Device::HandlePool::han
|
||||
|
||||
switch ( type ) {
|
||||
case enums::Command::GENERATE_TEXTURE: if ( glIsTexture(index) ) glDeleteTextures(1, &index); break;
|
||||
#if !UF_ENV_DREAMCAST
|
||||
#if !UF_USE_OPENGL_FIXED_FUNCTION
|
||||
case enums::Command::GENERATE_BUFFER: if ( glIsBuffer(index) ) glDeleteBuffers(1, &index); break;
|
||||
#endif
|
||||
}
|
||||
@ -89,15 +89,15 @@ void ext::opengl::Device::initialize() {
|
||||
spec::Context::globalInit();
|
||||
activateContext();
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_USE_OPENGL_GLDC
|
||||
GLdcConfig config;
|
||||
glKosInitConfig(&config);
|
||||
config.fsaa_enabled = GL_FALSE;
|
||||
glKosInitEx(&config);
|
||||
#else
|
||||
glKosInit();
|
||||
#endif
|
||||
#if UF_USE_OPENGL_GLDC
|
||||
GLdcConfig config;
|
||||
glKosInitConfig(&config);
|
||||
config.fsaa_enabled = GL_FALSE;
|
||||
glKosInitEx(&config);
|
||||
#elif UF_ENV_DREAMCAST
|
||||
UF_MSG_DEBUG("?");
|
||||
glKosInit();
|
||||
UF_MSG_DEBUG("!");
|
||||
#else
|
||||
glewExperimental = GL_TRUE;
|
||||
GLenum error;
|
||||
|
||||
@ -397,17 +397,26 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
||||
drawCommandInfo.attributes.index.pointer = (void*) ((uint8_t*) drawCommandInfo.attributes.index.pointer + drawCommand.indexID * drawCommandInfo.attributes.index.stride);
|
||||
drawCommandInfo.attributes.index.length = drawCommand.indices;
|
||||
|
||||
for ( auto attribute : descriptor.inputs.vertex.attributes ) {
|
||||
for ( uf::Mesh::Attribute attribute : descriptor.inputs.vertex.attributes ) {
|
||||
attribute.pointer = (void*) ((uint8_t*) attribute.pointer + drawCommand.vertexID * attribute.stride);
|
||||
attribute.length = drawCommand.vertices;
|
||||
|
||||
if ( attribute.descriptor.name == "position" ) drawCommandInfo.attributes.position = attribute;
|
||||
else if ( attribute.descriptor.name == "uv" ) drawCommandInfo.attributes.uv = attribute;
|
||||
else if ( attribute.descriptor.name == "st" ) drawCommandInfo.attributes.st = attribute;
|
||||
// else if ( attribute.descriptor.name == "normal" ) drawCommandInfo.attributes.normal = attribute;
|
||||
// else if ( attribute.descriptor.name == "color" ) drawCommandInfo.attributes.color = attribute;
|
||||
else if ( attribute.descriptor.name == "normal" ) drawCommandInfo.attributes.normal = attribute;
|
||||
else if ( attribute.descriptor.name == "color" ) drawCommandInfo.attributes.color = attribute;
|
||||
}
|
||||
|
||||
/*
|
||||
for ( size_t i = 0; i < drawCommand.vertices; ++i ) {
|
||||
float* p = (float*) (drawCommandInfo.attributes.position.pointer + i * drawCommandInfo.attributes.position.stride + drawCommandInfo.attributes.position.descriptor.offset);
|
||||
float* uv = (float*) (drawCommandInfo.attributes.uv.pointer + i * drawCommandInfo.attributes.uv.stride + drawCommandInfo.attributes.uv.descriptor.offset);
|
||||
std::cout << "(" << p[0] << ", " << p[1] << ", " << p[2] << "|" << uv[0] << ", " << uv[1] << ") ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
*/
|
||||
|
||||
drawCommandInfo.attributes.instance.pointer = &instance;
|
||||
drawCommandInfo.attributes.instance.length = sizeof(instance);
|
||||
|
||||
@ -435,7 +444,6 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
||||
auto uniformBuffer = (*uniformBufferIt++).buffer;
|
||||
auto uniformOffset = (size_t) 0;
|
||||
|
||||
pod::Uniform* uniforms = (pod::Uniform*) device->getBuffer( uniformBuffer );
|
||||
|
||||
CommandBuffer::InfoDraw drawCommandInfo = {};
|
||||
drawCommandInfo.type = ext::opengl::enums::Command::DRAW;
|
||||
@ -451,9 +459,12 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
||||
|
||||
drawCommandInfo.textures.primary = this->material.textures.front().descriptor;
|
||||
|
||||
drawCommandInfo.matrices.model = NULL;
|
||||
drawCommandInfo.matrices.view = &uniforms->modelView;
|
||||
drawCommandInfo.matrices.projection = &uniforms->projection;
|
||||
if ( !uniformBuffers.empty() ) {
|
||||
pod::Uniform* uniforms = (pod::Uniform*) device->getBuffer( uniformBuffer );
|
||||
drawCommandInfo.matrices.model = NULL;
|
||||
drawCommandInfo.matrices.view = &uniforms->modelView;
|
||||
drawCommandInfo.matrices.projection = &uniforms->projection;
|
||||
}
|
||||
|
||||
commandBuffer.record(drawCommandInfo);
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ void ext::opengl::BaseRenderMode::initialize( Device& device ) {
|
||||
|
||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||
GL_ERROR_CHECK(glDepthFunc(GL_GEQUAL));
|
||||
#if !UF_ENV_DREAMCAST || (UF_ENV_DREAMCAST && UF_USE_OPENGL_GLDC)
|
||||
#if !UF_ENV_DREAMCAST || UF_USE_OPENGL_GLDC
|
||||
glDepthRange(0, 1);
|
||||
#endif
|
||||
} else {
|
||||
|
||||
@ -253,7 +253,7 @@ void ext::opengl::Texture::update( uf::Image& image, uint32_t layer ) {
|
||||
return this->update( (void*) image.getPixelsPtr(), image.getPixels().size(), layer );
|
||||
}
|
||||
void ext::opengl::Texture::update( void* data, size_t bufferSize, uint32_t layer ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_ENV_DREAMCAST || UF_USE_OPENGL_GLDC
|
||||
if ( internalFormat > 0 ) {
|
||||
GL_MUTEX_LOCK();
|
||||
GL_ERROR_CHECK(glBindTexture(viewType, image));
|
||||
@ -287,7 +287,7 @@ void ext::opengl::Texture::update( void* data, size_t bufferSize, uint32_t layer
|
||||
GL_ERROR_CHECK(glBindTexture(viewType, image));
|
||||
switch ( viewType ) {
|
||||
case enums::Image::VIEW_TYPE_2D: { GL_ERROR_CHECK(glTexImage2D(viewType, 0, format, width, height, 0, format, type, data)); } break;
|
||||
#if !UF_ENV_DREAMCAST
|
||||
#if !UF_USE_OPENGL_FIXED_FUNCTION
|
||||
case enums::Image::VIEW_TYPE_3D: { GL_ERROR_CHECK(glTexImage3D(viewType, 0, format, width, height, depth, 0, format, type, data)); } break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#include <uf/utils/io/iostream.h>
|
||||
|
||||
#if UF_ENV_WINDOWS && !UF_USE_SFML
|
||||
#if UF_ENV_WINDOWS && UF_USE_OPENGL && !UF_USE_OPENGL_GLDC
|
||||
UF_API_CALL spec::win32::Context::Context( uni::Context* shared, const Context::Settings& settings ) :
|
||||
uni::Context( NULL, true, settings ),
|
||||
m_deviceContext (NULL),
|
||||
@ -11,21 +11,18 @@ UF_API_CALL spec::win32::Context::Context( uni::Context* shared, const Context::
|
||||
// Creating a dummy window is mandatory: we could create a memory DC but then
|
||||
// its pixel format wouldn't match the regular contexts' format, and thus
|
||||
// wglShareLists would always fail. Too bad...
|
||||
#if UF_USE_OPENGL
|
||||
// Create a dummy window (disabled and hidden)
|
||||
this->m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL);
|
||||
ShowWindow(this->m_window, SW_HIDE);
|
||||
this->m_deviceContext = GetDC(this->m_window);
|
||||
|
||||
if ( this->m_deviceContext ) this->create(shared);
|
||||
#endif
|
||||
}
|
||||
UF_API_CALL spec::win32::Context::Context( uni::Context* shared, const Context::Settings& settings, const Context::window_t& window ) :
|
||||
uni::Context( NULL, false, settings ),
|
||||
m_deviceContext (NULL),
|
||||
m_context (NULL)
|
||||
{
|
||||
#if UF_USE_OPENGL
|
||||
// Get the owner window and its device context
|
||||
this->m_window = window.getHandle();
|
||||
this->m_deviceContext = GetDC(this->m_window);
|
||||
@ -33,7 +30,6 @@ UF_API_CALL spec::win32::Context::Context( uni::Context* shared, const Context::
|
||||
// Create the context
|
||||
if ( this->m_deviceContext )
|
||||
this->create(shared);
|
||||
#endif
|
||||
}
|
||||
UF_API_CALL spec::win32::Context::Context( uni::Context* shared, const Context::Settings& settings, unsigned int width, unsigned int height ) : Context( shared, settings ) {
|
||||
|
||||
@ -43,7 +39,6 @@ spec::win32::Context::~Context() {
|
||||
}
|
||||
|
||||
void UF_API_CALL spec::win32::Context::create( uni::Context* shared ) {
|
||||
#if UF_USE_OPENGL
|
||||
// this->m_settings = settings;
|
||||
Context::Settings glSettings{24, 4, 8, 0, 3, 3};
|
||||
|
||||
@ -206,10 +201,8 @@ void UF_API_CALL spec::win32::Context::create( uni::Context* shared ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void UF_API_CALL spec::win32::Context::terminate() {
|
||||
#if UF_USE_OPENGL
|
||||
// Destroy the OpenGL context
|
||||
if ( this->m_context ) {
|
||||
if ( wglGetCurrentContext() == this->m_context) wglMakeCurrent(NULL, NULL);
|
||||
@ -221,28 +214,19 @@ void UF_API_CALL spec::win32::Context::terminate() {
|
||||
|
||||
// Destroy the window if we own it
|
||||
if ( this->m_window && this->m_ownsWindow ) DestroyWindow(this->m_window);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool spec::win32::Context::makeCurrent() {
|
||||
#if UF_USE_OPENGL
|
||||
return this->m_deviceContext && this->m_context && wglMakeCurrent(this->m_deviceContext, this->m_context);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void spec::win32::Context::display() {
|
||||
#if UF_USE_OPENGL
|
||||
if (this->m_deviceContext && this->m_context)
|
||||
SwapBuffers(this->m_deviceContext);
|
||||
#endif
|
||||
}
|
||||
|
||||
void spec::win32::Context::setVerticalSyncEnabled(bool enabled) {
|
||||
#if UF_USE_OPENGL
|
||||
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
|
||||
if (wglSwapIntervalEXT) wglSwapIntervalEXT(enabled ? 1 : 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
void spec::win32::controller::initialize() {}
|
||||
void spec::win32::controller::tick() {
|
||||
#if 0 || UF_USE_OPENVR
|
||||
#if 0 && UF_USE_OPENVR
|
||||
if ( ext::openvr::context ) {
|
||||
uf::stl::string key = "";
|
||||
if ( name == "R_DPAD_UP" ) { i = vr::Controller_Hand::Hand_Right; key = "dpadUp"; }
|
||||
|
||||
@ -88,14 +88,14 @@ uf::stl::string uf::Image::getFilename() const {
|
||||
|
||||
// from file
|
||||
bool uf::Image::open( const uf::stl::string& filename, bool flip ) {
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_USE_OPENGL_GLDC
|
||||
uf::stl::string extension = uf::io::extension(filename);
|
||||
if ( extension != "dtex" ) {
|
||||
uf::stl::string dtex = uf::string::replace( filename, ".png", ".dtex" );
|
||||
if ( uf::io::exists(dtex) ) return this->open(dtex, flip);
|
||||
|
||||
UF_EXCEPTION("non-dtex loading is highly discouraged on this platform:" << filename);
|
||||
return false;
|
||||
UF_MSG_WARNING("non-dtex loading is highly discouraged on this platform:" << filename);
|
||||
// return false;
|
||||
}
|
||||
#endif
|
||||
if ( !uf::io::exists(filename) ) UF_EXCEPTION("IO error: file does not exist: " + filename);
|
||||
@ -103,7 +103,7 @@ bool uf::Image::open( const uf::stl::string& filename, bool flip ) {
|
||||
this->m_filename = filename;
|
||||
this->m_pixels.clear();
|
||||
int width = 0, height = 0, channelsDud = 0, bit_depth = 8, channels = 4;
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if UF_USE_OPENGL_GLDC
|
||||
if ( extension == "dtex" ) {
|
||||
struct {
|
||||
char id[4]; // 'DTEX'
|
||||
|
||||
@ -60,8 +60,30 @@ void uf::Mesh::destroy() {
|
||||
}
|
||||
uf::Mesh uf::Mesh::interleave() const {
|
||||
uf::Mesh interleaved;
|
||||
auto& buffer = interleaved.buffers.emplace_back();
|
||||
interleaved.vertex.interleaved = true;
|
||||
interleaved.index.interleaved = false;
|
||||
interleaved.instance.interleaved = true;
|
||||
interleaved.indirect.interleaved = false;
|
||||
interleaved.bind(*this);
|
||||
|
||||
#define PARSE_INPUT_INTERLEAVED(N){\
|
||||
uf::Mesh::Input input = N;\
|
||||
interleaved.N = input;\
|
||||
auto& buffer = interleaved.buffers.at(interleaved.N.interleaved);\
|
||||
while ( input.count-- ) {\
|
||||
for ( auto& attribute : input.attributes ) {\
|
||||
buffer.insert( buffer.end(), (uint8_t*) attribute.pointer, (uint8_t*) attribute.pointer + attribute.descriptor.size );\
|
||||
attribute.pointer += input.stride;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
PARSE_INPUT_INTERLEAVED(vertex);
|
||||
interleaved.insertIndices(*this);
|
||||
PARSE_INPUT_INTERLEAVED(instance);
|
||||
interleaved.insertIndirects(*this);
|
||||
/*
|
||||
auto& buffer = interleaved.buffers.emplace_back();
|
||||
#define PARSE_INPUT_INTERLEAVED(name) {\
|
||||
interleaved.name = name;\
|
||||
interleaved.name.offset = buffer.size();\
|
||||
@ -72,7 +94,7 @@ uf::Mesh uf::Mesh::interleave() const {
|
||||
PARSE_INPUT_INTERLEAVED(index);
|
||||
PARSE_INPUT_INTERLEAVED(instance);
|
||||
PARSE_INPUT_INTERLEAVED(indirect);
|
||||
|
||||
*/
|
||||
return interleaved;
|
||||
}
|
||||
void uf::Mesh::updateDescriptor() {
|
||||
@ -269,7 +291,7 @@ void uf::Mesh::_updateDescriptor( uf::Mesh::Input& input ) {
|
||||
const bool interleaved = isInterleaved(input.interleaved);
|
||||
auto& buffer = buffers[interleaved ? input.interleaved : attribute.buffer];
|
||||
attribute.length = buffer.size();
|
||||
attribute.pointer = (void*) (buffer.data());
|
||||
attribute.pointer = (void*) (buffer.data() + attribute.offset);
|
||||
if ( !interleaved ) attribute.stride = attribute.descriptor.size;
|
||||
input.stride += attribute.descriptor.size;
|
||||
}
|
||||
|
||||
@ -36,10 +36,10 @@ namespace {
|
||||
float scaleY = 1;
|
||||
|
||||
mesh.insertVertices<uf::graph::mesh::Base>({
|
||||
{ {-1.0f * scaleX, 1.0f * scaleY, 0.0f}, {}, {0.0f, 1.0f}, {0.0f, 1.0f}, {0.0f, 0.0f, -1.0f} },
|
||||
{ {-1.0f * scaleX, -1.0f * scaleY, 0.0f}, {}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, -1.0f} },
|
||||
{ {1.0f * scaleX, -1.0f * scaleY, 0.0f}, {}, {1.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, -1.0f} },
|
||||
{ {1.0f * scaleX, 1.0f * scaleY, 0.0f}, {}, {1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f, -1.0f}, }
|
||||
{ {-1.0f * scaleX, 1.0f * scaleY, 0.0f}, {0.0f, 1.0f}, {}, {0.0f, 1.0f}, {0.0f, 0.0f, -1.0f} },
|
||||
{ {-1.0f * scaleX, -1.0f * scaleY, 0.0f}, {0.0f, 0.0f}, {}, {0.0f, 0.0f}, {0.0f, 0.0f, -1.0f} },
|
||||
{ {1.0f * scaleX, -1.0f * scaleY, 0.0f}, {1.0f, 0.0f}, {}, {1.0f, 0.0f}, {0.0f, 0.0f, -1.0f} },
|
||||
{ {1.0f * scaleX, 1.0f * scaleY, 0.0f}, {1.0f, 1.0f}, {}, {1.0f, 1.0f}, {0.0f, 0.0f, -1.0f}, }
|
||||
});
|
||||
mesh.insertIndices<uint16_t>({
|
||||
0, 1, 2, 2, 3, 0
|
||||
|
||||
Loading…
Reference in New Issue
Block a user