more fixes
This commit is contained in:
parent
a2636e834c
commit
65a08839f9
@ -274,7 +274,7 @@
|
||||
"rebuild on tick begin": false
|
||||
},
|
||||
"pipelines": {
|
||||
"culling": false
|
||||
"culling": true
|
||||
},
|
||||
"experimental": {
|
||||
"rebuild on tick begin": false,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"import": "./base_sourceengine.json",
|
||||
"assets": [
|
||||
// { "filename": "./maps/cs_office.bsp" }
|
||||
{ "filename": "./maps/cs_office/graph.json" }
|
||||
{ "filename": "./maps/cs_office.bsp" }
|
||||
// { "filename": "./maps/cs_office/graph.json" }
|
||||
]
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"import": "./base_sourceengine.json",
|
||||
"assets": [
|
||||
{ "filename": "./maps/de_dust2.bsp" }
|
||||
// { "filename": "./maps/de_dust2/graph.json" }
|
||||
// { "filename": "./maps/de_dust2.bsp" }
|
||||
{ "filename": "./maps/de_dust2/graph.json" }
|
||||
]
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
{
|
||||
// "import": "./rp_downtown_v2.json"
|
||||
// "import": "./ss2_medsci1.json"
|
||||
"import": "./mds_mcdonalds.json"
|
||||
// "import": "./cs_office.json"
|
||||
// "import": "./mds_mcdonalds.json"
|
||||
"import": "./cs_office.json"
|
||||
// "import": "./de_dust2.json"
|
||||
// "import": "./gm_construct.json"
|
||||
}
|
||||
@ -97,6 +97,10 @@ struct Bounds {
|
||||
float padding1;
|
||||
vec3 max;
|
||||
float padding2;
|
||||
vec3 center;
|
||||
float padding3;
|
||||
vec3 extent;
|
||||
float padding4;
|
||||
};
|
||||
|
||||
struct LOD {
|
||||
|
||||
@ -27,8 +27,8 @@ float mipLevels( ivec2 size ) {
|
||||
|
||||
vec4 aabbToSphere( Bounds bounds ) {
|
||||
vec4 sphere;
|
||||
sphere.xyz = (bounds.max + bounds.min) * 0.5;
|
||||
sphere.w = length((bounds.max - bounds.min) * 0.5);
|
||||
sphere.xyz = bounds.center;
|
||||
sphere.w = length( bounds.extent );
|
||||
return sphere;
|
||||
}
|
||||
|
||||
|
||||
@ -182,4 +182,8 @@ static const type_t ASTC_10x10_SRGB_BLOCK = 180;
|
||||
static const type_t ASTC_12x10_UNORM_BLOCK = 181;
|
||||
static const type_t ASTC_12x10_SRGB_BLOCK = 182;
|
||||
static const type_t ASTC_12x12_UNORM_BLOCK = 183;
|
||||
static const type_t ASTC_12x12_SRGB_BLOCK = 184;
|
||||
static const type_t ASTC_12x12_SRGB_BLOCK = 184;
|
||||
|
||||
static const type_t R8G8B8A8_RGBE = 255;
|
||||
static const type_t R8G8B8_UNORM_E8_SINT = R8G8B8A8_RGBE;
|
||||
static const type_t R8G8B8E8_UFLOAT = R8G8B8A8_RGBE;
|
||||
@ -182,4 +182,8 @@ static const type_t ASTC_10x10_SRGB_BLOCK = VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
|
||||
static const type_t ASTC_12x10_UNORM_BLOCK = VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
|
||||
static const type_t ASTC_12x10_SRGB_BLOCK = VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
|
||||
static const type_t ASTC_12x12_UNORM_BLOCK = VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
|
||||
static const type_t ASTC_12x12_SRGB_BLOCK = VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
|
||||
static const type_t ASTC_12x12_SRGB_BLOCK = VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
|
||||
|
||||
static const type_t R8G8B8A8_RGBE = (VkFormat)(255);
|
||||
static const type_t R8G8B8_UNORM_E8_SINT = R8G8B8A8_RGBE;
|
||||
static const type_t R8G8B8E8_UFLOAT = R8G8B8A8_RGBE;
|
||||
@ -93,7 +93,9 @@ namespace uf {
|
||||
size_t getChannels() const;
|
||||
|
||||
uf::stl::string getHash() const;
|
||||
size_t getFormat() const;
|
||||
|
||||
size_t getFormat( bool srgb = false ) const;
|
||||
void setFormat( size_t );
|
||||
|
||||
void setLayers( size_t );
|
||||
|
||||
|
||||
@ -126,6 +126,8 @@ namespace uf {
|
||||
slice.primitive.instance.auxID = atlasID;
|
||||
slice.primitive.instance.bounds.min = node.effectiveExtents.min;
|
||||
slice.primitive.instance.bounds.max = node.effectiveExtents.max;
|
||||
slice.primitive.instance.bounds.center = (node.effectiveExtents.max + node.effectiveExtents.min) * 0.5f;
|
||||
slice.primitive.instance.bounds.extent = (node.effectiveExtents.max - node.effectiveExtents.min) * 0.5f;
|
||||
|
||||
slice.primitive.drawCommand.indices = slice.indices.size();
|
||||
slice.primitive.drawCommand.instances = 1;
|
||||
|
||||
@ -103,9 +103,13 @@ namespace pod {
|
||||
// should be for the specific draw call itself, rather than the mesh(let) entirely
|
||||
struct Bounds {
|
||||
pod::Vector3f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||
alignas(4) float padding1 = 0;
|
||||
alignas(4) float padding1;
|
||||
pod::Vector3f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
||||
alignas(4) float padding2 = 0;
|
||||
alignas(4) float padding2;
|
||||
pod::Vector3f center = { 0, 0, 0 };
|
||||
alignas(4) float padding3;
|
||||
pod::Vector3f extent = { 0, 0, 0 };
|
||||
alignas(4) float padding4;
|
||||
} bounds;
|
||||
|
||||
// stores "pointers" on the GPU side for buffer locations, used for RT / recalculating barycentrics
|
||||
|
||||
@ -113,6 +113,8 @@ namespace {
|
||||
instance.jointID = -1;
|
||||
instance.bounds.min = boundsMin;
|
||||
instance.bounds.max = boundsMax;
|
||||
instance.bounds.center = (boundsMax + boundsMin) * 0.5f;
|
||||
instance.bounds.extent = (boundsMax - boundsMin) * 0.5f;
|
||||
|
||||
if ( sourceDrawCommands ) {
|
||||
drawCommand = sourceDrawCommands[drawCommandID];
|
||||
|
||||
@ -25,26 +25,46 @@
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
size_t deduceFormat( const uf::stl::string& format ) {
|
||||
if ( format == "ARGB4444" ) return uf::renderer::enums::Format::R4G4B4A4_UNORM_PACK16;
|
||||
if ( format == "RGB565" ) return uf::renderer::enums::Format::R5G6B5_UNORM_PACK16;
|
||||
return 0;
|
||||
}
|
||||
uf::Image decodeImage( ext::json::Value& json, pod::Graph& graph, const uf::stl::string& imageName ) {
|
||||
uf::Image image;
|
||||
|
||||
uf::stl::string filename = "";
|
||||
size_t offset = 0, length = 0, layers = json["layers"].as<size_t>(1);
|
||||
uf::stl::string formatHint = "";
|
||||
size_t offset = 0;
|
||||
size_t length = 0;
|
||||
size_t format = 0;
|
||||
size_t layers = json["layers"].as<size_t>(1);
|
||||
uf::stl::string extension = "";
|
||||
|
||||
if ( json["format"].is<uf::stl::string>() ) {
|
||||
format = deduceFormat( json["format"].as<uf::stl::string>() );
|
||||
} else {
|
||||
format = json["format"].as<size_t>();
|
||||
}
|
||||
#if UF_ENV_DREAMCAST
|
||||
if (json["dtex"].isObject()) {
|
||||
if ( json["dtex"].isObject() ) {
|
||||
filename = json["dtex"]["filename"].as<uf::stl::string>();
|
||||
extension = "dtex";
|
||||
|
||||
offset = json["dtex"]["offset"].as<size_t>();
|
||||
length = json["dtex"]["length"].as<size_t>();
|
||||
formatHint = "dtex";
|
||||
if ( json["dtex"]["format"].is<uf::stl::string>() ) {
|
||||
format = deduceFormat( json["dtex"]["format"].as<uf::stl::string>() );
|
||||
} else {
|
||||
format = json["dtex"]["format"].as<size_t>();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if ( json["filename"].is<uf::stl::string>() ) {
|
||||
filename = json["filename"].as<uf::stl::string>();
|
||||
extension = uf::io::extension(filename);
|
||||
|
||||
offset = json["offset"].as<size_t>(0);
|
||||
length = json["length"].as<size_t>(0);
|
||||
formatHint = uf::io::extension(filename);
|
||||
} else {
|
||||
auto size = uf::vector::decode( json["size"], pod::Vector2ui{} );
|
||||
size_t bpp = json["bpp"].as<size_t>();
|
||||
@ -52,6 +72,7 @@ namespace {
|
||||
auto pixels = uf::base64::decode( json["data"].as<uf::stl::string>() );
|
||||
image.loadFromBuffer( &pixels[0], size, bpp, channels, true );
|
||||
image.setLayers( layers );
|
||||
image.setFormat( format );
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -60,19 +81,20 @@ namespace {
|
||||
if ( graph.settings.stream.textures ) {
|
||||
auto& storage = uf::graph::getStorage(graph);
|
||||
graph.streams.images[imageName] = { fullPath, offset, length };
|
||||
image.setFilename(fullPath);
|
||||
} else {
|
||||
uf::stl::vector<uint8_t> buffer;
|
||||
if (length > 0) {
|
||||
uf::io::readAsBuffer(buffer, fullPath, offset, length);
|
||||
if ( length > 0 ) {
|
||||
uf::io::readAsBuffer( buffer, fullPath, offset, length );
|
||||
} else {
|
||||
uf::io::readAsBuffer(buffer, fullPath);
|
||||
uf::io::readAsBuffer( buffer, fullPath );
|
||||
}
|
||||
|
||||
uf::image::open( image, buffer, formatHint, false );
|
||||
uf::image::open( image, buffer, extension, false );
|
||||
uf::image::layers( image, layers );
|
||||
image.setFilename(fullPath);
|
||||
}
|
||||
|
||||
image.setFilename( fullPath );
|
||||
image.setFormat( format );
|
||||
|
||||
return image;
|
||||
}
|
||||
@ -252,7 +274,7 @@ namespace {
|
||||
uf::io::readAsBuffer(mesh.buffers[attr.buffer], region.filename, region.offset, region.length);
|
||||
}
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
#if 1 || UF_ENV_DREAMCAST
|
||||
// remove extraneous buffers
|
||||
// if ( graph.metadata["renderer"]["separate"].as<bool>() )
|
||||
{
|
||||
|
||||
@ -389,6 +389,7 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
|
||||
auto& image = storage.images.map.at(name).data;
|
||||
uf::Serializer json;
|
||||
json["name"] = name;
|
||||
json["format"] = image.getFormat();
|
||||
|
||||
if ( !settings.combined ) {
|
||||
uf::stl::string f = ::fmt::format("image.{}.png", i );
|
||||
@ -409,9 +410,44 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
|
||||
json["layers"] = image.layers;
|
||||
|
||||
#if UF_USE_DC_TEXCONV
|
||||
auto converted = image.scale( {32, 32}, "nearest" );
|
||||
auto img = uf::Image(image);
|
||||
pod::Vector2ui size = { 32, 32 };
|
||||
uf::stl::string filter = "nearest";
|
||||
uf::stl::string dtexFormat = "ARGB4444";
|
||||
if ( name == "lightmap_atlas" || img.getFormat() == uf::renderer::enums::Format::R8G8B8A8_RGBE ) {
|
||||
size = { 128, 128 };
|
||||
filter = "linear";
|
||||
dtexFormat = "RGB565";
|
||||
auto* pixels = (pod::Vector4ub*) img.getPixels().data();
|
||||
auto& size = img.getDimensions();
|
||||
for ( auto p = 0; p < size.x * size.y; ++p ) {
|
||||
auto& pixel = pixels[p];
|
||||
if ( pixel.w == 0 ) {
|
||||
pixel = {0,0,0,255};
|
||||
continue;
|
||||
}
|
||||
|
||||
// decode
|
||||
float exp = (float) pixel.w - 128.0f;
|
||||
float mult = std::exp2(exp);
|
||||
|
||||
const float gamma = 1.0f / 2.2f;
|
||||
auto linear = pod::Vector3f{ pixel.x, pixel.y, pixel.z } * mult / 255.0f;
|
||||
// tone-map
|
||||
FOR_EACH( 3, {
|
||||
linear[i] = linear[i] / ( 1 + linear[i] );
|
||||
});
|
||||
// gamma correct
|
||||
linear = uf::vector::pow( uf::vector::clamp( linear, 0.0f, 1.0f ), gamma );
|
||||
// 0-1 => 0-255
|
||||
linear *= 255.0f;
|
||||
pixel = { (uint8_t)(linear.x), (uint8_t)(linear.y), (uint8_t)(linear.z), 255 };
|
||||
}
|
||||
}
|
||||
|
||||
img = img.scale( size, filter );
|
||||
uf::stl::vector<uint8_t> dtexBytes;
|
||||
auto dtex = ext::texconv::convert( converted );
|
||||
auto dtex = ext::texconv::convert( img, dtexFormat );
|
||||
ext::texconv::save( dtex, dtexBytes );
|
||||
|
||||
size_t dtexOffset = dtexBuffer.size();
|
||||
@ -421,6 +457,7 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
|
||||
json["dtex"]["filename"] = dtexBinName;
|
||||
json["dtex"]["offset"] = dtexOffset;
|
||||
json["dtex"]["length"] = dtexLength;
|
||||
json["dtex"]["format"] = dtexFormat;
|
||||
#endif
|
||||
|
||||
serializer["images"].emplace_back( json );
|
||||
|
||||
@ -837,7 +837,37 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
graphMetadataJson["baking"]["enabled"] = false;
|
||||
textureDescriptors["lightmap_atlas"].srgb = false;
|
||||
|
||||
if ( !graphMetadataJson["lights"]["lightmap"].as<bool>() ) {
|
||||
if ( graphMetadataJson["lights"]["lightmap"].as<bool>() ) {
|
||||
#if UF_USE_OPENGL && !UF_ENV_DREAMCAST
|
||||
auto& image = storage.images["lightmap_atlas"].data;
|
||||
auto* pixels = (pod::Vector4ub*) image.getPixels().data();
|
||||
auto& size = image.getDimensions();
|
||||
for ( auto p = 0; p < size.x * size.y; ++p ) {
|
||||
auto& pixel = pixels[p];
|
||||
if ( pixel.w == 0 ) {
|
||||
pixel = {0,0,0,255};
|
||||
continue;
|
||||
}
|
||||
|
||||
// decode
|
||||
float exp = (float) pixel.w - 128.0f;
|
||||
float mult = std::exp2(exp);
|
||||
|
||||
const float gamma = 1.0f / 2.2f;
|
||||
auto linear = pod::Vector3f{ pixel.x, pixel.y, pixel.z } * mult / 255.0f;
|
||||
// tone-map
|
||||
FOR_EACH( 3, {
|
||||
linear[i] = linear[i] / ( 1 + linear[i] );
|
||||
});
|
||||
// gamma correct
|
||||
linear = uf::vector::pow( uf::vector::clamp( linear, 0.0f, 1.0f ), gamma );
|
||||
// 0-1 => 0-255
|
||||
linear *= 255.0f;
|
||||
pixel = { (uint8_t)(linear.x), (uint8_t)(linear.y), (uint8_t)(linear.z), 255 };
|
||||
}
|
||||
// to-do: update format
|
||||
#endif
|
||||
} else {
|
||||
for ( auto& name : graph.primitives ) {
|
||||
auto& primitives = storage.primitives[name];
|
||||
for ( auto& primitive : primitives ) {
|
||||
@ -1555,6 +1585,9 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
grouped.emplace_back(newInstance);
|
||||
}
|
||||
|
||||
bounds.center = (bounds.max + bounds.min) * 0.5f;
|
||||
bounds.extent = uf::vector::abs(bounds.max - bounds.min) * 0.5f;
|
||||
|
||||
#if !UF_GRAPH_EXTENDED
|
||||
bool isFirstInstance = ( grouped.size() == primitives.size() );
|
||||
bool isSkinned = graphMetadataJson["renderer"]["skinned"].as<bool>();
|
||||
@ -1575,16 +1608,10 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
|
||||
bool isMesh = type == "mesh" || type == "hull";
|
||||
if ( !isMesh ) {
|
||||
auto min = bounds.min; // uf::matrix::multiply<float>( model, bounds.min, 1.0f );
|
||||
auto max = bounds.max; // uf::matrix::multiply<float>( model, bounds.max, 1.0f );
|
||||
|
||||
pod::Vector3f center = (max + min) * 0.5f;
|
||||
pod::Vector3f extent = uf::vector::abs(max - min) * 0.5f;
|
||||
|
||||
if ( ext::json::isNull( metadataJson["physics"]["center"] ) ) metadataJson["physics"]["center"] = uf::vector::encode( center );
|
||||
if ( ext::json::isNull( metadataJson["physics"]["extent"] ) ) metadataJson["physics"]["extent"] = uf::vector::encode( extent );
|
||||
if ( ext::json::isNull( metadataJson["physics"]["min"] ) ) metadataJson["physics"]["min"] = uf::vector::encode( min );
|
||||
if ( ext::json::isNull( metadataJson["physics"]["max"] ) ) metadataJson["physics"]["max"] = uf::vector::encode( max );
|
||||
if ( ext::json::isNull( metadataJson["physics"]["center"] ) ) metadataJson["physics"]["center"] = uf::vector::encode( bounds.center );
|
||||
if ( ext::json::isNull( metadataJson["physics"]["extent"] ) ) metadataJson["physics"]["extent"] = uf::vector::encode( bounds.extent );
|
||||
if ( ext::json::isNull( metadataJson["physics"]["min"] ) ) metadataJson["physics"]["min"] = uf::vector::encode( bounds.min );
|
||||
if ( ext::json::isNull( metadataJson["physics"]["max"] ) ) metadataJson["physics"]["max"] = uf::vector::encode( bounds.max );
|
||||
}
|
||||
#if !UF_GRAPH_EXTENDED
|
||||
if ( isMesh ) {
|
||||
@ -2108,7 +2135,7 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) {
|
||||
auto& instance = primitive.instance;
|
||||
auto& drawCommand = primitive.drawCommand;
|
||||
|
||||
pod::Vector3f center = uf::matrix::multiply( model, (instance.bounds.max + instance.bounds.min) * 0.5f, 1.0f ); // transform the center of the draw call
|
||||
pod::Vector3f center = uf::matrix::multiply( model, instance.bounds.center, 1.0f ); // transform the center of the draw call
|
||||
float distanceSquared = uf::vector::distanceSquared( center, controllerPosition ); // saves a sqrt()
|
||||
|
||||
// store closest draw call
|
||||
|
||||
@ -186,6 +186,9 @@ for ( auto& p : m.primitives ) {
|
||||
meshlet.primitive.drawCommand.instanceID = 0;
|
||||
meshlet.primitive.drawCommand.vertices = meshlet.vertices.size();
|
||||
|
||||
meshlet.primitive.instance.bounds.center = (meshlet.primitive.instance.bounds.max + meshlet.primitive.instance.bounds.min) * 0.5f;
|
||||
meshlet.primitive.instance.bounds.extent = (meshlet.primitive.instance.bounds.max - meshlet.primitive.instance.bounds.min) * 0.5f;
|
||||
|
||||
/* detect winding order */ if ( sanitizer.windingOrder.should ) {
|
||||
sanitizer.windingOrder.corrected += uf::mesh::windingOrder( meshlet.vertices, meshlet.indices );
|
||||
sanitizer.windingOrder.total += meshlet.indices.empty() ? meshlet.vertices.size() : meshlet.indices.size();
|
||||
|
||||
@ -197,71 +197,29 @@ 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 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 },
|
||||
pod::Vector4f{ instance.bounds.max.x, instance.bounds.max.y, instance.bounds.min.z, 1.0f },
|
||||
pod::Vector4f{ instance.bounds.min.x, instance.bounds.max.y, instance.bounds.min.z, 1.0f },
|
||||
#pragma unroll
|
||||
for ( auto p = 0; p < 4; ++p ) {
|
||||
int i = p / 2;
|
||||
int j = p % 2;
|
||||
|
||||
pod::Vector4f{ instance.bounds.min.x, instance.bounds.min.y, instance.bounds.max.z, 1.0f },
|
||||
pod::Vector4f{ instance.bounds.max.x, instance.bounds.min.y, instance.bounds.max.z, 1.0f },
|
||||
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
|
||||
for ( uint p = 0; p < 8; ++p ) {
|
||||
pod::Vector4f t = uf::matrix::multiply( mat, corners[p] );
|
||||
float w = t.w * 1.25f;
|
||||
if ( -w <= t.x && t.x <= w && -w <= t.y && t.y <= w && -w <= t.z && t.z <= w ) return true;
|
||||
}
|
||||
#else
|
||||
pod::Vector4f planes[6]; {
|
||||
#pragma unroll
|
||||
for ( auto i = 0; i < 3; ++i )
|
||||
#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]);
|
||||
float z = mat[4*2+3] + (j == 0 ? mat[4*2+i] : -mat[4*2+i]);
|
||||
float w = mat[4*3+3] + (j == 0 ? mat[4*3+i] : -mat[4*3+i]);
|
||||
float length = 1.0f / sqrt( x * x + y * y + z * z );
|
||||
|
||||
planes[i*2+j] = pod::Vector4f{ x * length, y * length, z * length, w * length };
|
||||
}
|
||||
}
|
||||
#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.z * planes[p].z, instance.bounds.max.z * planes[p].z);
|
||||
if ( d > -planes[p].w ) return true;
|
||||
}
|
||||
#else
|
||||
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 },
|
||||
pod::Vector4f{ instance.bounds.max.x, instance.bounds.max.y, instance.bounds.min.z, 1.0f },
|
||||
pod::Vector4f{ instance.bounds.min.x, instance.bounds.max.y, instance.bounds.min.z, 1.0f },
|
||||
float x = mat(0,3) + (j == 0 ? mat(0,i) : -mat(0,i));
|
||||
float y = mat(1,3) + (j == 0 ? mat(1,i) : -mat(1,i));
|
||||
float z = mat(2,3) + (j == 0 ? mat(2,i) : -mat(2,i));
|
||||
float w = mat(3,3) + (j == 0 ? mat(3,i) : -mat(3,i));
|
||||
|
||||
pod::Vector4f{ instance.bounds.min.x, instance.bounds.min.y, instance.bounds.max.z, 1.0f },
|
||||
pod::Vector4f{ instance.bounds.max.x, instance.bounds.min.y, instance.bounds.max.z, 1.0f },
|
||||
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
|
||||
for ( uint p = 0; p < 8; ++p ) corners[p] = uf::matrix::multiply( mat, corners[p] );
|
||||
#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;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return visible;
|
||||
float length = 1.0f / std::sqrt( x * x + y * y + z * z );
|
||||
|
||||
pod::Vector3f normal = { x * length, y * length, z * length };
|
||||
float planeDist = w * length;
|
||||
|
||||
pod::Vector3f absNormal = uf::vector::abs(normal);
|
||||
float r = uf::vector::dot(instance.bounds.extent, absNormal);
|
||||
float d = uf::vector::dot(instance.bounds.center, normal) + planeDist;
|
||||
|
||||
if ( d < -r ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,8 +233,8 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
if ( drawInfo.matrices.projection ) projection = *drawInfo.matrices.projection;
|
||||
|
||||
if ( drawInfo.attributes.indirect.pointer && drawInfo.attributes.indirect.length == sizeof(pod::DrawCommand) ) {
|
||||
pod::DrawCommand& drawCommand = *(pod::DrawCommand*) drawInfo.attributes.indirect.pointer;
|
||||
if ( ext::opengl::settings::pipelines::culling && drawInfo.attributes.instance.pointer && drawInfo.attributes.instance.length == sizeof(pod::Instance) ) {
|
||||
pod::DrawCommand& drawCommand = *(pod::DrawCommand*) drawInfo.attributes.indirect.pointer;
|
||||
pod::Instance& instance = *(pod::Instance*) drawInfo.attributes.instance.pointer;
|
||||
pod::Matrix4f mat = (*drawInfo.matrices.projection) * (*drawInfo.matrices.view) * (*drawInfo.matrices.model);
|
||||
|
||||
@ -447,11 +405,15 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
GL_ERROR_CHECK(glNormalPointer(normalType, drawInfo.attributes.normal.stride, normalPtr));
|
||||
}
|
||||
|
||||
// prioritize uniform color for now
|
||||
if ( drawInfo.color.enabled ) {
|
||||
const auto& color = drawInfo.color.pointer ? *drawInfo.color.pointer : drawInfo.color.value;
|
||||
{
|
||||
pod::Vector4f color = {1,1,1,1};
|
||||
if ( drawInfo.color.enabled ) {
|
||||
color = drawInfo.color.pointer ? *drawInfo.color.pointer : drawInfo.color.value;
|
||||
}
|
||||
GL_ERROR_CHECK(glColor4f( color[0], color[1], color[2], color[3] ));
|
||||
} else if ( drawInfo.attributes.color.pointer ) {
|
||||
}
|
||||
|
||||
if ( drawInfo.attributes.color.pointer ) {
|
||||
GLenum colorType = GL_UNSIGNED_BYTE;
|
||||
switch ( drawInfo.attributes.color.descriptor.size / drawInfo.attributes.color.descriptor.components ) {
|
||||
case sizeof(uint8_t): colorType = GL_UNSIGNED_BYTE; break;
|
||||
@ -459,8 +421,6 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
}
|
||||
GL_ERROR_CHECK(glEnableClientState(GL_COLOR_ARRAY));
|
||||
GL_ERROR_CHECK(glColorPointer(drawInfo.attributes.color.descriptor.components, colorType, drawInfo.attributes.color.stride, colorPtr));
|
||||
} else {
|
||||
GL_ERROR_CHECK(glColor4f( 1, 1, 1, 1 ));
|
||||
}
|
||||
|
||||
if ( drawInfo.textures.primary.image && drawInfo.attributes.uv.pointer ) {
|
||||
@ -471,7 +431,7 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
GL_ERROR_CHECK(glBindTexture(drawInfo.textures.primary.viewType, drawInfo.textures.primary.image));
|
||||
GL_ERROR_CHECK(glTexCoordPointer(2, uvType, drawInfo.attributes.uv.stride, uvPtr));
|
||||
|
||||
if ( drawInfo.attributes.color.pointer || drawInfo.color.enabled ) {
|
||||
if ( drawInfo.attributes.color.pointer ) {
|
||||
GL_ERROR_CHECK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
|
||||
} else {
|
||||
GL_ERROR_CHECK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE));
|
||||
@ -503,15 +463,7 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
if ( drawInfo.descriptor.inputs.index.count ) {
|
||||
GL_ERROR_CHECK(glDrawElements(mode, drawInfo.descriptor.inputs.index.count, indicesType, (static_cast<uint8_t*>(drawInfo.attributes.index.pointer) + drawInfo.attributes.index.stride * drawInfo.descriptor.inputs.index.first)));
|
||||
} else {
|
||||
#if 0 && UF_ENV_DREAMCAST
|
||||
// GLdc has a "regression" where glDrawArrays does not work
|
||||
// everything should be using indices anyways so this path shouldn't really ever be taken
|
||||
uf::stl::vector<uint16_t> indices(drawInfo.descriptor.inputs.vertex.count);
|
||||
for ( auto i = 0; i < drawInfo.descriptor.inputs.vertex.count; ++i ) indices[i] = i;
|
||||
GL_ERROR_CHECK(glDrawElements(mode, indices.size(), GL_UNSIGNED_SHORT, indices.data()));
|
||||
#else
|
||||
GL_ERROR_CHECK(glDrawArrays(mode, drawInfo.descriptor.inputs.vertex.first, drawInfo.descriptor.inputs.vertex.count));
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( drawInfo.textures.secondary.image ) {
|
||||
@ -528,7 +480,7 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer::
|
||||
}
|
||||
|
||||
if ( drawInfo.attributes.normal.pointer ) GL_ERROR_CHECK(glDisableClientState(GL_NORMAL_ARRAY));
|
||||
if ( drawInfo.attributes.color.pointer || drawInfo.color.enabled ) GL_ERROR_CHECK(glDisableClientState(GL_COLOR_ARRAY));
|
||||
if ( drawInfo.attributes.color.pointer ) GL_ERROR_CHECK(glDisableClientState(GL_COLOR_ARRAY));
|
||||
if ( drawInfo.attributes.uv.pointer ) GL_ERROR_CHECK(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
GL_ERROR_CHECK(glDisableClientState(GL_VERTEX_ARRAY));
|
||||
}
|
||||
|
||||
@ -107,73 +107,8 @@ void ext::opengl::Texture::loadFromImage(
|
||||
Device& device,
|
||||
enums::Format::type_t format
|
||||
) {
|
||||
switch ( format ) {
|
||||
case enums::Format::R8_SRGB:
|
||||
case enums::Format::R8G8_SRGB:
|
||||
case enums::Format::R8G8B8_SRGB:
|
||||
case enums::Format::R8G8B8A8_SRGB:
|
||||
srgb = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( image.getFormat() != 0 ) {
|
||||
internalFormat = image.getFormat();
|
||||
} else {
|
||||
switch ( image.getChannels() ) {
|
||||
// R
|
||||
case 1:
|
||||
switch ( image.getBpp() ) {
|
||||
case 8:
|
||||
format = srgb ? enums::Format::R8_SRGB : enums::Format::R8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of {}", image.getBpp() );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RB
|
||||
case 2:
|
||||
switch ( image.getBpp() ) {
|
||||
case 16:
|
||||
format = srgb ? enums::Format::R8G8_SRGB : enums::Format::R8G8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of {}", image.getBpp() );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RGB
|
||||
case 3:
|
||||
switch ( image.getBpp() ) {
|
||||
case 24:
|
||||
format = srgb ? enums::Format::R8G8B8_SRGB : enums::Format::R8G8B8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of {}", image.getBpp() );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RGBA
|
||||
case 4:
|
||||
switch ( image.getBpp() ) {
|
||||
case 16:
|
||||
format = enums::Format::R4G4B4A4_UNORM_PACK16;
|
||||
break;
|
||||
case 32:
|
||||
format = srgb ? enums::Format::R8G8B8A8_SRGB : enums::Format::R8G8B8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of {}", image.getBpp() );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported channels of {}", image.getChannels() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// convert to power of two
|
||||
//image.padToPowerOfTwo();
|
||||
format = image.getFormat( srgb );
|
||||
internalFormat = image.format > 0 ? format : 0;
|
||||
|
||||
this->fromBuffers(
|
||||
(void*) image.getPixelsPtr(),
|
||||
@ -334,6 +269,12 @@ void ext::opengl::Texture::update( void* data, size_t bufferSize, uint32_t layer
|
||||
format = GL_RGBA;
|
||||
internalFormat = GL_RGBA8;
|
||||
break;
|
||||
|
||||
// to-do: convert
|
||||
case enums::Format::R8G8B8A8_RGBE:
|
||||
format = GL_RGBA;
|
||||
internalFormat = GL_RGBA;
|
||||
break;
|
||||
}
|
||||
GL_MUTEX_LOCK();
|
||||
GL_ERROR_CHECK(glBindTexture(viewType, image));
|
||||
|
||||
@ -1096,7 +1096,12 @@ void ext::valve::loadBsp( pod::Graph& graph, const uf::stl::string& filename, co
|
||||
auto& mesh = storage.meshes[meshName];
|
||||
auto& primitives = storage.primitives[meshName];
|
||||
|
||||
// for ( auto& pair : meshlets ) uf::mesh::tangents( pair.second.vertices, pair.second.indices );
|
||||
// recompute bounds from min/max to center-extent
|
||||
for ( auto& [ _, meshlet ] : meshlets ) {
|
||||
auto& bounds = meshlet.primitive.instance.bounds;
|
||||
bounds.center = ( bounds.min + bounds.max ) * 0.5f;
|
||||
bounds.extent = ( bounds.min - bounds.max ) * 0.5f;
|
||||
}
|
||||
|
||||
// slice worldspawn
|
||||
if ( false && m == 0 ) {
|
||||
|
||||
@ -396,6 +396,13 @@ bool ext::valve::loadMdl( pod::Graph& graph, const uf::stl::string& filename ) {
|
||||
}
|
||||
|
||||
meshlet.primitive.instance.materialID = materialID;
|
||||
|
||||
// recompute bounds
|
||||
{
|
||||
auto& bounds = meshlet.primitive.instance.bounds;
|
||||
bounds.center = ( bounds.max + bounds.min ) * 0.5f;
|
||||
bounds.extent = ( bounds.max - bounds.min ) * 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,13 +405,24 @@ void ext::vulkan::Texture::loadFromImage(
|
||||
VkImageLayout layout,
|
||||
VkImageCreateFlags flags
|
||||
) {
|
||||
// for some reason this causes everything to get washed out
|
||||
#if 0
|
||||
format = (VkFormat) image.getFormat( srgb );
|
||||
|
||||
// convert non-vulkan formats
|
||||
switch ( format ) {
|
||||
case enums::Format::R8G8B8A8_RGBE:
|
||||
format = srgb ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch ( image.getChannels() ) {
|
||||
// R
|
||||
case 1:
|
||||
switch ( image.getBpp() ) {
|
||||
case 8: format = srgb ? VK_FORMAT_R8_SRGB : VK_FORMAT_R8_UNORM; break;
|
||||
case 16: format = VK_FORMAT_R16_SFLOAT; break; // Half-float
|
||||
case 32: format = VK_FORMAT_R32_SFLOAT; break; // Full-float
|
||||
case 16: format = VK_FORMAT_R16_SFLOAT; break;
|
||||
case 32: format = VK_FORMAT_R32_SFLOAT; break;
|
||||
default: UF_EXCEPTION("Vulkan error: unsupported BPP of {}", image.getBpp() ); break;
|
||||
}
|
||||
break;
|
||||
@ -446,6 +457,7 @@ void ext::vulkan::Texture::loadFromImage(
|
||||
UF_EXCEPTION("Vulkan error: unsupported channels of {}", image.getChannels() );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
this->fromBuffers(
|
||||
(void*) image.getPixelsPtr(),
|
||||
|
||||
@ -570,8 +570,68 @@ size_t& uf::Image::getChannels() {
|
||||
size_t uf::Image::getChannels() const {
|
||||
return this->channels;
|
||||
}
|
||||
size_t uf::Image::getFormat() const {
|
||||
return this->format;
|
||||
size_t uf::Image::getFormat( bool srgb ) const {
|
||||
auto format = this->format;
|
||||
|
||||
// for some reason i'm auto-deducing it here
|
||||
#if UF_USE_OPENGL
|
||||
switch ( format ) {
|
||||
case uf::renderer::enums::Format::R8_SRGB:
|
||||
case uf::renderer::enums::Format::R8G8_SRGB:
|
||||
case uf::renderer::enums::Format::R8G8B8_SRGB:
|
||||
case uf::renderer::enums::Format::R8G8B8A8_SRGB:
|
||||
srgb = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( this->format > 0 ) format = this->format;
|
||||
else switch ( this->channels ) {
|
||||
// R
|
||||
case 1:
|
||||
switch ( this->bpp ) {
|
||||
case 8: format = srgb ? uf::renderer::enums::Format::R8_SRGB : uf::renderer::enums::Format::R8_UNORM; break;
|
||||
case 16: format = uf::renderer::enums::Format::R16_SFLOAT; break;
|
||||
case 32: format = uf::renderer::enums::Format::R32_SFLOAT; break;
|
||||
default: UF_EXCEPTION("unsupported BPP of {}", this->bpp ); break;
|
||||
}
|
||||
break;
|
||||
// RG
|
||||
case 2:
|
||||
switch ( this->bpp ) {
|
||||
case 16: format = srgb ? uf::renderer::enums::Format::R8G8_SRGB : uf::renderer::enums::Format::R8G8_UNORM; break;
|
||||
case 32: format = uf::renderer::enums::Format::R16G16_SFLOAT; break;
|
||||
case 64: format = uf::renderer::enums::Format::R32G32_SFLOAT; break;
|
||||
default: UF_EXCEPTION("unsupported BPP of {}", this->bpp ); break;
|
||||
}
|
||||
break;
|
||||
// RGB
|
||||
case 3:
|
||||
switch ( this->bpp ) {
|
||||
case 24: format = srgb ? uf::renderer::enums::Format::R8G8B8_SRGB : uf::renderer::enums::Format::R8G8B8_UNORM; break;
|
||||
case 48: format = uf::renderer::enums::Format::R16G16B16_SFLOAT; break;
|
||||
case 96: format = uf::renderer::enums::Format::R32G32B32_SFLOAT; break;
|
||||
default: UF_EXCEPTION("unsupported BPP of {}", this->bpp ); break;
|
||||
}
|
||||
break;
|
||||
// RGBA
|
||||
case 4:
|
||||
switch ( this->bpp ) {
|
||||
case 32: format = srgb ? uf::renderer::enums::Format::R8G8B8A8_SRGB : uf::renderer::enums::Format::R8G8B8A8_UNORM; break;
|
||||
case 64: format = uf::renderer::enums::Format::R16G16B16A16_SFLOAT; break; // 16-bit HDR
|
||||
case 128: format = uf::renderer::enums::Format::R32G32B32A32_SFLOAT; break; // 32-bit HDR
|
||||
default: UF_EXCEPTION("unsupported BPP of {}", this->bpp ); break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("unsupported channels of {}", this->channels );
|
||||
break;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
void uf::Image::setFormat( size_t format ) {
|
||||
this->format = format;
|
||||
}
|
||||
uf::stl::string uf::Image::getHash() const {
|
||||
return uf::image::hash( *this );
|
||||
|
||||
Loading…
Reference in New Issue
Block a user