Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS app crashes on creating Texture #814

Closed
Raki opened this issue Feb 14, 2019 · 15 comments
Closed

iOS app crashes on creating Texture #814

Raki opened this issue Feb 14, 2019 · 15 comments
Assignees
Labels
ios Issue/request for iOS only opengl Issue/request specific to OpenGL

Comments

@Raki
Copy link

Raki commented Feb 14, 2019

I'm trying to render a texture quad by following the "hello-triangle" example on iOS. My new material to render the quad is proper as it is drawing a black quad if I didn't bind any texture to material instance. But when I call this function to create texture, it is crashing at generateMipmaps(*engine)

void loadTexture(Engine* engine, const std::string& filePath, Texture** map, bool sRGB)
{
int w, h, n;
unsigned char* data = stbi_load(path.c_str(), &w, &h, &n, 3);
if (data != nullptr) {
*map = Texture::Builder()
.width(uint32_t(w))
.height(uint32_t(h))
.levels(0xff)
.format(sRGB?driver::TextureFormat::SRGB8:driver::TextureFormat::RGB8)
.build(*engine);
Texture::PixelBufferDescriptor buffer(data, size_t(w * h * 3),
Texture::Format::RGB, Texture::Type::UBYTE,
(driver::BufferDescriptor::Callback) &stbi_image_free);
(*map)->setImage(*engine, 0, std::move(buffer));
(*map)->generateMipmaps(*engine);
}

I pulled this function from Desktop samples of filament.
I tried tweaking png compression options on xCode but no luck.

  • Device: iPhone 7
  • OS: iOS 11.4.1
@bejado bejado self-assigned this Feb 14, 2019
@bejado
Copy link
Member

bejado commented Feb 14, 2019

Which backend are you using, OpenGL? I think there were some changes recently to mipmap generation, but it's possible this is specific to iOS. Is there any particular message logged before crashing?

@Raki
Copy link
Author

Raki commented Feb 14, 2019

if format is RGB8 then log is

019-02-14 10:35:51.922809+0530 FilamentDemo[291:12092] [DYMTLInitPlatform] platform initialization successful
FEngine (64 bits) created at 0x104800000 (threading is enabled)
FEngine resolved backend: OpenGL
2019-02-14 10:35:52.216054+0530 FilamentDemo[291:12101] Metal GPU Frame Capture Enabled
2019-02-14 10:35:52.217089+0530 FilamentDemo[291:12101] Metal API Validation Enabled
N5utils18PostconditionPanicE
in virtual void filament::PlatformCocoaTouchGL::makeCurrent(filament::driver::Platform::SwapChain *, filament::driver::Platform::SwapChain *):129
reason: Incomplete framebuffer.
#0 0 libsystem_pthread.dylib 0x0000000184cd1110 + 0
libc++abi.dylib: terminating with uncaught exception of type utils::PostconditionPanic

if format is SRGB8 then log is

2019-02-14 10:38:53.261018+0530 FilamentDemo[297:13117] [DYMTLInitPlatform] platform initialization successful
FEngine (64 bits) created at 0x109800000 (threading is enabled)
FEngine resolved backend: OpenGL
2019-02-14 10:38:53.542747+0530 FilamentDemo[297:13125] Metal GPU Frame Capture Enabled
2019-02-14 10:38:53.543834+0530 FilamentDemo[297:13125] Metal API Validation Enabled
N5utils18PostconditionPanicE
in void filament::details::FTexture::generateMipmaps(filament::details::FEngine &) const:199
reason: Texture format must be color renderable
0 FilamentDemo 0x0000000104e8b08c -[FilamentView initializeFilamentQuad] + 1388
1 0 FilamentDemo 0x0000000104e8a5f8 -[FilamentView initWithCoder:] + 180
2 0 UIKit 0x000000018f32cfec + 248
3 0 UIKit 0x000000018f48e738 + 688
4 0 UIKit 0x000000018f48e470 + 312
5 0 UIKit 0x000000018f32cc94 + 188
6 0 UIKit 0x000000018f48e738 + 688
7 0 UIKit 0x000000018f48e8b0 + 1064
8 0 UIKit 0x000000018f48e470 + 312
9 0 UIKit 0x000000018f32bfe4 + 1164
10 0 UIKit 0x000000018f15daa8 + 372
11 0 UIKit 0x000000018eda1074 + 176
12 0 UIKit 0x000000018ecc5b14 + 172
13 0 UIKit 0x000000018ecc5a50 + 28
14 0 UIKit 0x000000018ecb6ce4 + 136
15 0 UIKit 0x000000018ecb5b18 + 272
16 0 UIKit 0x000000018ed4362c + 48
17 0 UIKit 0x000000018ecb9274 + 3660
libc++abi.dylib: terminating with uncaught exception of type utils::PostconditionPanic

@bejado
Copy link
Member

bejado commented Feb 14, 2019

I don't think iOS supports RGB colorbuffers, hence the "Texture format must be color renderable." assertion. Can you try with a RGBA texture and see if that succeeds?

@Raki
Copy link
Author

Raki commented Feb 14, 2019

tried with format driver::TextureFormat::RGBA8 got the following error

2019-02-14 10:47:16.609869+0530 FilamentDemo[302:15292] [DYMTLInitPlatform] platform initialization successful
FEngine (64 bits) created at 0x107800000 (threading is enabled)
FEngine resolved backend: OpenGL
2019-02-14 10:47:16.876139+0530 FilamentDemo[302:15301] Metal GPU Frame Capture Enabled
2019-02-14 10:47:16.877123+0530 FilamentDemo[302:15301] Metal API Validation Enabled
N5utils18PostconditionPanicE
in virtual void filament::PlatformCocoaTouchGL::makeCurrent(filament::driver::Platform::SwapChain *, filament::driver::Platform::SwapChain *):129
reason: Incomplete framebuffer.
#0 0 libsystem_pthread.dylib 0x0000000184cd1110 + 0
libc++abi.dylib: terminating with uncaught exception of type utils::PostconditionPanic

with format driver::TextureFormat::SRGBA8 got the following error

2019-02-14 10:49:25.732349+0530 FilamentDemo[308:16078] [DYMTLInitPlatform] platform initialization successful
FEngine (64 bits) created at 0x1037d8000 (threading is enabled)
FEngine resolved backend: OpenGL
2019-02-14 10:49:26.002348+0530 FilamentDemo[308:16086] Metal GPU Frame Capture Enabled
2019-02-14 10:49:26.003308+0530 FilamentDemo[308:16086] Metal API Validation Enabled
N5utils18PostconditionPanicE
in void filament::details::FTexture::generateMipmaps(filament::details::FEngine &) const:199
reason: Texture format must be color renderable

@bejado
Copy link
Member

bejado commented Feb 14, 2019

Okay, potentially something else going on- will take a closer look.

@romainguy romainguy added ios Issue/request for iOS only opengl Issue/request specific to OpenGL labels Feb 14, 2019
@romainguy
Copy link
Collaborator

This error triggers when isRenderTargetFormatSupported() returns false in the driver. Maybe it's just that it wasn't implemented properly for iOS?

@bejado
Copy link
Member

bejado commented Feb 14, 2019

@Raki just merged a fix- can pull and try again? Note that sRGB textures (correctly) do not support mipmap generation on iOS.

@Raki
Copy link
Author

Raki commented Feb 15, 2019

Hi @bejado , I tried with latest code, no crashes so far.
But the texture quad I am drawing with unlit material is coming like this.
img_0236

While debugging i can see like, the texture is being updated with current frame.
I'm using format as driver::TextureFormat::RGBA8

@bejado
Copy link
Member

bejado commented Feb 15, 2019

Does that only happen when you generate mipmaps? Can you show your material file?

@Raki
Copy link
Author

Raki commented Feb 18, 2019

@bejado , I tried disabling mipmaps but no change in output.
I'm using the following material .

material
{
name : simple_tex,
shadingModel : unlit,
parameters : [
// Base color sRGB texture
{
type : sampler2d,
name : albedo
}
],
// To sample textures our material must declare that it requires
// a set of UV coordinates from the rendered mesh
requires: [
uv0
]
}

fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_albedo, getUV0());
}
}

@bejado
Copy link
Member

bejado commented Feb 19, 2019

I don't see anything wrong with the material. Are you creating a sampler and setting it as a parameter on your material instance?

TextureSampler sampler(TextureSampler::MinFilter::LINEAR, TextureSampler::MagFilter::LINEAR);
materialInstance = material->createInstance();
materialInstance->setParameter("albedo", texture, sampler);

It would help if you could post all the changes you've made to HelloTriangle.

@Raki
Copy link
Author

Raki commented Feb 20, 2019

@bejado The following are the changes I made to HelloTriangle Demo.

struct Vertex3
{
    math::float2 pos;
    math::float2 uv;
};

static const Vertex3 QUAD_VERTICES[4] = {
    {{-0.5,-0.5}, {0,0}},
    {{0.5,-0.5}, {1,0}},
{{0.5,0.5}, {1,1}},
{{-0.5,0.5}, {0,1}}
};

static constexpr uint16_t QUAD_INDICES[6] = {0,1,2,0,2,3};
-(void) initializeFilamentQuad
{
    engine = Engine::create(filament::Engine::Backend::OPENGL);
    swapChain = engine->createSwapChain((__bridge void*) self.layer);
    renderer = engine->createRenderer();
    scene = engine->createScene();
    camera = engine->createCamera();
    
    filaView = engine->createView();
    filaView->setClearColor({0.1, 0.125, 0.25, 1.0});
    filaView->setPostProcessingEnabled(false);
    filaView->setDepthPrepass(filament::View::DepthPrepass::DISABLED);
    
    int stride = sizeof(float)*4;
    
    app.vb = VertexBuffer::Builder()
    .vertexCount(4)
    .bufferCount(1)
    .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT2, 0, stride)
    .attribute(VertexAttribute::UV0, 0, VertexBuffer::AttributeType::FLOAT2, 8, stride)
    .build(*engine);
    app.vb->setBufferAt(*engine, 0,
                        VertexBuffer::BufferDescriptor(QUAD_VERTICES, stride*4, nullptr));
    
    app.ib = IndexBuffer::Builder()
    .indexCount(6)
    .bufferType(IndexBuffer::IndexType::USHORT)
    .build(*engine);
    app.ib->setBuffer(*engine,
                      IndexBuffer::BufferDescriptor(QUAD_INDICES, sizeof(uint16_t)*6, nullptr));
    
    app.mat = Material::Builder()
    .package((void*) SIMPLE_TEXR_PACKAGE, sizeof(SIMPLE_TEXR_PACKAGE))
    .build(*engine);
    
    materialInstance = app.mat->getDefaultInstance();
    
    NSString *bcPath = [[NSBundle mainBundle] pathForResource:@"Model_1_txt" ofType:@"png"];
    const char *bcPath_cstr = [bcPath fileSystemRepresentation];

    TextureLoader::loadTexture(engine,string(bcPath_cstr),&albedo);
    TextureSampler *sampler = new TextureSampler(TextureSampler::MinFilter::LINEAR,TextureSampler::MagFilter::LINEAR);
    materialInstance->setParameter("albedo", albedo, *sampler);
    
    
    
    app.renderable = EntityManager::get().create();
    RenderableManager::Builder(1)
    .boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }})
    .material(0, materialInstance)
    .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, app.vb, app.ib, 0, 6)
    .culling(false)
    .receiveShadows(false)
    .castShadows(false)
    .build(*engine, app.renderable);
    scene->addEntity(app.renderable);
    
     
    filaView->setScene(scene);
    filaView->setCamera(camera);
    CGRect nativeBounds = [UIScreen mainScreen].nativeBounds;
    filaView->setViewport(Viewport(0, 0, nativeBounds.size.width, nativeBounds.size.height));
    
    
    constexpr float ZOOM = 1.5f;
    const uint32_t w = filaView->getViewport().width;
    const uint32_t h = filaView->getViewport().height;
    const float aspect = (float) w / h;
    camera->setProjection(Camera::Projection::ORTHO,
                          -aspect * ZOOM, aspect * ZOOM,
                          -ZOOM, ZOOM, 0, 1);
}
//loadTexture code 
        int w, h, n;
        unsigned char* data = stbi_load(path.c_str(), &w, &h, &n, 4);
        if (data != nullptr) {
            *map = Texture::Builder()
            .width(uint32_t(w))
            .height(uint32_t(h))
            .levels(0xff)
            .format(driver::TextureFormat::RGBA8)
            .build(*engine);
            Texture::PixelBufferDescriptor buffer(data, size_t(w * h * 4),
                                                  Texture::Format::RGBA, Texture::Type::UBYTE,
                                                  (driver::BufferDescriptor::Callback) &stbi_image_free);
            (*map)->setImage(*engine, 0, std::move(buffer));
            (*map)->generateMipmaps(*engine);

@bejado
Copy link
Member

bejado commented Feb 20, 2019

Can you try replacing

    materialInstance = app.mat->getDefaultInstance();

with

    materialInstance = app.mat->createInstance();

This might be a bug on our side.

@Raki
Copy link
Author

Raki commented Feb 21, 2019

@bejado Yes, it worked with app.mat->createInstance(); . Thank you very much.

@bejado
Copy link
Member

bejado commented Feb 21, 2019

Sure thing! Note that you should be able to use getDefaultInstance so that is in fact a bug on our part which will be fixed in #854.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ios Issue/request for iOS only opengl Issue/request specific to OpenGL
Projects
None yet
Development

No branches or pull requests

3 participants