BinomialLLC / basis_universal

Basis Universal GPU Texture Codec
Apache License 2.0
2.67k stars 260 forks source link

Balck Textures on android #368

Closed benanil closed 8 months ago

benanil commented 8 months ago

this code works fine on my windows pc but when I run on my android phone, textures are black I don't got any basis or opengl errors, and for a while I can't figure out why this is happenning, can you help? note: I've checked my device supports GL_COMPRESSED_RGBA8_ETC2_EAC

void TranscodeBasisTextures(const char* basisPath, AImage* images, Texture* textures, int numImages)
{
    using namespace basist;
    basisu_transcoder_init();

    basisu_transcoder transcoder;
    char* basisFile = ReadAllFile(basisPath);
    uint64_t fileSize = FileSize(basisPath);
    unsigned char* outputTexture = new unsigned char[1024 * 1024 * 3];
    transcoder.start_transcoding(basisFile, fileSize);

    for (int i = 0; i < numImages; i++)
    {
        basisu_image_level_info info;
        transcoder.get_image_level_info(basisFile, fileSize, info, i, 0);
        // windows: (transcoder_texture_format)(2 + info.m_alpha_flag);
        transcoder_texture_format transcoderFormat = transcoder_texture_format::cTFETC2_RGBA;

        uint32_t size = (info.m_width * info.m_height);
        bool result = transcoder.transcode_image_level(basisFile, fileSize, i, 0, outputTexture, size, transcoderFormat);
        if (!result) {
            AX_ERROR("transcoding failed");
            continue;
        }

        textures[i] = CreateTexture(info.m_width, info.m_height, outputTexture, info.m_alpha_flag, true, true);
    }
    transcoder.stop_transcoding();
    delete[] outputTexture;
}
// type is either 0 or 1 if compressed. 1 means has alpha
// and when compressed, type is the size
Texture CreateTexture(int width, int height, void* data, TextureType type, bool mipmap, bool compressed)
{
    Texture texture;
    glGenTextures(1, &texture.handle);
    glBindTexture(GL_TEXTURE_2D, texture.handle);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmap ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
    texture.width  = width;
    texture.height = height;
    texture.buffer = (unsigned char*)data;

    IsETCSupported();
    if (!compressed)
    {
        TextureFormat format = TextureFormatTable[type];
        glTexImage2D(GL_TEXTURE_2D, 0, format.first, width, height, 0, format.format, format.type, data);
    }
    else
    {
#ifndef __ANDROID__
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, type == 1 ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
                                                 width, height, 0, width * height, data);
#else
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA8_ETC2_EAC, width, height, 0, ((width/4) * (height/4)) * 16, data);
#endif
    }

    if (mipmap)
        ;// glGenerateMipmap(GL_TEXTURE_2D);
    GLenum error = glGetError();
    if (error)
    {
        __android_log_print(ANDROID_LOG_FATAL, "AX-GL_ERROR", "%s -line:%i message: %s", __FILE__, __LINE__, GetGLErrorString(error));
        ASSERT(0);
    }
    return texture;
}
benanil commented 8 months ago

when I transcode to raw image format cTFRGBA32 it works fine in Android, but I want to use compressed textures on android note: the file that I transcoding is sponza textures all encoded in one basis file

I appriciaded your awesome work and its awesome technology best regards

benanil commented 8 months ago

this doesn't work too

uint32_t bytesPerPixel = basis_get_bytes_per_block_or_pixel(transcoder_texture_format::cTFETC2_RGBA);
uint32_t size = (info.m_num_blocks_x * info.m_num_blocks_y) * bytesPerPixel;

bool result = transcoder.transcode_image_level(basisFile, fileSize, i, 0, outputTexture, size,
                                               transcoder_texture_format::cTFETC2_RGBA);

glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA8_ETC2_EAC, width, height, 0, size, outputTexture);
benanil commented 8 months ago

ktx format works fine too

richgel999 commented 8 months ago

when I transcode to raw image format cTFRGBA32 it works fine in Android

Hi - This is a good sign. It means the transcoder is able to decompress the compressed texture data and then give you RGBA data successfully. When you transcode to cTFETC2_RGBA, can you examine the returned memory and see if it's all 0's? Or write it to disk and verify it on your desktop?

benanil commented 8 months ago

here how it looks on my phoneScreenshot_2023-12-20-12-59-58-74.jpg

this is because I used ambient light and ndl

without lighting:Screenshot_2023-12-20-13-04-03-25.jpg

benanil commented 8 months ago

"can you examine the returned memory and see if it's all 0's?" mostly zero image image

benanil commented 8 months ago

oh no, its not... the second image that I inspect has more bits set note: this is metallic roughness texture, all red. is it looking correct? image

benanil commented 8 months ago

here is example of normal map: image it's not full of zero

benanil commented 8 months ago

image and its binary image

benanil commented 8 months ago

I couldn't find any resource about transcoding etc2 and using it using vulkan or opengl is there any project that use basis that I can take a look as reference?

benanil commented 8 months ago

this was probably because, I was using size_t on both 32bit and 64bit architectures, and when I read from disk problem was occuring, but I gived up working on this one week ago and currently using etcpak and zstd.