KhronosGroup / KTX-Software

KTX (Khronos Texture) Library and Tools
Other
861 stars 225 forks source link

KTX 2.0 texture format unable to GLupload | DEBUG_OUTPUT printing error on ktx 1.0 | typo in the documentation #819

Closed Raffaello closed 8 months ago

Raffaello commented 8 months ago

IT is a composite issue, all related, so i am just creating 1 starting from left most important and separated by a | char.

as a referenced with the example here: https://github.khronos.org/KTX-Software/libktx/index.html#createGL

Using OpenGL 4.3


the GLUpload with a KTX 2.0 image is returning error code 10: INVALID_OPERATION

Not sure what is missing to have a successful GLUpload.

The only thing i noticed is that the KTX2.0 texture need transcoding


instead when using a KTX 1.0 is successful but the DEBUG_OUTPUT call back function intercept an error:

GL error GL_INVALID_ENUM in (null): (ID: 173538523) Generic error

I suppose ktxTexture_GLUpload internally is doing a self-healing operation, trying something unsuccessful and then do something else. Is it supposed to be in this way? As those errors are generating noise. Would it be possible to avoid having a kind of false positive error from DEBUG_OUTPUT?


Finally the doc i think has a typo:

#include <ktx.h>

ktxTexture* kTexture;
KTX_error_code result;
ktx_size_t offset;
ktx_uint8_t* image;
ktx_uint32_t level, layer, faceSlice;
GLuint texture = 0;
GLenum target, glerror;

result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
                                        KTX_TEXTURE_CREATE_NO_FLAGS,
                                        &kTexture);
glGenTextures(1, &texture); // Optional. GLUpload can generate a texture.
result = ktxTexture_GLUpload(kTexture, &texture, &target, &glerror);
ktxTexture_Destroy(texture); /// <------- here it should be kTexure
// ...
// GL rendering using the texture
// ...

the line is ktxTexture_Destroy(texture); and I think it should be ktxTexture_Destroy(kTexture); Besides, to clean up properly shouldn't be called as well glDeleteTextures(1, &texture); ?

MarkCallow commented 8 months ago

There is not enough information for me to take action on the first item. I need your actual example. The one in the doc only shows the key pieces. If the texture needs transcoding you must do it before calling ktxTexture_GLUpload. If you do not, KTX_INVALID_OPERATION will be returned.

The error cannot be avoided. In OpenGL there is no query to determine if the implementation accepts the given format. Rather than some error-prone heuristics the loader simply attempts to load the texture. If GL_INVALID_ENUM is returned, the loader checks if it has a software decoder for the format (only true for ETC[12]). If it does, it clears the error, decodes the texture and uploads the decoded texture. If not, it returns the GL_INVALID_ENUM in glerror.

I've fixed the typo in the documentation. It will be in the next release.

Raffaello commented 8 months ago

@MarkCallow thanks.

  1. Doing the transcoding is enough to be succeful in GLUpload. I am wondering wouldn't be possible to have a function to do also the transcoding if needed for an easier usage?

  2. thanks, anyway that led me to improve my handling error routine.

  3. 👍

MarkCallow commented 8 months ago

@Raffaello

  1. Automatically transcoding would require guessing the needs and intent of the application. The choice of target needs to be in the hands of the application writer.
Raffaello commented 8 months ago

@MarkCallow One more thing, I noticed that GLUpload or `ktTexture_createdFromNamedFile' doesn't flip the Y of the images. Is there anything available in the ktxlib to tell to flip Y of the images? As it is not really convinient after the texture being created to flip it or negate the tex coords...

MarkCallow commented 8 months ago

You can set the orientation when you create a texture with ktx create. A y-flip will be performed if the input image orientation differs from that specified. (Default origin is top-left or, in terms of increasing s & t, right-down). You should make textures with the orientation you desire. If the texture and coordinates do not match, it is fairly easy to modify them. E.g,

    if (kTexture->orientation.x == KTX_ORIENT_X_LEFT)
        sign_s = -1;
    if (kTexture->orientation.y == KTX_ORIENT_Y_UP)
        sign_t = -1;

    if (sign_s < 0 || sign_t < 0) {
        // Transform the texture coordinates to get correct image orientation.
        for (uint32_t i = 0; i < vertexBuffer.size(); i++) {
            if (sign_t < 1) {
                vertexBuffer[i].uv[1] = vertexBuffer[i].uv[1] * -1 + 1;
            }
            if (sign_s < 1) {
                vertexBuffer[i].uv[0] = vertexBuffer[i].uv[0] * -1 + 1;
            }
        }
    }

If you do not want to modify the uv coordinates before loading it is easy to apply the texture coordinate transform in the vertex shader.

As with automatic transcoding, an automatic flip would require second guessing the application and would be wrong in some cases.

Re. ktxTexture_CreateFromNamedFile we chose to keep image processing out of libktx. Applications need to perform any necessary flip before calling this function.