support 3D texture/2D texture arrays
This commit is contained in:
@@ -226,21 +226,29 @@ namespace thermion
|
||||
EMSCRIPTEN_KEEPALIVE TTexture *Engine_buildTexture(TEngine *tEngine,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
uint8_t levels,
|
||||
TTextureSamplerType tSamplerType,
|
||||
TTextureFormat tFormat)
|
||||
{
|
||||
TRACE("Creating texture %dx%d (depth %d), sampler type %d, format %d", width, height, depth, static_cast<int>(tSamplerType), static_cast<int>(tFormat));
|
||||
auto *engine = reinterpret_cast<Engine *>(tEngine);
|
||||
auto format = convertToFilamentFormat(tFormat);
|
||||
auto samplerType = static_cast<::filament::Texture::Sampler>(static_cast<int>(tSamplerType));
|
||||
auto *texture = Texture::Builder()
|
||||
.width(width)
|
||||
.height(height)
|
||||
.depth(depth)
|
||||
.levels(levels)
|
||||
.sampler(samplerType)
|
||||
.format(format)
|
||||
.build(*engine);
|
||||
Log("Created texture %d x %d, format %d", texture->getWidth(), texture->getHeight(), texture->getFormat());
|
||||
if(texture) {
|
||||
TRACE("Texture successfully created");
|
||||
} else {
|
||||
Log("Error: failed to created texture");
|
||||
}
|
||||
|
||||
return reinterpret_cast<TTexture *>(texture);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <vector>
|
||||
|
||||
#include <filament/MaterialInstance.h>
|
||||
#include <filament/Material.h>
|
||||
#include <math/mat4.h>
|
||||
@@ -41,11 +43,11 @@ namespace thermion
|
||||
reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setDepthCulling(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *tMaterialInstance, const char *propertyName, double x, double y, double z, double w)
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance *tMaterialInstance, const char *propertyName, double value)
|
||||
{
|
||||
auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance);
|
||||
filament::math::float4 data{static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(w)};
|
||||
materialInstance->setParameter(propertyName, data);
|
||||
auto fValue = static_cast<float>(value);
|
||||
materialInstance->setParameter(propertyName, fValue);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y)
|
||||
@@ -54,16 +56,36 @@ namespace thermion
|
||||
reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance *tMaterialInstance, const char *propertyName, double value)
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat3(TMaterialInstance *materialInstance, const char *propertyName, double x, double y, double z)
|
||||
{
|
||||
auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance);
|
||||
auto fValue = static_cast<float>(value);
|
||||
materialInstance->setParameter(propertyName, fValue);
|
||||
filament::math::float3 data{static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) };
|
||||
reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance *materialInstance, const char *propertyName, int value)
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat3Array(TMaterialInstance *tMaterialInstance, const char *propertyName, double* raw, uint32_t length) {
|
||||
TRACE("Setting property %s to array from raw length %d", propertyName, length);
|
||||
|
||||
std::vector<filament::math::float3> data;
|
||||
|
||||
for(int i = 0; i < length; i+=3) {
|
||||
// TRACE("Vector %f %f %f", static_cast<float>(raw[i]), static_cast<float>(raw[i+1]), static_cast<float>(raw[i+2]));
|
||||
data.push_back(filament::math::float3 { static_cast<float>(raw[i]), static_cast<float>(raw[i+1]), static_cast<float>(raw[i+2]) });
|
||||
}
|
||||
auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance);
|
||||
materialInstance->setParameter(propertyName, data.data(), data.size());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *tMaterialInstance, const char *propertyName, double x, double y, double z, double w)
|
||||
{
|
||||
reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, value);
|
||||
auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance);
|
||||
filament::math::float4 data{static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(w)};
|
||||
materialInstance->setParameter(propertyName, data);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance *tMaterialInstance, const char *propertyName, int value)
|
||||
{
|
||||
auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance);
|
||||
materialInstance->setParameter(propertyName, value);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterBool(TMaterialInstance *materialInstance, const char *propertyName, bool value)
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace thermion
|
||||
return false;
|
||||
}
|
||||
|
||||
Log("Dimensions %d x %d, channels %d, size %d, buffer format %d and pixel data type %d", w, h, channels, size, bufferFormat, pixelDataType);
|
||||
TRACE("Loading image from dimensions %d x %d, channels %d, size %d, buffer format %d and pixel data type %d", w, h, channels, size, bufferFormat, pixelDataType);
|
||||
|
||||
filament::Texture::PixelBufferDescriptor buffer(
|
||||
image->getPixelRef(),
|
||||
@@ -115,51 +115,151 @@ namespace thermion
|
||||
uint32_t height,
|
||||
uint32_t channels,
|
||||
uint32_t tBufferFormat,
|
||||
uint32_t tPixelDataType
|
||||
) {
|
||||
uint32_t tPixelDataType)
|
||||
{
|
||||
auto engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||
|
||||
|
||||
auto texture = reinterpret_cast<filament::Texture *>(tTexture);
|
||||
auto bufferFormat = static_cast<PixelBufferDescriptor::PixelDataFormat>(tBufferFormat);
|
||||
auto pixelDataType = static_cast<PixelBufferDescriptor::PixelDataType>(tPixelDataType);
|
||||
|
||||
switch (bufferFormat)
|
||||
{
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGB:
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGBA:
|
||||
if(size != width * height * channels * sizeof(float)) {
|
||||
Log("Size mismatch");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER:
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER:
|
||||
if(size != width * height * channels * sizeof(uint8_t)) {
|
||||
Log("Size mismatch");
|
||||
// return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log("Unsupported buffer format type : %d", bufferFormat);
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGB:
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGBA:
|
||||
if (size != width * height * channels * sizeof(float))
|
||||
{
|
||||
Log("Size mismatch");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER:
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER:
|
||||
if (size != width * height * channels * sizeof(uint8_t))
|
||||
{
|
||||
Log("Size mismatch");
|
||||
// return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log("Unsupported buffer format type : %d", bufferFormat);
|
||||
return false;
|
||||
}
|
||||
|
||||
filament::Texture::PixelBufferDescriptor buffer(
|
||||
data,
|
||||
// the texture upload is async, so we need to copy the buffer
|
||||
auto *buffer = new std::vector<uint8_t>(size);
|
||||
std::copy(data, data + size, buffer->begin());
|
||||
|
||||
filament::Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t,
|
||||
void *data)
|
||||
{
|
||||
delete reinterpret_cast<std::vector<uint8_t> *>(data);
|
||||
};
|
||||
|
||||
filament::Texture::PixelBufferDescriptor pbd(
|
||||
buffer->data(),
|
||||
size,
|
||||
bufferFormat,
|
||||
pixelDataType);
|
||||
|
||||
texture->setImage(*engine, level, std::move(buffer));
|
||||
pixelDataType,
|
||||
1, // alignment
|
||||
0, // left
|
||||
0, // top
|
||||
0, // stride
|
||||
freeCallback,
|
||||
buffer);
|
||||
|
||||
texture->setImage(*engine, level, std::move(pbd));
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool Texture_setImageWithDepth(
|
||||
TEngine *tEngine,
|
||||
TTexture *tTexture,
|
||||
uint32_t level,
|
||||
uint8_t *data,
|
||||
size_t size,
|
||||
uint32_t x_offset,
|
||||
uint32_t y_offset,
|
||||
uint32_t z_offset,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t channels,
|
||||
uint32_t depth,
|
||||
uint32_t tBufferFormat,
|
||||
uint32_t tPixelDataType)
|
||||
{
|
||||
auto engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TLinearImage *Image_createEmpty(uint32_t width,uint32_t height,uint32_t channel) {
|
||||
auto *image = new ::image::LinearImage(width, height, channel);
|
||||
return reinterpret_cast<TLinearImage*>(image);
|
||||
auto texture = reinterpret_cast<filament::Texture *>(tTexture);
|
||||
auto bufferFormat = static_cast<PixelBufferDescriptor::PixelDataFormat>(tBufferFormat);
|
||||
auto pixelDataType = static_cast<PixelBufferDescriptor::PixelDataType>(tPixelDataType);
|
||||
TRACE("Setting texture image (depth %d, %dx%dx%d (%d bytes, z_offset %d)", depth, width, height, channels, size, z_offset);
|
||||
|
||||
switch (bufferFormat)
|
||||
{
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGB:
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGBA:
|
||||
if (size != width * height * channels * sizeof(float))
|
||||
{
|
||||
Log("Size mismatch");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER:
|
||||
case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER:
|
||||
if (size != width * height * channels * sizeof(uint8_t))
|
||||
{
|
||||
Log("Size mismatch");
|
||||
// return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log("Unsupported buffer format type : %d", bufferFormat);
|
||||
return false;
|
||||
}
|
||||
|
||||
// the texture upload is async, so we need to copy the buffer
|
||||
auto *buffer = new std::vector<uint8_t>(size);
|
||||
std::copy(data, data + size, buffer->begin());
|
||||
|
||||
filament::Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t,
|
||||
void *data)
|
||||
{
|
||||
|
||||
delete reinterpret_cast<std::vector<uint8_t> *>(data);
|
||||
};
|
||||
|
||||
filament::Texture::PixelBufferDescriptor pbd(
|
||||
buffer->data(),
|
||||
size,
|
||||
bufferFormat,
|
||||
pixelDataType,
|
||||
1, // alignment
|
||||
0, // left
|
||||
0, // top
|
||||
0, // stride
|
||||
freeCallback,
|
||||
buffer);
|
||||
|
||||
texture->setImage(
|
||||
*engine,
|
||||
level,
|
||||
x_offset,
|
||||
y_offset,
|
||||
z_offset,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
std::move(pbd));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TLinearImage *Image_createEmpty(uint32_t width, uint32_t height, uint32_t channel)
|
||||
{
|
||||
auto *image = new ::image::LinearImage(width, height, channel);
|
||||
return reinterpret_cast<TLinearImage *>(image);
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TTextureSampler *TextureSampler_create()
|
||||
{
|
||||
@@ -288,11 +388,12 @@ namespace thermion
|
||||
delete textureSampler;
|
||||
}
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TTexture *RenderTarget_getColorTexture(TRenderTarget *tRenderTarget) {
|
||||
auto renderTarget = reinterpret_cast<filament::RenderTarget*>(tRenderTarget);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TTexture *RenderTarget_getColorTexture(TRenderTarget *tRenderTarget)
|
||||
{
|
||||
auto renderTarget = reinterpret_cast<filament::RenderTarget *>(tRenderTarget);
|
||||
auto texture = renderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR0);
|
||||
return reinterpret_cast<TTexture*>(texture);
|
||||
return reinterpret_cast<TTexture *>(texture);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -332,6 +332,7 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_buildTextureRenderThread(TEngine *engine,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
uint8_t levels,
|
||||
TTextureSamplerType sampler,
|
||||
TTextureFormat format,
|
||||
@@ -340,7 +341,7 @@ extern "C"
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]() mutable
|
||||
{
|
||||
auto texture = Engine_buildTexture(engine, width, height, levels, sampler, format);
|
||||
auto texture = Engine_buildTexture(engine, width, height, depth, levels, sampler, format);
|
||||
onComplete(texture);
|
||||
});
|
||||
auto fut = _rl->add_task(lambda);
|
||||
@@ -909,6 +910,47 @@ extern "C"
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Texture_setImageWithDepthRenderThread(
|
||||
TEngine *tEngine,
|
||||
TTexture *tTexture,
|
||||
uint32_t level,
|
||||
uint8_t *data,
|
||||
size_t size,
|
||||
uint32_t x_offset,
|
||||
uint32_t y_offset,
|
||||
uint32_t z_offset,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t channels,
|
||||
uint32_t depth,
|
||||
uint32_t bufferFormat,
|
||||
uint32_t pixelDataType,
|
||||
void (*onComplete)(bool)
|
||||
) {
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]() mutable
|
||||
{
|
||||
bool result = Texture_setImageWithDepth(
|
||||
tEngine,
|
||||
tTexture,
|
||||
level,
|
||||
data,
|
||||
size,
|
||||
x_offset,
|
||||
y_offset,
|
||||
z_offset,
|
||||
width,
|
||||
height,
|
||||
channels,
|
||||
depth,
|
||||
bufferFormat,
|
||||
pixelDataType
|
||||
);
|
||||
onComplete(result);
|
||||
});
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *))
|
||||
{
|
||||
std::packaged_task<void()> lambda(
|
||||
|
||||
Reference in New Issue
Block a user