Add support for fetching specific cube map faces
| | |
| | | #include <assert.h> |
| | | #include <errno.h> |
| | | #include <stdbool.h> |
| | | #include <stdint.h> |
| | |
| | | } |
| | | |
| | | uint32_t hash = 0x12345678; |
| | | switch (textureType) { |
| | | case MOJODDS_TEXTURE_NONE: |
| | | assert(false); // this is not supposed to happen |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_2D: |
| | | for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { |
| | | const void *miptex = NULL; |
| | | unsigned long miptexlen = 0; |
| | |
| | | hash = (hash * 65537) ^ miptex_[i]; |
| | | } |
| | | } |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_CUBE: |
| | | for (MOJODDS_cubeFace cubeFace = MOJODDS_CUBEFACE_POSITIVE_X; cubeFace <= MOJODDS_CUBEFACE_NEGATIVE_Z; cubeFace++) { |
| | | for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { |
| | | const void *miptex = NULL; |
| | | unsigned long miptexlen = 0; |
| | | unsigned int mipW = 0, mipH = 0; |
| | | retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); |
| | | if (!retval) { |
| | | continue; |
| | | } |
| | | |
| | | // read every byte to make sure any buffer overflows actually overflow |
| | | const char *miptex_ = (const char *) miptex; |
| | | for (unsigned int i = 0; i < miptexlen; i++) { |
| | | hash = (hash * 65537) ^ miptex_[i]; |
| | | } |
| | | } |
| | | } |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_VOLUME: |
| | | // TODO: do something with the data |
| | | break; |
| | | |
| | | } |
| | | // do something the optimizer is not allowed to remove |
| | | printf("0x%08x\n", hash); |
| | | |
| | |
| | | |
| | | case MOJODDS_TEXTURE_2D: |
| | | printf("2D\n"); |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_CUBE: |
| | | printf("cube\n"); |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_VOLUME: |
| | | printf("volume\n"); |
| | | break; |
| | | |
| | | } |
| | | printf("\n"); |
| | | |
| | | for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { |
| | |
| | | printf("miptexoffset: %8u ", (unsigned int)(miptexoffset)); |
| | | printf("miptexlen: %8lu\n", miptexlen); |
| | | } |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_CUBE: |
| | | printf("cube\n"); |
| | | printf("\n"); |
| | | |
| | | for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { |
| | | const void *miptex = NULL; |
| | | unsigned long miptexlen = 0; |
| | | unsigned int mipW = 0, mipH = 0; |
| | | retval = MOJODDS_getCubeFace(MOJODDS_CUBEFACE_POSITIVE_X, miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH); |
| | | if (!retval) { |
| | | printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval); |
| | | continue; |
| | | } |
| | | |
| | | uintptr_t miptexoffset = ((const char *)(miptex)) - ((const char *)(tex)); |
| | | bool npot = !(isPow2(mipW) || isPow2(mipH)); |
| | | printf("%4u x %4u %s", mipW, mipH, npot ? "NPOT " : " "); |
| | | printf("miptexoffset: %8u ", (unsigned int)(miptexoffset)); |
| | | printf("miptexlen: %8lu\n", miptexlen); |
| | | } |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_VOLUME: |
| | | printf("volume\n"); |
| | | break; |
| | | |
| | | } |
| | | } |
| | | |
| | | free(contents); |
| | |
| | | #define _GNU_SOURCE |
| | | |
| | | #include <assert.h> |
| | | #include <errno.h> |
| | | #include <stdbool.h> |
| | | #include <stdint.h> |
| | |
| | | GLuint texId = 0; |
| | | // we leak this but don't care |
| | | glGenTextures(1, &texId); |
| | | |
| | | switch (textureType) { |
| | | case MOJODDS_TEXTURE_NONE: |
| | | assert(false); // this is not supposed to happen |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_2D: |
| | | glBindTexture(GL_TEXTURE_2D, texId); |
| | | |
| | | for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { |
| | |
| | | } |
| | | } |
| | | } |
| | | glBindTexture(GL_TEXTURE_2D, 0); |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_CUBE: |
| | | glBindTexture(GL_TEXTURE_CUBE_MAP, texId); |
| | | |
| | | for (MOJODDS_cubeFace cubeFace = MOJODDS_CUBEFACE_POSITIVE_X; cubeFace <= MOJODDS_CUBEFACE_NEGATIVE_Z; cubeFace++) { |
| | | for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { |
| | | const void *miptex = NULL; |
| | | unsigned long miptexlen = 0; |
| | | unsigned int mipW = 0, mipH = 0; |
| | | retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); |
| | | if (!retval) { |
| | | printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval); |
| | | continue; |
| | | } |
| | | |
| | | if (isCompressed) { |
| | | glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, glfmt, mipW, mipH, 0, miptexlen, miptex); |
| | | pumpGLErrors("glCompressedTexImage2D %u 0x%04x %ux%u %u", miplevel, glfmt, mipW, mipH, miptexlen); |
| | | } else { |
| | | glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, internalFormat, mipW, mipH, 0, glfmt, GL_UNSIGNED_BYTE, miptex); |
| | | pumpGLErrors("glTexImage2D %u 0x%04x %ux%u 0x%04x", miplevel, internalFormat, mipW, mipH, glfmt); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // and now the same with ARB_texture_storage if it's available |
| | | if (GLEW_ARB_texture_storage) { |
| | | glGenTextures(1, &texId); |
| | | glBindTexture(GL_TEXTURE_CUBE_MAP, texId); |
| | | glTexStorage2D(GL_TEXTURE_CUBE_MAP, miplevels, internalFormat, w, h); |
| | | pumpGLErrors("glTexStorage2D %u 0x%04x %ux%u", miplevels, internalFormat, w, h); |
| | | |
| | | for (MOJODDS_cubeFace cubeFace = MOJODDS_CUBEFACE_POSITIVE_X; cubeFace <= MOJODDS_CUBEFACE_NEGATIVE_Z; cubeFace++) { |
| | | for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) { |
| | | const void *miptex = NULL; |
| | | unsigned long miptexlen = 0; |
| | | unsigned int mipW = 0, mipH = 0; |
| | | retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH); |
| | | if (!retval) { |
| | | printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval); |
| | | continue; |
| | | } |
| | | |
| | | if (isCompressed) { |
| | | glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, 0, 0, mipW, mipH, glfmt, miptexlen, miptex); |
| | | pumpGLErrors("glCompressedTexSubImage2D %u %ux%u 0x%04x %u", miplevel, mipW, mipH, glfmt, miptexlen); |
| | | } else { |
| | | glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, miplevel, 0, 0, mipW, mipH, glfmt, GL_UNSIGNED_BYTE, miptex); |
| | | pumpGLErrors("glTexSubImage2D %u %ux%u 0x%04x", miplevel, mipW, mipH, glfmt); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | glBindTexture(GL_TEXTURE_CUBE_MAP, 0); |
| | | break; |
| | | |
| | | case MOJODDS_TEXTURE_VOLUME: |
| | | // TODO: do something with the data |
| | | break; |
| | | |
| | | } |
| | | } |
| | | |
| | | free(contents); |
| | |
| | | } // MOJODDS_getMipMapTexture |
| | | |
| | | |
| | | int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel, |
| | | unsigned int glfmt, const void *_basetex, |
| | | unsigned long _basetexlen, unsigned int w, unsigned h, |
| | | const void **_tex, unsigned long *_texlen, |
| | | unsigned int *_texw, unsigned int *_texh) |
| | | { |
| | | // pick correct face |
| | | const char *faceBaseTex = (const char *) _basetex; |
| | | faceBaseTex = faceBaseTex + cubeFace * _basetexlen; |
| | | |
| | | |
| | | // call MOJODDS_getMipMapTexture to get offset in that face |
| | | return MOJODDS_getMipMapTexture(miplevel, glfmt, faceBaseTex, _basetexlen, w, h, _tex, _texlen, _texw, _texh); |
| | | } |
| | | |
| | | |
| | | // end of mojodds.c ... |
| | | |
| | |
| | | MOJODDS_TEXTURE_VOLUME |
| | | } MOJODDS_textureType; |
| | | |
| | | |
| | | /* order and values for these matter, they are used for calculating offsets |
| | | lucky for us both DDS and OpengGL order matches */ |
| | | typedef enum MOJODDS_cubeFace { |
| | | MOJODDS_CUBEFACE_POSITIVE_X, |
| | | MOJODDS_CUBEFACE_NEGATIVE_X, |
| | | MOJODDS_CUBEFACE_POSITIVE_Y, |
| | | MOJODDS_CUBEFACE_NEGATIVE_Y, |
| | | MOJODDS_CUBEFACE_POSITIVE_Z, |
| | | MOJODDS_CUBEFACE_NEGATIVE_Z |
| | | } MOJODDS_cubeFace; |
| | | |
| | | |
| | | int MOJODDS_isDDS(const void *_ptr, const unsigned long _len); |
| | | int MOJODDS_getTexture(const void *_ptr, const unsigned long _len, |
| | | const void **_tex, unsigned long *_texlen, |
| | |
| | | const void **_tex, unsigned long *_texlen, |
| | | unsigned int *_texw, unsigned int *_texh); |
| | | |
| | | int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel, |
| | | unsigned int glfmt, const void*_basetex, |
| | | unsigned long _basetexlen, unsigned int w, unsigned h, |
| | | const void **_tex, unsigned long *_texlen, |
| | | unsigned int *_texw, unsigned int *_texh); |
| | | |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |