This structure is used to pass to a callback function data that is uniform across all images.
+
+
texImage1DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(faceLodSize);
+
UNUSED(depth);
+
UNUSED(height);
+
+
assert(gl.glTexImage1D != NULL);
+
gl.glTexImage1D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat, width, 0,
+
cbData->glFormat, cbData->glType, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
compressedTexImage1DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(depth);
+
UNUSED(height);
+
+
if (faceLodSize > UINT32_MAX)
+
+
+
assert(gl.glCompressedTexImage1D != NULL);
+
gl.glCompressedTexImage1D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat, width, 0,
+
(ktx_uint32_t)faceLodSize, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
texImage2DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(depth);
+
UNUSED(faceLodSize);
+
+
glTexImage2D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat, width,
+
cbData->numLayers == 0 ? (GLuint)height : cbData->numLayers, 0,
+
cbData->glFormat, cbData->glType, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
+
compressedTexImage2DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
GLenum glerror;
+
+
UNUSED(depth);
+
+
if (faceLodSize > UINT32_MAX)
+
+
+
+
+
+
glCompressedTexImage2D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat, width,
+
cbData->numLayers == 0 ? (GLuint)height : cbData->numLayers,
+
0,
+
(ktx_uint32_t)faceLodSize, pixels);
+
+
glerror = glGetError();
+
#if SUPPORT_SOFTWARE_ETC_UNPACK
+
+
if ((glerror == GL_INVALID_ENUM || glerror == GL_INVALID_VALUE)
+
&& (cbData->glInternalformat == GL_ETC1_RGB8_OES
+
|| (cbData->glInternalformat >= GL_COMPRESSED_R11_EAC
+
&& cbData->glInternalformat <= GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
+
))
+
{
+
GLubyte* unpacked;
+
GLenum format, internalformat, type;
+
+
result = _ktxUnpackETC((GLubyte*)pixels, cbData->glInternalformat,
+
width, height, &unpacked,
+
&format, &internalformat,
+
&type, R16Formats, supportsSRGB);
+
+
return result;
+
}
+
if (!(sizedFormats & _NON_LEGACY_FORMATS)) {
+
if (internalformat == GL_RGB8)
+
internalformat = GL_RGB;
+
else if (internalformat == GL_RGBA8)
+
internalformat = GL_RGBA;
+
}
+
glTexImage2D(cbData->glTarget + face, miplevel,
+
internalformat, width,
+
cbData->numLayers == 0 ? (GLuint)height : cbData->numLayers, 0,
+
format, type, unpacked);
+
+
free(unpacked);
+
glerror = glGetError();
+
}
+
#endif
+
+
if ((cbData->glError = glerror) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
texImage3DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(faceLodSize);
+
+
assert(gl.glTexImage3D != NULL);
+
gl.glTexImage3D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat,
+
width, height,
+
cbData->numLayers == 0 ? (GLuint)depth : cbData->numLayers,
+
0,
+
cbData->glFormat, cbData->glType, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
compressedTexImage3DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
+
if (faceLodSize > UINT32_MAX)
+
+
+
assert(gl.glCompressedTexImage3D != NULL);
+
gl.glCompressedTexImage3D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat,
+
width, height,
+
cbData->numLayers == 0 ? (GLuint)depth : cbData->numLayers,
+
0,
+
(ktx_uint32_t)faceLodSize, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
This function creates the GL texture object and sets up the callbacks to load the image data into it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifdef _WIN32
+
#define _CRT_SECURE_NO_WARNINGS
+
#endif
+
+
#include <assert.h>
+
#include <string.h>
+
#include <stdint.h>
+
#include <stdlib.h>
+
+
#include "gl_funcs.h"
+
#define SUPPORT_LEGACY_FORMAT_CONVERSION 0
+
+
#if SUPPORT_LEGACY_FORMAT_CONVERSION
+
+
#include "GL/glext.h"
+
#endif
+
+
+
#include "ktxint.h"
+
#include "texture.h"
+
#include "vk2gl.h"
+
#include "unused.h"
+
+
+
+
+
+
#if !defined( GL_LUMINANCE )
+
#define GL_LUMINANCE 0x1909
+
#endif
+
#if !defined( GL_LUMINANCE_ALPHA )
+
#define GL_LUMINANCE_ALPHA 0x190A
+
#endif
+
#if !defined( GL_INTENSITY )
+
#define GL_INTENSITY 0x8049
+
#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#define GL_GENERATE_MIPMAP 0x8191
+
+
#define _CONTEXT_ES_PROFILE_BIT 0x4
+
+
#define _NON_LEGACY_FORMATS 0x1
+
#define _LEGACY_FORMATS 0x2
+
#define _ALL_SIZED_FORMATS (_NON_LEGACY_FORMATS | _LEGACY_FORMATS)
+
#define _NO_SIZED_FORMATS 0
+
+
static GLint contextProfile = 0;
+
static GLint sizedFormats = _ALL_SIZED_FORMATS;
+
static GLboolean supportsSwizzle = GL_TRUE;
+
static GLint R16Formats = _KTX_ALL_R16_FORMATS;
+
static GLboolean supportsSRGB = GL_TRUE;
+
static GLboolean supportsCubeMapArrays = GL_FALSE;
+
+
static GLboolean supportsMaxLevel = GL_FALSE;
+
+
static GLboolean
+
hasExtension(const char* extension)
+
{
+
if (gl.glGetStringi == NULL) {
+
if (strstr(glGetString(GL_EXTENSIONS), extension) != NULL) {
+
return GL_TRUE;
+
} else {
+
return GL_FALSE;
+
}
+
} else {
+
int i, n;
+
+
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
+
for (i = 0; i < n; i++) {
+
if (strcmp((const char*)gl.glGetStringi(GL_EXTENSIONS, i), extension) == 0)
+
return GL_TRUE;
+
}
+
return GL_FALSE;
+
}
+
}
+
+
static void
+
discoverContextCapabilities(void)
+
{
+
GLint majorVersion = 1;
+
GLint minorVersion = 0;
+
+
if (strstr(glGetString(GL_VERSION), "GL ES") != NULL)
+
contextProfile = _CONTEXT_ES_PROFILE_BIT;
+
+
glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
+
glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
+
if (glGetError() != GL_NO_ERROR) {
+
+
if (contextProfile & _CONTEXT_ES_PROFILE_BIT)
+
sscanf(glGetString(GL_VERSION), "OpenGL ES %d.%d ",
+
&majorVersion, &minorVersion);
+
else
+
sscanf(glGetString(GL_VERSION), "OpenGL %d.%d ",
+
&majorVersion, &minorVersion);
+
}
+
if (contextProfile & _CONTEXT_ES_PROFILE_BIT) {
+
if (majorVersion < 3) {
+
supportsSwizzle = GL_FALSE;
+
sizedFormats = _NO_SIZED_FORMATS;
+
R16Formats = _KTX_NO_R16_FORMATS;
+
supportsSRGB = GL_FALSE;
+
+
+
+
+
gl.glGetStringi = NULL;
+
gl.glCompressedTexImage1D = NULL;
+
gl.glTexStorage1D = NULL;
+
gl.glTexStorage2D = NULL;
+
gl.glTexStorage3D = NULL;
+
if (!hasExtension("GL_OES_texture_3D")) {
+
gl.glCompressedTexImage3D = NULL;
+
gl.glCompressedTexSubImage3D = NULL;
+
gl.glTexImage3D = NULL;
+
gl.glTexSubImage3D = NULL;
+
}
+
if (majorVersion < 2)
+
gl.glGenerateMipmap = NULL;
+
+
} else {
+
sizedFormats = _NON_LEGACY_FORMATS;
+
if (hasExtension("GL_EXT_texture_cube_map_array")) {
+
supportsCubeMapArrays = GL_TRUE;
+
}
+
supportsMaxLevel = GL_TRUE;
+
}
+
if (hasExtension("GL_OES_required_internalformat")) {
+
sizedFormats |= _ALL_SIZED_FORMATS;
+
}
+
+
} else {
+
+
+
+
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &contextProfile);
+
if (glGetError() == GL_NO_ERROR) {
+
+
if (majorVersion == 3 && minorVersion < 3)
+
supportsSwizzle = GL_FALSE;
+
if ((contextProfile & GL_CONTEXT_CORE_PROFILE_BIT))
+
sizedFormats &= ~_LEGACY_FORMATS;
+
if (majorVersion >= 4)
+
supportsCubeMapArrays = GL_TRUE;
+
supportsMaxLevel = GL_TRUE;
+
} else {
+
+
contextProfile = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
+
supportsSwizzle = GL_FALSE;
+
+
if (majorVersion < 2 && !hasExtension("GL_EXT_texture_sRGB")) {
+
supportsSRGB = GL_FALSE;
+
}
+
+
if (majorVersion == 3) {
+
if (minorVersion == 0)
+
R16Formats &= ~_KTX_R16_FORMATS_SNORM;
+
if (minorVersion < 1) {
+
if (hasExtension("GL_ARB_texture_query_levels"))
+
supportsMaxLevel = GL_TRUE;
+
} else {
+
supportsMaxLevel = GL_TRUE;
+
}
+
} else if (hasExtension("GL_ARB_texture_rg")) {
+
R16Formats &= ~_KTX_R16_FORMATS_SNORM;
+
} else {
+
R16Formats = _KTX_NO_R16_FORMATS;
+
}
+
}
+
if (!supportsCubeMapArrays) {
+
if (hasExtension("GL_ARB_texture_cube_map_array")) {
+
supportsCubeMapArrays = GL_TRUE;
+
}
+
}
+
}
+
}
+
+
#if SUPPORT_LEGACY_FORMAT_CONVERSION
+
static void convertFormat(GLenum target, GLenum* pFormat, GLenum* pInternalformat) {
+
switch (*pFormat) {
+
case GL_ALPHA:
+
{
+
GLint swizzle[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED};
+
*pFormat = GL_RED;
+
glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+
switch (*pInternalformat) {
+
case GL_ALPHA:
+
case GL_ALPHA4_EXT:
+
case GL_ALPHA8_EXT:
+
*pInternalformat = GL_R8;
+
break;
+
case GL_ALPHA12_EXT:
+
case GL_ALPHA16_EXT:
+
*pInternalformat = GL_R16;
+
break;
+
}
+
}
+
case GL_LUMINANCE:
+
{
+
GLint swizzle[] = {GL_RED, GL_RED, GL_RED, GL_ONE};
+
*pFormat = GL_RED;
+
glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+
switch (*pInternalformat) {
+
case GL_LUMINANCE:
+
case GL_LUMINANCE4_EXT:
+
case GL_LUMINANCE8_EXT:
+
*pInternalformat = GL_R8;
+
break;
+
case GL_LUMINANCE12_EXT:
+
case GL_LUMINANCE16_EXT:
+
*pInternalformat = GL_R16;
+
break;
+
#if 0
+
+
+
case GL_SLUMINANCE:
+
case GL_SLUMINANCE8:
+
*pInternalformat = GL_SRGB8;
+
break;
+
#endif
+
}
+
break;
+
}
+
case GL_LUMINANCE_ALPHA:
+
{
+
GLint swizzle[] = {GL_RED, GL_RED, GL_RED, GL_GREEN};
+
*pFormat = GL_RG;
+
glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+
switch (*pInternalformat) {
+
case GL_LUMINANCE_ALPHA:
+
case GL_LUMINANCE4_ALPHA4_EXT:
+
case GL_LUMINANCE6_ALPHA2_EXT:
+
case GL_LUMINANCE8_ALPHA8_EXT:
+
*pInternalformat = GL_RG8;
+
break;
+
case GL_LUMINANCE12_ALPHA4_EXT:
+
case GL_LUMINANCE12_ALPHA12_EXT:
+
case GL_LUMINANCE16_ALPHA16_EXT:
+
*pInternalformat = GL_RG16;
+
break;
+
#if 0
+
+
+
case GL_SLUMINANCE_ALPHA_EXT:
+
case GL_SLUMINANCE8_ALPHA8_EXT:
+
*pInternalformat = GL_SRGB8_ALPHA8;
+
break;
+
#endif
+
}
+
break;
+
}
+
case GL_INTENSITY:
+
{
+
GLint swizzle[] = {GL_RED, GL_RED, GL_RED, GL_RED};
+
*pFormat = GL_RED;
+
glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+
switch (*pInternalformat) {
+
case GL_INTENSITY:
+
case GL_INTENSITY4_EXT:
+
case GL_INTENSITY8_EXT:
+
*pInternalformat = GL_R8;
+
break;
+
case GL_INTENSITY12_EXT:
+
case GL_INTENSITY16_EXT:
+
*pInternalformat = GL_R16;
+
break;
+
}
+
break;
+
}
+
default:
+
break;
+
}
+
}
+
#endif
+
+
typedef struct ktx_glformatinfo {
+
ktx_uint32_t glFormat;
+
ktx_uint32_t glInternalformat;
+
ktx_uint32_t glBaseInternalformat;
+
ktx_uint32_t glType;
+
} ktx_glformatinfo;
+
+
+
typedef struct ktx_cbdata {
+
GLenum glTarget;
+
GLenum glFormat;
+
GLenum glInternalformat;
+
GLenum glType;
+
GLenum glError;
+
GLuint numLayers;
+
} ktx_cbdata;
+
+
+
+
+
+
texImage1DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(faceLodSize);
+
UNUSED(depth);
+
UNUSED(height);
+
+
assert(gl.glTexImage1D != NULL);
+
gl.glTexImage1D(cbData->
glTarget + face, miplevel,
+
cbData->
glInternalformat, width, 0,
+
cbData->
glFormat, cbData->
glType, pixels);
+
+
if ((cbData->
glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
compressedTexImage1DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(depth);
+
UNUSED(height);
+
+
if (faceLodSize > UINT32_MAX)
+
+
+
assert(gl.glCompressedTexImage1D != NULL);
+
gl.glCompressedTexImage1D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat, width, 0,
+
(ktx_uint32_t)faceLodSize, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
texImage2DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(depth);
+
UNUSED(faceLodSize);
+
+
glTexImage2D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat, width,
+
cbData->
numLayers == 0 ? (GLuint)height : cbData->numLayers, 0,
+
cbData->glFormat, cbData->glType, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
+
compressedTexImage2DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
GLenum glerror;
+
+
UNUSED(depth);
+
+
if (faceLodSize > UINT32_MAX)
+
+
+
+
+
+
glCompressedTexImage2D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat, width,
+
cbData->numLayers == 0 ? (GLuint)height : cbData->numLayers,
+
0,
+
(ktx_uint32_t)faceLodSize, pixels);
+
+
glerror = glGetError();
+
#if SUPPORT_SOFTWARE_ETC_UNPACK
+
+
if ((glerror == GL_INVALID_ENUM || glerror == GL_INVALID_VALUE)
+
&& (cbData->glInternalformat == GL_ETC1_RGB8_OES
+
|| (cbData->glInternalformat >= GL_COMPRESSED_R11_EAC
+
&& cbData->glInternalformat <= GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
+
))
+
{
+
GLubyte* unpacked;
+
GLenum format, internalformat, type;
+
+
result = _ktxUnpackETC((GLubyte*)pixels, cbData->glInternalformat,
+
width, height, &unpacked,
+
&format, &internalformat,
+
&type, R16Formats, supportsSRGB);
+
+
return result;
+
}
+
if (!(sizedFormats & _NON_LEGACY_FORMATS)) {
+
if (internalformat == GL_RGB8)
+
internalformat = GL_RGB;
+
else if (internalformat == GL_RGBA8)
+
internalformat = GL_RGBA;
+
}
+
glTexImage2D(cbData->glTarget + face, miplevel,
+
internalformat, width,
+
cbData->numLayers == 0 ? (GLuint)height : cbData->numLayers, 0,
+
format, type, unpacked);
+
+
free(unpacked);
+
glerror = glGetError();
+
}
+
#endif
+
+
if ((cbData->glError = glerror) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
texImage3DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
UNUSED(faceLodSize);
+
+
assert(gl.glTexImage3D != NULL);
+
gl.glTexImage3D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat,
+
width, height,
+
cbData->numLayers == 0 ? (GLuint)depth : cbData->numLayers,
+
0,
+
cbData->glFormat, cbData->glType, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
compressedTexImage3DCallback(int miplevel, int face,
+
int width, int height,
+
int depth,
+
ktx_uint64_t faceLodSize,
+
void* pixels, void* userdata)
+
{
+
ktx_cbdata* cbData = (ktx_cbdata*)userdata;
+
+
if (faceLodSize > UINT32_MAX)
+
+
+
assert(gl.glCompressedTexImage3D != NULL);
+
gl.glCompressedTexImage3D(cbData->glTarget + face, miplevel,
+
cbData->glInternalformat,
+
width, height,
+
cbData->numLayers == 0 ? (GLuint)depth : cbData->numLayers,
+
0,
+
(ktx_uint32_t)faceLodSize, pixels);
+
+
if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
+
+
} else {
+
+
}
+
}
+
+
+
+
+
ktxTexture_GLUploadPrivate(
ktxTexture* This, ktx_glformatinfo* formatInfo,
+
GLuint* pTexture, GLenum* pTarget, GLenum* pGlerror)
+
{
+
GLuint texname;
+
GLenum target = GL_TEXTURE_2D;
+
int texnameUser;
+
+
ktx_cbdata cbData;
+
PFNKTXITERCB iterCb = NULL;
+
int dimensions;
+
+
if (pGlerror)
+
*pGlerror = GL_NO_ERROR;
+
+
assert(This && pTarget);
+
+
if (contextProfile == 0)
+
discoverContextCapabilities();
+
+
texnameUser = pTexture && *pTexture;
+
if (texnameUser) {
+
texname = *pTexture;
+
} else {
+
glGenTextures(1, &texname);
+
}
+
+
cbData.glFormat = formatInfo->
glFormat;
+
cbData.glInternalformat = formatInfo->
glInternalformat;
+
cbData.glType = formatInfo->
glType;
+
+
+
+
dimensions += 1;
+
+
+
+
target = GL_TEXTURE_CUBE_MAP_ARRAY;
+
} else {
+
+
case 1: target = GL_TEXTURE_1D_ARRAY; break;
+
case 2: target = GL_TEXTURE_2D_ARRAY; break;
+
+
default: assert(KTX_TRUE);
+
}
+
}
+
cbData.numLayers = This->
numLayers;
+
} else {
+
+
+
+
target = GL_TEXTURE_CUBE_MAP;
+
} else {
+
+
case 1: target = GL_TEXTURE_1D; break;
+
case 2: target = GL_TEXTURE_2D; break;
+
case 3: target = GL_TEXTURE_3D; break;
+
+
default: assert(KTX_TRUE);
+
}
+
}
+
cbData.numLayers = 0;
+
}
+
+
if (target == GL_TEXTURE_1D &&
+
((This->
isCompressed && (gl.glCompressedTexImage1D == NULL)) ||
+
+
{
+
+
}
+
+
+
if (target == GL_TEXTURE_3D &&
+
((This->
isCompressed && (gl.glCompressedTexImage3D == NULL)) ||
+
+
{
+
+
}
+
+
+
if (target == GL_TEXTURE_CUBE_MAP_ARRAY && !supportsCubeMapArrays) {
+
+
}
+
+
+
+
switch (dimensions) {
+
case 1:
+
+
? compressedTexImage1DCallback : texImage1DCallback;
+
break;
+
case 2:
+
+
? compressedTexImage2DCallback : texImage2DCallback;
+
break;
+
case 3:
+
+
? compressedTexImage3DCallback : texImage3DCallback;
+
break;
+
default:
+
assert(KTX_TRUE);
+
}
+
+
glBindTexture(target, texname);
+
+
+
+
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
+
}
+
+
+
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, This->
numLevels - 1);
+
+
if (target == GL_TEXTURE_CUBE_MAP) {
+
cbData.glTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+
} else {
+
cbData.glTarget = target;
+
}
+
+
+
#if SUPPORT_LEGACY_FORMAT_CONVERSION
+
+
+
+
if (sizedFormats == _NON_LEGACY_FORMATS && supportsSwizzle) {
+
convertFormat(target, &cbData.glFormat, &cbData.glInternalformat);
+
} else if (sizedFormats == _NO_SIZED_FORMATS)
+
cbData.glInternalformat = formatInfo->
glBaseInternalformat;
+
#else
+
+
+
if (sizedFormats == _NO_SIZED_FORMATS
+
|| (!(sizedFormats & _LEGACY_FORMATS) &&
+
(formatInfo->glBaseInternalformat == GL_ALPHA
+
|| formatInfo->glBaseInternalformat == GL_LUMINANCE
+
|| formatInfo->glBaseInternalformat == GL_LUMINANCE_ALPHA
+
|| formatInfo->glBaseInternalformat == GL_INTENSITY))) {
+
cbData.glInternalformat = formatInfo->glBaseInternalformat;
+
}
+
#endif
+
}
+
+
+
+
else
+
result = ktxTexture_IterateLevelFaces(This, iterCb, &cbData);
+
+
+
if (result !=
KTX_SUCCESS && cbData.glError != GL_NO_ERROR) {
+
if (pGlerror)
+
*pGlerror = cbData.glError;
+
}
+
+
+
{
+
+
+
gl.glGenerateMipmap(target);
+
}
+
*pTarget = target;
+
if (pTexture) {
+
*pTexture = texname;
+
}
+
} else if (!texnameUser) {
+
glDeleteTextures(1, &texname);
+
}
+
return result;
+
}
+
+
+
+
ktxTexture1_GLUpload(
ktxTexture1* This, GLuint* pTexture, GLenum* pTarget,
+
GLenum* pGlerror)
+
{
+
GLint previousUnpackAlignment;
+
+
ktx_glformatinfo formatInfo;
+
+
if (!This) {
+
+
}
+
+
if (!pTarget) {
+
+
}
+
+
+
+
return result;
+
}
+
+
glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousUnpackAlignment);
+
+
+
}
+
+
+
+
+
formatInfo.glType = This->
glType;
+
+
result = ktxTexture_GLUploadPrivate(
ktxTexture(This), &formatInfo,
+
pTexture, pTarget, pGlerror);
+
+
+
+
glPixelStorei(GL_UNPACK_ALIGNMENT, previousUnpackAlignment);
+
}
+
+
return result;
+
}
+
+
+
ktxTexture2_GLUpload(
ktxTexture2* This, GLuint* pTexture, GLenum* pTarget,
+
GLenum* pGlerror)
+
{
+
GLint previousUnpackAlignment;
+
+
ktx_glformatinfo formatInfo;
+
+
if (!This) {
+
+
}
+
+
if (!pTarget) {
+
+
}
+
+
+
+
return result;
+
}
+
+
if (This->
vkFormat != VK_FORMAT_UNDEFINED) {
+
formatInfo.glInternalformat =
+
vkFormat2glInternalFormat(This->vkFormat);
+
if (formatInfo.glInternalformat == GL_INVALID_VALUE) {
+
+
+
}
+
} else {
+
+
+
+
}
+
+
if (This->
isCompressed) {
+
+
formatInfo.glFormat = GL_INVALID_VALUE;
+
formatInfo.glType = GL_INVALID_VALUE;
+
formatInfo.glBaseInternalformat = GL_INVALID_VALUE;
+
} else {
+
formatInfo.glFormat = vkFormat2glFormat(This->vkFormat);
+
formatInfo.glType = vkFormat2glType(This->vkFormat);
+
formatInfo.glBaseInternalformat = formatInfo.glInternalformat;
+
+
if (formatInfo.glFormat == GL_INVALID_VALUE || formatInfo.glType == GL_INVALID_VALUE)
+
+
}
+
+
glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousUnpackAlignment);
+
if (previousUnpackAlignment != 1) {
+
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
}
+
+
result = ktxTexture_GLUploadPrivate(
ktxTexture(This), &formatInfo,
+
pTexture, pTarget, pGlerror);
+
+
+
if (previousUnpackAlignment != 1) {
+
glPixelStorei(GL_UNPACK_ALIGNMENT, previousUnpackAlignment);
+
}
+
+
return result;
+
}
+
+
+
ktxTexture_GLUpload(
ktxTexture* This, GLuint* pTexture, GLenum* pTarget,
+
GLenum* pGlerror)
+
{
+
if (This->
classId == ktxTexture2_c)
+
return ktxTexture2_GLUpload((
ktxTexture2*)This, pTexture, pTarget,
+
pGlerror);
+
else
+
return ktxTexture1_GLUpload((
ktxTexture1*)This, pTexture, pTarget,
+
pGlerror);
+
}
+
+
KTX_API KTX_error_code KTX_APIENTRY ktxLoadOpenGL(PFNGLGETPROCADDRESS pfnGLGetProcAddress)
Load pointers for the GL functions used by the ktxTexture*_GLUpload functions.
Definition gl_funcs.c:216
+
ktx_error_code_e
Error codes returned by library functions.
Definition ktx.h:169
+
@ KTX_INVALID_VALUE
Definition ktx.h:181
+
@ KTX_GL_ERROR
Definition ktx.h:179
+
@ KTX_UNSUPPORTED_TEXTURE_TYPE
Definition ktx.h:186
+
@ KTX_INVALID_OPERATION
Definition ktx.h:180
+
@ KTX_SUCCESS
Definition ktx.h:170
+
#define KTX_error_code
For backward compatibility.
Definition ktx.h:198
+
#define KTX_GL_UNPACK_ALIGNMENT
Required unpack alignment.
Definition ktx.h:159
+
#define ktxTexture_IterateLoadLevelFaces(This, iterCb, userdata)
Helper for calling the IterateLoadLevelFaces virtual method of a ktxTexture.
Definition ktx.h:585
+
Class representing a KTX version 1 format texture.
Definition ktx.h:667
+
ktx_uint32_t glFormat
Definition ktx.h:669
+
ktx_uint32_t glInternalformat
Definition ktx.h:670
+
ktx_uint32_t glBaseInternalformat
Definition ktx.h:672
+
ktx_uint32_t glType
Definition ktx.h:674
+
Class representing a KTX version 2 format texture.
Definition ktx.h:706
+
Base class representing a texture.
Definition ktx.h:287
+
class_id classId
Identify the class type.
Definition ktx.h:288
+
ktx_bool_t isCompressed
Definition ktx.h:288
+
ktx_uint32_t numFaces
Number of faces: 6 for cube maps, 1 otherwise.
Definition ktx.h:288
+
ktx_uint32_t numDimensions
Number of dimensions in the texture: 1, 2 or 3.
Definition ktx.h:288
+
ktx_uint32_t numLevels
Number of mip levels in the texture.
Definition ktx.h:288
+
ktx_bool_t isArray
Definition ktx.h:288
+
ktx_bool_t generateMipmaps
Definition ktx.h:288
+