TextureData is now named Image!;

The existing Image construct was renamed StorageImage.
This commit is contained in:
bjorn 2021-02-08 20:17:47 -07:00
parent dca79f83f0
commit 8164e0b6e8
23 changed files with 337 additions and 337 deletions

View File

@ -349,18 +349,18 @@ endif()
if(LOVR_ENABLE_DATA)
target_sources(lovr PRIVATE
src/modules/data/blob.c
src/modules/data/image.c
src/modules/data/modelData.c
src/modules/data/modelData_gltf.c
src/modules/data/modelData_obj.c
src/modules/data/rasterizer.c
src/modules/data/sound.c
src/modules/data/textureData.c
src/api/l_data.c
src/api/l_data_blob.c
src/api/l_data_image.c
src/api/l_data_modelData.c
src/api/l_data_rasterizer.c
src/api/l_data_sound.c
src/api/l_data_textureData.c
src/lib/minimp3/minimp3.c
src/lib/stb/stb_image.c
src/lib/stb/stb_truetype.c

View File

@ -41,6 +41,7 @@ extern const luaL_Reg lovrCylinderShape[];
extern const luaL_Reg lovrDistanceJoint[];
extern const luaL_Reg lovrFont[];
extern const luaL_Reg lovrHingeJoint[];
extern const luaL_Reg lovrImage[];
extern const luaL_Reg lovrMat4[];
extern const luaL_Reg lovrMaterial[];
extern const luaL_Reg lovrMesh[];
@ -58,7 +59,6 @@ extern const luaL_Reg lovrSource[];
extern const luaL_Reg lovrSphereShape[];
extern const luaL_Reg lovrMeshShape[];
extern const luaL_Reg lovrTexture[];
extern const luaL_Reg lovrTextureData[];
extern const luaL_Reg lovrThread[];
extern const luaL_Reg lovrVec2[];
extern const luaL_Reg lovrVec4[];

View File

@ -3,7 +3,7 @@
#include "data/modelData.h"
#include "data/rasterizer.h"
#include "data/sound.h"
#include "data/textureData.h"
#include "data/image.h"
#include <stdlib.h>
#include <string.h>
@ -90,37 +90,37 @@ static int l_lovrDataNewSound(lua_State* L) {
return 1;
}
static int l_lovrDataNewTextureData(lua_State* L) {
TextureData* textureData = NULL;
static int l_lovrDataNewImage(lua_State* L) {
Image* image = NULL;
if (lua_type(L, 1) == LUA_TNUMBER) {
int width = luaL_checkinteger(L, 1);
int height = luaL_checkinteger(L, 2);
TextureFormat format = luax_checkenum(L, 3, TextureFormat, "rgba");
Blob* blob = lua_isnoneornil(L, 4) ? NULL : luax_checktype(L, 4, Blob);
textureData = lovrTextureDataCreate(width, height, blob, 0x0, format);
image = lovrImageCreate(width, height, blob, 0x0, format);
} else {
TextureData* source = luax_totype(L, 1, TextureData);
Image* source = luax_totype(L, 1, Image);
if (source) {
textureData = lovrTextureDataCreate(source->width, source->height, source->blob, 0x0, source->format);
image = lovrImageCreate(source->width, source->height, source->blob, 0x0, source->format);
} else {
Blob* blob = luax_readblob(L, 1, "Texture");
bool flip = lua_isnoneornil(L, 2) ? true : lua_toboolean(L, 2);
textureData = lovrTextureDataCreateFromBlob(blob, flip);
image = lovrImageCreateFromBlob(blob, flip);
lovrRelease(blob, lovrBlobDestroy);
}
}
luax_pushtype(L, TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
luax_pushtype(L, Image, image);
lovrRelease(image, lovrImageDestroy);
return 1;
}
static const luaL_Reg lovrData[] = {
{ "newBlob", l_lovrDataNewBlob },
{ "newImage", l_lovrDataNewImage },
{ "newModelData", l_lovrDataNewModelData },
{ "newRasterizer", l_lovrDataNewRasterizer },
{ "newSound", l_lovrDataNewSound },
{ "newTextureData", l_lovrDataNewTextureData },
{ NULL, NULL }
};
@ -128,9 +128,9 @@ int luaopen_lovr_data(lua_State* L) {
lua_newtable(L);
luax_register(L, lovrData);
luax_registertype(L, Blob);
luax_registertype(L, Image);
luax_registertype(L, ModelData);
luax_registertype(L, Rasterizer);
luax_registertype(L, Sound);
luax_registertype(L, TextureData);
return 1;
}

View File

@ -1,57 +1,57 @@
#include "api.h"
#include "data/textureData.h"
#include "data/image.h"
#include "data/blob.h"
static int l_lovrTextureDataEncode(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
Blob* blob = lovrTextureDataEncode(textureData);
static int l_lovrImageEncode(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
Blob* blob = lovrImageEncode(image);
luax_pushtype(L, Blob, blob);
return 1;
}
static int l_lovrTextureDataGetWidth(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
lua_pushinteger(L, textureData->width);
static int l_lovrImageGetWidth(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
lua_pushinteger(L, image->width);
return 1;
}
static int l_lovrTextureDataGetHeight(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
lua_pushinteger(L, textureData->height);
static int l_lovrImageGetHeight(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
lua_pushinteger(L, image->height);
return 1;
}
static int l_lovrTextureDataGetDimensions(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
lua_pushinteger(L, textureData->width);
lua_pushinteger(L, textureData->height);
static int l_lovrImageGetDimensions(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
lua_pushinteger(L, image->width);
lua_pushinteger(L, image->height);
return 2;
}
static int l_lovrTextureDataGetFormat(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
luax_pushenum(L, TextureFormat, textureData->format);
static int l_lovrImageGetFormat(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
luax_pushenum(L, TextureFormat, image->format);
return 1;
}
static int l_lovrTextureDataPaste(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
TextureData* source = luax_checktype(L, 2, TextureData);
static int l_lovrImagePaste(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
Image* source = luax_checktype(L, 2, Image);
uint32_t dx = luaL_optinteger(L, 3, 0);
uint32_t dy = luaL_optinteger(L, 4, 0);
uint32_t sx = luaL_optinteger(L, 5, 0);
uint32_t sy = luaL_optinteger(L, 6, 0);
uint32_t w = luaL_optinteger(L, 7, source->width);
uint32_t h = luaL_optinteger(L, 8, source->height);
lovrTextureDataPaste(textureData, source, dx, dy, sx, sy, w, h);
lovrImagePaste(image, source, dx, dy, sx, sy, w, h);
return 0;
}
static int l_lovrTextureDataGetPixel(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
static int l_lovrImageGetPixel(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
int x = luaL_checkinteger(L, 2);
int y = luaL_checkinteger(L, 3);
Color color = lovrTextureDataGetPixel(textureData, x, y);
Color color = lovrImageGetPixel(image, x, y);
lua_pushnumber(L, color.r);
lua_pushnumber(L, color.g);
lua_pushnumber(L, color.b);
@ -59,8 +59,8 @@ static int l_lovrTextureDataGetPixel(lua_State* L) {
return 4;
}
static int l_lovrTextureDataSetPixel(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
static int l_lovrImageSetPixel(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
int x = luaL_checkinteger(L, 2);
int y = luaL_checkinteger(L, 3);
Color color = {
@ -69,26 +69,26 @@ static int l_lovrTextureDataSetPixel(lua_State* L) {
luax_optfloat(L, 6, 1.f),
luax_optfloat(L, 7, 1.f)
};
lovrTextureDataSetPixel(textureData, x, y, color);
lovrImageSetPixel(image, x, y, color);
return 0;
}
static int l_lovrTextureDataGetBlob(lua_State* L) {
TextureData* textureData = luax_checktype(L, 1, TextureData);
Blob* blob = textureData->blob;
static int l_lovrImageGetBlob(lua_State* L) {
Image* image = luax_checktype(L, 1, Image);
Blob* blob = image->blob;
luax_pushtype(L, Blob, blob);
return 1;
}
const luaL_Reg lovrTextureData[] = {
{ "encode", l_lovrTextureDataEncode },
{ "getWidth", l_lovrTextureDataGetWidth },
{ "getHeight", l_lovrTextureDataGetHeight },
{ "getDimensions", l_lovrTextureDataGetDimensions },
{ "getFormat", l_lovrTextureDataGetFormat },
{ "paste", l_lovrTextureDataPaste },
{ "getPixel", l_lovrTextureDataGetPixel },
{ "setPixel", l_lovrTextureDataSetPixel },
{ "getBlob", l_lovrTextureDataGetBlob },
const luaL_Reg lovrImage[] = {
{ "encode", l_lovrImageEncode },
{ "getWidth", l_lovrImageGetWidth },
{ "getHeight", l_lovrImageGetHeight },
{ "getDimensions", l_lovrImageGetDimensions },
{ "getFormat", l_lovrImageGetFormat },
{ "paste", l_lovrImagePaste },
{ "getPixel", l_lovrImageGetPixel },
{ "setPixel", l_lovrImageSetPixel },
{ "getBlob", l_lovrImageGetBlob },
{ NULL, NULL }
};

View File

@ -9,7 +9,7 @@
#include "data/blob.h"
#include "data/modelData.h"
#include "data/rasterizer.h"
#include "data/textureData.h"
#include "data/image.h"
#include "core/os.h"
#include "core/util.h"
#include <math.h>
@ -304,18 +304,18 @@ static void stencilCallback(void* userdata) {
}
// Must be released when done
static TextureData* luax_checktexturedata(lua_State* L, int index, bool flip) {
TextureData* textureData = luax_totype(L, index, TextureData);
static Image* luax_checkimage(lua_State* L, int index, bool flip) {
Image* image = luax_totype(L, index, Image);
if (textureData) {
lovrRetain(textureData);
if (image) {
lovrRetain(image);
} else {
Blob* blob = luax_readblob(L, index, "Texture");
textureData = lovrTextureDataCreateFromBlob(blob, flip);
image = lovrImageCreateFromBlob(blob, flip);
lovrRelease(blob, lovrBlobDestroy);
}
return textureData;
return image;
}
// Base
@ -360,12 +360,12 @@ static int l_lovrGraphicsCreateWindow(lua_State* L) {
lua_pop(L, 1);
lua_getfield(L, 1, "icon");
TextureData* textureData = NULL;
Image* image = NULL;
if (!lua_isnil(L, -1)) {
textureData = luax_checktexturedata(L, -1, false);
flags.icon.data = textureData->blob->data;
flags.icon.width = textureData->width;
flags.icon.height = textureData->height;
image = luax_checkimage(L, -1, false);
flags.icon.data = image->blob->data;
flags.icon.width = image->width;
flags.icon.height = image->height;
}
lua_pop(L, 1);
@ -375,7 +375,7 @@ static int l_lovrGraphicsCreateWindow(lua_State* L) {
lovrGraphicsCreateWindow(&flags);
luax_atexit(L, lovrGraphicsDestroy); // The lua_State that creates the window shall be the one to destroy it
lovrRelease(textureData, lovrTextureDataDestroy);
lovrRelease(image, lovrImageDestroy);
return 0;
}
@ -1262,11 +1262,11 @@ static int l_lovrGraphicsNewMaterial(lua_State* L) {
if (lua_type(L, index) == LUA_TSTRING) {
Blob* blob = luax_readblob(L, index++, "Texture");
TextureData* textureData = lovrTextureDataCreateFromBlob(blob, true);
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, true, 0);
Image* image = lovrImageCreateFromBlob(blob, true);
Texture* texture = lovrTextureCreate(TEXTURE_2D, &image, 1, true, true, 0);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
lovrRelease(blob, lovrBlobDestroy);
lovrRelease(textureData, lovrTextureDataDestroy);
lovrRelease(image, lovrImageDestroy);
lovrRelease(texture, lovrTextureDestroy);
} else if (lua_isuserdata(L, index)) {
Texture* texture = luax_checktype(L, index, Texture);
@ -1710,12 +1710,12 @@ static int l_lovrGraphicsNewTexture(lua_State* L) {
for (int i = 0; i < depth; i++) {
lua_rawgeti(L, 1, i + 1);
TextureData* textureData = luax_checktexturedata(L, -1, type != TEXTURE_CUBE);
Image* image = luax_checkimage(L, -1, type != TEXTURE_CUBE);
if (i == 0) {
lovrTextureAllocate(texture, textureData->width, textureData->height, depth, textureData->format);
lovrTextureAllocate(texture, image->width, image->height, depth, image->format);
}
lovrTextureReplacePixels(texture, textureData, 0, 0, i, 0);
lovrRelease(textureData, lovrTextureDataDestroy);
lovrTextureReplacePixels(texture, image, 0, 0, i, 0);
lovrRelease(image, lovrImageDestroy);
lua_pop(L, 1);
}
}

View File

@ -50,15 +50,15 @@ void luax_readattachments(lua_State* L, int index, Attachment* attachments, int*
}
}
static int l_lovrCanvasNewTextureData(lua_State* L) {
static int l_lovrCanvasNewImage(lua_State* L) {
Canvas* canvas = luax_checktype(L, 1, Canvas);
uint32_t index = luaL_optinteger(L, 2, 1) - 1;
uint32_t count;
lovrCanvasGetAttachments(canvas, &count);
lovrAssert(index < count, "Can not create a TextureData from Texture #%d of Canvas (it only has %d textures)", index, count);
TextureData* textureData = lovrCanvasNewTextureData(canvas, index);
luax_pushtype(L, TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
lovrAssert(index < count, "Can not create an Image from Texture #%d of Canvas (it only has %d textures)", index, count);
Image* image = lovrCanvasNewImage(canvas, index);
luax_pushtype(L, Image, image);
lovrRelease(image, lovrImageDestroy);
return 1;
}
@ -133,7 +133,7 @@ static int l_lovrCanvasIsStereo(lua_State* L) {
}
const luaL_Reg lovrCanvas[] = {
{ "newTextureData", l_lovrCanvasNewTextureData },
{ "newImage", l_lovrCanvasNewImage },
{ "renderTo", l_lovrCanvasRenderTo },
{ "getTexture", l_lovrCanvasGetTexture },
{ "setTexture", l_lovrCanvasSetTexture },

View File

@ -71,13 +71,13 @@ int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* des
}
case UNIFORM_IMAGE: {
Image* image = (Image*) dest + i;
StorageImage* image = (StorageImage*) dest + i;
image->texture = luax_checktype(L, j, Texture);
image->slice = -1;
image->mipmap = 0;
image->access = ACCESS_READ_WRITE;
TextureType type = lovrTextureGetType(image->texture);
lovrAssert(type == uniform->textureType, "Attempt to send %s texture to %s image uniform", lovrTextureType[type], lovrTextureType[uniform->textureType]);
lovrAssert(type == uniform->textureType, "Attempt to send %s texture to %s storage image uniform", lovrTextureType[type], lovrTextureType[uniform->textureType]);
break;
}
@ -256,7 +256,7 @@ static int l_lovrShaderSendImage(lua_State* L) {
int slice = luaL_optinteger(L, index++, 0) - 1; // Default is -1
int mipmap = luax_optmipmap(L, index++, texture);
UniformAccess access = luax_checkenum(L, index++, UniformAccess, "readwrite");
Image image = { .texture = texture, .slice = slice, .mipmap = mipmap, .access = access };
StorageImage image = { .texture = texture, .slice = slice, .mipmap = mipmap, .access = access };
lovrShaderSetImages(shader, name, &image, start, 1);
return 0;
}

View File

@ -83,12 +83,12 @@ static int l_lovrTextureGetWrap(lua_State* L) {
static int l_lovrTextureReplacePixels(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
TextureData* textureData = luax_checktype(L, 2, TextureData);
Image* image = luax_checktype(L, 2, Image);
int x = luaL_optinteger(L, 3, 0);
int y = luaL_optinteger(L, 4, 0);
int slice = luaL_optinteger(L, 5, 1) - 1;
int mipmap = luaL_optinteger(L, 6, 1) - 1;
lovrTextureReplacePixels(texture, textureData, x, y, slice, mipmap);
lovrTextureReplacePixels(texture, image, x, y, slice, mipmap);
return 0;
}

View File

@ -1,4 +1,4 @@
#include "data/textureData.h"
#include "data/image.h"
#include "data/blob.h"
#include "lib/stb/stb_image.h"
#include <stdlib.h>
@ -32,7 +32,7 @@ static size_t getPixelSize(TextureFormat format) {
}
// Modified from ddsparse (https://bitbucket.org/slime73/ddsparse)
static bool parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
static bool parseDDS(uint8_t* data, size_t size, Image* image) {
enum {
DDPF_ALPHAPIXELS = 0x000001,
DDPF_ALPHA = 0x000002,
@ -255,17 +255,17 @@ static bool parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
case DXGI_FORMAT_BC1_TYPELESS:
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC1_UNORM_SRGB:
textureData->format = FORMAT_DXT1;
image->format = FORMAT_DXT1;
break;
case DXGI_FORMAT_BC2_TYPELESS:
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC2_UNORM_SRGB:
textureData->format = FORMAT_DXT3;
image->format = FORMAT_DXT3;
break;
case DXGI_FORMAT_BC3_TYPELESS:
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC3_UNORM_SRGB:
textureData->format = FORMAT_DXT5;
image->format = FORMAT_DXT5;
break;
default:
return 1;
@ -277,20 +277,20 @@ static bool parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
// Ensure DXT 1/3/5
switch (header->format.fourCC) {
case FOUR_CC('D', 'X', 'T', '1'): textureData->format = FORMAT_DXT1; break;
case FOUR_CC('D', 'X', 'T', '3'): textureData->format = FORMAT_DXT3; break;
case FOUR_CC('D', 'X', 'T', '5'): textureData->format = FORMAT_DXT5; break;
case FOUR_CC('D', 'X', 'T', '1'): image->format = FORMAT_DXT1; break;
case FOUR_CC('D', 'X', 'T', '3'): image->format = FORMAT_DXT3; break;
case FOUR_CC('D', 'X', 'T', '5'): image->format = FORMAT_DXT5; break;
default: return false;
}
}
uint32_t width = textureData->width = header->width;
uint32_t height = textureData->height = header->height;
uint32_t mipmapCount = textureData->mipmapCount = MAX(header->mipMapCount, 1);
textureData->mipmaps = malloc(mipmapCount * sizeof(Mipmap));
uint32_t width = image->width = header->width;
uint32_t height = image->height = header->height;
uint32_t mipmapCount = image->mipmapCount = MAX(header->mipMapCount, 1);
image->mipmaps = malloc(mipmapCount * sizeof(Mipmap));
size_t blockBytes = 0;
switch (textureData->format) {
switch (image->format) {
case FORMAT_DXT1: blockBytes = 8; break;
case FORMAT_DXT3: blockBytes = 16; break;
case FORMAT_DXT5: blockBytes = 16; break;
@ -305,22 +305,22 @@ static bool parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
// Overflow check
if (mipmapSize == 0 || (offset + mipmapSize) > size) {
free(textureData->mipmaps);
free(image->mipmaps);
return false;
}
textureData->mipmaps[i] = (Mipmap) { .width = width, .height = height, .data = &data[offset], .size = mipmapSize };
image->mipmaps[i] = (Mipmap) { .width = width, .height = height, .data = &data[offset], .size = mipmapSize };
offset += mipmapSize;
width = MAX(width >> 1, 1);
height = MAX(height >> 1, 1);
}
textureData->blob->data = NULL;
image->blob->data = NULL;
return true;
}
static bool parseKTX(uint8_t* bytes, size_t size, TextureData* textureData) {
static bool parseKTX(uint8_t* bytes, size_t size, Image* image) {
typedef struct {
uint8_t magic[12];
uint32_t endianness;
@ -356,34 +356,34 @@ static bool parseKTX(uint8_t* bytes, size_t size, TextureData* textureData) {
// TODO MOAR FORMATS, GIMME COOOBMAPS
switch (data.ktx->glInternalFormat) {
case 0x83F0: textureData->format = FORMAT_DXT1; break;
case 0x83F2: textureData->format = FORMAT_DXT3; break;
case 0x83F3: textureData->format = FORMAT_DXT5; break;
case 0x93B0: case 0x93D0: textureData->format = FORMAT_ASTC_4x4; break;
case 0x93B1: case 0x93D1: textureData->format = FORMAT_ASTC_5x4; break;
case 0x93B2: case 0x93D2: textureData->format = FORMAT_ASTC_5x5; break;
case 0x93B3: case 0x93D3: textureData->format = FORMAT_ASTC_6x5; break;
case 0x93B4: case 0x93D4: textureData->format = FORMAT_ASTC_6x6; break;
case 0x93B5: case 0x93D5: textureData->format = FORMAT_ASTC_8x5; break;
case 0x93B6: case 0x93D6: textureData->format = FORMAT_ASTC_8x6; break;
case 0x93B7: case 0x93D7: textureData->format = FORMAT_ASTC_8x8; break;
case 0x93B8: case 0x93D8: textureData->format = FORMAT_ASTC_10x5; break;
case 0x93B9: case 0x93D9: textureData->format = FORMAT_ASTC_10x6; break;
case 0x93BA: case 0x93DA: textureData->format = FORMAT_ASTC_10x8; break;
case 0x93BB: case 0x93DB: textureData->format = FORMAT_ASTC_10x10; break;
case 0x93BC: case 0x93DC: textureData->format = FORMAT_ASTC_12x10; break;
case 0x93BD: case 0x93DD: textureData->format = FORMAT_ASTC_12x12; break;
case 0x83F0: image->format = FORMAT_DXT1; break;
case 0x83F2: image->format = FORMAT_DXT3; break;
case 0x83F3: image->format = FORMAT_DXT5; break;
case 0x93B0: case 0x93D0: image->format = FORMAT_ASTC_4x4; break;
case 0x93B1: case 0x93D1: image->format = FORMAT_ASTC_5x4; break;
case 0x93B2: case 0x93D2: image->format = FORMAT_ASTC_5x5; break;
case 0x93B3: case 0x93D3: image->format = FORMAT_ASTC_6x5; break;
case 0x93B4: case 0x93D4: image->format = FORMAT_ASTC_6x6; break;
case 0x93B5: case 0x93D5: image->format = FORMAT_ASTC_8x5; break;
case 0x93B6: case 0x93D6: image->format = FORMAT_ASTC_8x6; break;
case 0x93B7: case 0x93D7: image->format = FORMAT_ASTC_8x8; break;
case 0x93B8: case 0x93D8: image->format = FORMAT_ASTC_10x5; break;
case 0x93B9: case 0x93D9: image->format = FORMAT_ASTC_10x6; break;
case 0x93BA: case 0x93DA: image->format = FORMAT_ASTC_10x8; break;
case 0x93BB: case 0x93DB: image->format = FORMAT_ASTC_10x10; break;
case 0x93BC: case 0x93DC: image->format = FORMAT_ASTC_12x10; break;
case 0x93BD: case 0x93DD: image->format = FORMAT_ASTC_12x12; break;
default: lovrThrow("Unsupported KTX format '%d' (please open an issue)", data.ktx->glInternalFormat);
}
uint32_t width = textureData->width = data.ktx->pixelWidth;
uint32_t height = textureData->height = data.ktx->pixelHeight;
uint32_t mipmapCount = textureData->mipmapCount = data.ktx->numberOfMipmapLevels;
textureData->mipmaps = malloc(mipmapCount * sizeof(Mipmap));
uint32_t width = image->width = data.ktx->pixelWidth;
uint32_t height = image->height = data.ktx->pixelHeight;
uint32_t mipmapCount = image->mipmapCount = data.ktx->numberOfMipmapLevels;
image->mipmaps = malloc(mipmapCount * sizeof(Mipmap));
data.u8 += sizeof(KTXHeader) + data.ktx->bytesOfKeyValueData;
for (uint32_t i = 0; i < mipmapCount; i++) {
textureData->mipmaps[i] = (Mipmap) { .width = width, .height = height, .data = data.u8 + sizeof(uint32_t), .size = *data.u32 };
image->mipmaps[i] = (Mipmap) { .width = width, .height = height, .data = data.u8 + sizeof(uint32_t), .size = *data.u32 };
width = MAX(width >> 1, 1u);
height = MAX(height >> 1, 1u);
data.u8 = (uint8_t*) ALIGN(data.u8 + sizeof(uint32_t) + *data.u32, 4);
@ -392,7 +392,7 @@ static bool parseKTX(uint8_t* bytes, size_t size, TextureData* textureData) {
return true;
}
static bool parseASTC(uint8_t* bytes, size_t size, TextureData* textureData) {
static bool parseASTC(uint8_t* bytes, size_t size, Image* image) {
typedef struct {
uint32_t magic;
uint8_t blockX;
@ -416,36 +416,36 @@ static bool parseASTC(uint8_t* bytes, size_t size, TextureData* textureData) {
}
uint32_t bx = data.astc->blockX, by = data.astc->blockY, bz = data.astc->blockZ;
if (bx == 4 && by == 4 && bz == 1) { textureData->format = FORMAT_ASTC_4x4; }
else if (bx == 5 && by == 4 && bz == 1) { textureData->format = FORMAT_ASTC_5x4; }
else if (bx == 5 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_5x5; }
else if (bx == 6 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_6x5; }
else if (bx == 6 && by == 6 && bz == 1) { textureData->format = FORMAT_ASTC_6x6; }
else if (bx == 8 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_8x5; }
else if (bx == 8 && by == 6 && bz == 1) { textureData->format = FORMAT_ASTC_8x6; }
else if (bx == 8 && by == 8 && bz == 1) { textureData->format = FORMAT_ASTC_8x8; }
else if (bx == 10 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_10x5; }
else if (bx == 10 && by == 6 && bz == 1) { textureData->format = FORMAT_ASTC_10x6; }
else if (bx == 10 && by == 8 && bz == 1) { textureData->format = FORMAT_ASTC_10x8; }
else if (bx == 10 && by == 10 && bz == 1) { textureData->format = FORMAT_ASTC_10x10; }
else if (bx == 12 && by == 10 && bz == 1) { textureData->format = FORMAT_ASTC_12x10; }
else if (bx == 12 && by == 12 && bz == 1) { textureData->format = FORMAT_ASTC_12x12; }
if (bx == 4 && by == 4 && bz == 1) { image->format = FORMAT_ASTC_4x4; }
else if (bx == 5 && by == 4 && bz == 1) { image->format = FORMAT_ASTC_5x4; }
else if (bx == 5 && by == 5 && bz == 1) { image->format = FORMAT_ASTC_5x5; }
else if (bx == 6 && by == 5 && bz == 1) { image->format = FORMAT_ASTC_6x5; }
else if (bx == 6 && by == 6 && bz == 1) { image->format = FORMAT_ASTC_6x6; }
else if (bx == 8 && by == 5 && bz == 1) { image->format = FORMAT_ASTC_8x5; }
else if (bx == 8 && by == 6 && bz == 1) { image->format = FORMAT_ASTC_8x6; }
else if (bx == 8 && by == 8 && bz == 1) { image->format = FORMAT_ASTC_8x8; }
else if (bx == 10 && by == 5 && bz == 1) { image->format = FORMAT_ASTC_10x5; }
else if (bx == 10 && by == 6 && bz == 1) { image->format = FORMAT_ASTC_10x6; }
else if (bx == 10 && by == 8 && bz == 1) { image->format = FORMAT_ASTC_10x8; }
else if (bx == 10 && by == 10 && bz == 1) { image->format = FORMAT_ASTC_10x10; }
else if (bx == 12 && by == 10 && bz == 1) { image->format = FORMAT_ASTC_12x10; }
else if (bx == 12 && by == 12 && bz == 1) { image->format = FORMAT_ASTC_12x12; }
else { lovrThrow("Unsupported ASTC format %dx%dx%d", bx, by, bz); }
textureData->width = data.astc->width[0] + (data.astc->width[1] << 8) + (data.astc->width[2] << 16);
textureData->height = data.astc->height[0] + (data.astc->height[1] << 8) + (data.astc->height[2] << 16);
image->width = data.astc->width[0] + (data.astc->width[1] << 8) + (data.astc->width[2] << 16);
image->height = data.astc->height[0] + (data.astc->height[1] << 8) + (data.astc->height[2] << 16);
size_t imageSize = ((textureData->width + bx - 1) / bx) * ((textureData->height + by - 1) / by) * (128 / 8);
size_t imageSize = ((image->width + bx - 1) / bx) * ((image->height + by - 1) / by) * (128 / 8);
if (imageSize > size - sizeof(ASTCHeader)) {
return false;
}
textureData->mipmapCount = 1;
textureData->mipmaps = malloc(sizeof(Mipmap));
textureData->mipmaps[0] = (Mipmap) {
.width = textureData->width,
.height = textureData->height,
image->mipmapCount = 1;
image->mipmaps = malloc(sizeof(Mipmap));
image->mipmaps[0] = (Mipmap) {
.width = image->width,
.height = image->height,
.data = data.u8 + sizeof(ASTCHeader),
.size = imageSize
};
@ -453,18 +453,18 @@ static bool parseASTC(uint8_t* bytes, size_t size, TextureData* textureData) {
return true;
}
TextureData* lovrTextureDataCreate(uint32_t width, uint32_t height, Blob* contents, uint8_t value, TextureFormat format) {
TextureData* textureData = calloc(1, sizeof(TextureData));
lovrAssert(textureData, "Out of memory");
textureData->ref = 1;
Image* lovrImageCreate(uint32_t width, uint32_t height, Blob* contents, uint8_t value, TextureFormat format) {
Image* image = calloc(1, sizeof(Image));
lovrAssert(image, "Out of memory");
image->ref = 1;
size_t pixelSize = getPixelSize(format);
size_t size = width * height * pixelSize;
lovrAssert(width > 0 && height > 0, "TextureData dimensions must be positive");
lovrAssert(format < FORMAT_DXT1, "Blank TextureData cannot be compressed");
lovrAssert(!contents || contents->size >= size, "TextureData Blob is too small (%d bytes needed, got %d)", size, contents->size);
textureData->width = width;
textureData->height = height;
textureData->format = format;
lovrAssert(width > 0 && height > 0, "Image dimensions must be positive");
lovrAssert(format < FORMAT_DXT1, "Blank images cannot be compressed");
lovrAssert(!contents || contents->size >= size, "Image Blob is too small (%d bytes needed, got %d)", size, contents->size);
image->width = width;
image->height = height;
image->format = format;
void* data = malloc(size);
lovrAssert(data, "Out of memory");
if (contents) {
@ -472,27 +472,27 @@ TextureData* lovrTextureDataCreate(uint32_t width, uint32_t height, Blob* conten
} else {
memset(data, value, size);
}
textureData->blob = lovrBlobCreate(data, size, "TextureData plain");
return textureData;
image->blob = lovrBlobCreate(data, size, "Image");
return image;
}
TextureData* lovrTextureDataCreateFromBlob(Blob* blob, bool flip) {
TextureData* textureData = calloc(1, sizeof(TextureData));
lovrAssert(textureData, "Out of memory");
textureData->ref = 1;
textureData->blob = lovrBlobCreate(NULL, 0, NULL);
if (parseDDS(blob->data, blob->size, textureData)) {
textureData->source = blob;
Image* lovrImageCreateFromBlob(Blob* blob, bool flip) {
Image* image = calloc(1, sizeof(Image));
lovrAssert(image, "Out of memory");
image->ref = 1;
image->blob = lovrBlobCreate(NULL, 0, NULL);
if (parseDDS(blob->data, blob->size, image)) {
image->source = blob;
lovrRetain(blob);
return textureData;
} else if (parseKTX(blob->data, blob->size, textureData)) {
textureData->source = blob;
return image;
} else if (parseKTX(blob->data, blob->size, image)) {
image->source = blob;
lovrRetain(blob);
return textureData;
} else if (parseASTC(blob->data, blob->size, textureData)) {
textureData->source = blob;
return image;
} else if (parseASTC(blob->data, blob->size, image)) {
image->source = blob;
lovrRetain(blob);
return textureData;
return image;
}
int width, height;
@ -500,71 +500,79 @@ TextureData* lovrTextureDataCreateFromBlob(Blob* blob, bool flip) {
stbi_set_flip_vertically_on_load_thread(flip);
if (stbi_is_16_bit_from_memory(blob->data, length)) {
int channels;
textureData->blob->data = stbi_load_16_from_memory(blob->data, length, &width, &height, &channels, 0);
image->blob->data = stbi_load_16_from_memory(blob->data, length, &width, &height, &channels, 0);
switch (channels) {
case 1:
textureData->format = FORMAT_R16;
textureData->blob->size = 2 * width * height;
image->format = FORMAT_R16;
image->blob->size = 2 * width * height;
break;
case 2:
textureData->format = FORMAT_RG16;
textureData->blob->size = 4 * width * height;
image->format = FORMAT_RG16;
image->blob->size = 4 * width * height;
break;
case 4:
textureData->format = FORMAT_RGBA16;
textureData->blob->size = 8 * width * height;
image->format = FORMAT_RGBA16;
image->blob->size = 8 * width * height;
break;
default:
lovrThrow("Unsupported channel count for 16 bit image: %d", channels);
}
} else if (stbi_is_hdr_from_memory(blob->data, length)) {
textureData->format = FORMAT_RGBA32F;
textureData->blob->data = stbi_loadf_from_memory(blob->data, length, &width, &height, NULL, 4);
textureData->blob->size = 16 * width * height;
image->format = FORMAT_RGBA32F;
image->blob->data = stbi_loadf_from_memory(blob->data, length, &width, &height, NULL, 4);
image->blob->size = 16 * width * height;
} else {
textureData->format = FORMAT_RGBA;
textureData->blob->data = stbi_load_from_memory(blob->data, length, &width, &height, NULL, 4);
textureData->blob->size = 4 * width * height;
image->format = FORMAT_RGBA;
image->blob->data = stbi_load_from_memory(blob->data, length, &width, &height, NULL, 4);
image->blob->size = 4 * width * height;
}
if (!textureData->blob->data) {
lovrThrow("Could not load texture data from '%s'", blob->name);
lovrRelease(textureData->blob, lovrBlobDestroy);
free(textureData);
if (!image->blob->data) {
lovrThrow("Could not load image from '%s'", blob->name);
lovrRelease(image->blob, lovrBlobDestroy);
free(image);
return NULL;
}
textureData->width = width;
textureData->height = height;
textureData->mipmapCount = 0;
return textureData;
image->width = width;
image->height = height;
image->mipmapCount = 0;
return image;
}
Color lovrTextureDataGetPixel(TextureData* textureData, uint32_t x, uint32_t y) {
lovrAssert(textureData->blob->data, "TextureData does not have any pixel data");
lovrAssert(x < textureData->width && y < textureData->height, "getPixel coordinates must be within TextureData bounds");
size_t index = (textureData->height - (y + 1)) * textureData->width + x;
size_t pixelSize = getPixelSize(textureData->format);
uint8_t* u8 = (uint8_t*) textureData->blob->data + pixelSize * index;
void lovrImageDestroy(void* ref) {
Image* image = ref;
lovrRelease(image->source, lovrBlobDestroy);
free(image->mipmaps);
lovrRelease(image->blob, lovrBlobDestroy);
free(image);
}
Color lovrImageGetPixel(Image* image, uint32_t x, uint32_t y) {
lovrAssert(image->blob->data, "Image does not have any pixel data");
lovrAssert(x < image->width && y < image->height, "getPixel coordinates must be within Image bounds");
size_t index = (image->height - (y + 1)) * image->width + x;
size_t pixelSize = getPixelSize(image->format);
uint8_t* u8 = (uint8_t*) image->blob->data + pixelSize * index;
float* f32 = (float*) u8;
switch (textureData->format) {
switch (image->format) {
case FORMAT_RGB: return (Color) { u8[0] / 255.f, u8[1] / 255.f, u8[2] / 255.f, 1.f };
case FORMAT_RGBA: return (Color) { u8[0] / 255.f, u8[1] / 255.f, u8[2] / 255.f, u8[3] / 255.f };
case FORMAT_RGBA32F: return (Color) { f32[0], f32[1], f32[2], f32[3] };
case FORMAT_R32F: return (Color) { f32[0], 1.f, 1.f, 1.f };
case FORMAT_RG32F: return (Color) { f32[0], f32[1], 1.f, 1.f };
default: lovrThrow("Unsupported format for TextureData:getPixel");
default: lovrThrow("Unsupported format for Image:getPixel");
}
}
void lovrTextureDataSetPixel(TextureData* textureData, uint32_t x, uint32_t y, Color color) {
lovrAssert(textureData->blob->data, "TextureData does not have any pixel data");
lovrAssert(x < textureData->width && y < textureData->height, "setPixel coordinates must be within TextureData bounds");
size_t index = (textureData->height - (y + 1)) * textureData->width + x;
size_t pixelSize = getPixelSize(textureData->format);
uint8_t* u8 = (uint8_t*) textureData->blob->data + pixelSize * index;
void lovrImageSetPixel(Image* image, uint32_t x, uint32_t y, Color color) {
lovrAssert(image->blob->data, "Image does not have any pixel data");
lovrAssert(x < image->width && y < image->height, "setPixel coordinates must be within Image bounds");
size_t index = (image->height - (y + 1)) * image->width + x;
size_t pixelSize = getPixelSize(image->format);
uint8_t* u8 = (uint8_t*) image->blob->data + pixelSize * index;
float* f32 = (float*) u8;
switch (textureData->format) {
switch (image->format) {
case FORMAT_RGB:
u8[0] = (uint8_t) (color.r * 255.f + .5f);
u8[1] = (uint8_t) (color.g * 255.f + .5f);
@ -594,7 +602,7 @@ void lovrTextureDataSetPixel(TextureData* textureData, uint32_t x, uint32_t y, C
f32[1] = color.g;
break;
default: lovrThrow("Unsupported format for TextureData:setPixel");
default: lovrThrow("Unsupported format for Image:setPixel");
}
}
@ -623,11 +631,11 @@ static uint32_t crc32(uint8_t* data, size_t length) {
return c ^ 0xffffffff;
}
Blob* lovrTextureDataEncode(TextureData* textureData) {
lovrAssert(textureData->format == FORMAT_RGBA, "Only RGBA TextureData can be encoded");
uint32_t w = textureData->width;
uint32_t h = textureData->height;
uint8_t* pixels = (uint8_t*) textureData->blob->data + (h - 1) * w * 4;
Blob* lovrImageEncode(Image* image) {
lovrAssert(image->format == FORMAT_RGBA, "Only RGBA Image can be encoded");
uint32_t w = image->width;
uint32_t h = image->height;
uint8_t* pixels = (uint8_t*) image->blob->data + (h - 1) * w * 4;
int32_t stride = -1 * (int) (w * 4);
// The world's worst png encoder
@ -732,28 +740,20 @@ Blob* lovrTextureDataEncode(TextureData* textureData) {
memcpy(data + 8, (uint8_t[4]) { crc >> 24, crc >> 16, crc >> 8, crc >> 0 }, 4);
data += 8 + 4;
return lovrBlobCreate(data - size, size, "Encoded TextureData");
return lovrBlobCreate(data - size, size, "Encoded Image");
}
void lovrTextureDataPaste(TextureData* textureData, TextureData* source, uint32_t dx, uint32_t dy, uint32_t sx, uint32_t sy, uint32_t w, uint32_t h) {
lovrAssert(textureData->format == source->format, "Currently TextureData must have the same format to paste");
lovrAssert(textureData->format < FORMAT_DXT1, "Compressed TextureData cannot be pasted");
size_t pixelSize = getPixelSize(textureData->format);
lovrAssert(dx + w <= textureData->width && dy + h <= textureData->height, "Attempt to paste outside of destination TextureData bounds");
lovrAssert(sx + w <= source->width && sy + h <= source->height, "Attempt to paste from outside of source TextureData bounds");
void lovrImagePaste(Image* image, Image* source, uint32_t dx, uint32_t dy, uint32_t sx, uint32_t sy, uint32_t w, uint32_t h) {
lovrAssert(image->format == source->format, "Currently Image must have the same format to paste");
lovrAssert(image->format < FORMAT_DXT1, "Compressed Image cannot be pasted");
size_t pixelSize = getPixelSize(image->format);
lovrAssert(dx + w <= image->width && dy + h <= image->height, "Attempt to paste outside of destination Image bounds");
lovrAssert(sx + w <= source->width && sy + h <= source->height, "Attempt to paste from outside of source Image bounds");
uint8_t* src = (uint8_t*) source->blob->data + ((source->height - 1 - sy) * source->width + sx) * pixelSize;
uint8_t* dst = (uint8_t*) textureData->blob->data + ((textureData->height - 1 - dy) * textureData->width + sx) * pixelSize;
uint8_t* dst = (uint8_t*) image->blob->data + ((image->height - 1 - dy) * image->width + sx) * pixelSize;
for (uint32_t y = 0; y < h; y++) {
memcpy(dst, src, w * pixelSize);
src -= source->width * pixelSize;
dst -= textureData->width * pixelSize;
dst -= image->width * pixelSize;
}
}
void lovrTextureDataDestroy(void* ref) {
TextureData* textureData = ref;
lovrRelease(textureData->source, lovrBlobDestroy);
free(textureData->mipmaps);
lovrRelease(textureData->blob, lovrBlobDestroy);
free(textureData);
}

View File

@ -51,7 +51,7 @@ typedef struct {
void* data;
} Mipmap;
typedef struct TextureData {
typedef struct Image {
ref_t ref;
struct Blob* blob;
uint32_t width;
@ -60,12 +60,12 @@ typedef struct TextureData {
TextureFormat format;
Mipmap* mipmaps;
uint32_t mipmapCount;
} TextureData;
} Image;
TextureData* lovrTextureDataCreate(uint32_t width, uint32_t height, struct Blob* contents, uint8_t value, TextureFormat format);
TextureData* lovrTextureDataCreateFromBlob(struct Blob* blob, bool flip);
Color lovrTextureDataGetPixel(TextureData* textureData, uint32_t x, uint32_t y);
void lovrTextureDataSetPixel(TextureData* textureData, uint32_t x, uint32_t y, Color color);
struct Blob* lovrTextureDataEncode(TextureData* textureData);
void lovrTextureDataPaste(TextureData* textureData, TextureData* source, uint32_t dx, uint32_t dy, uint32_t sx, uint32_t sy, uint32_t w, uint32_t h);
void lovrTextureDataDestroy(void* ref);
Image* lovrImageCreate(uint32_t width, uint32_t height, struct Blob* contents, uint8_t value, TextureFormat format);
Image* lovrImageCreateFromBlob(struct Blob* blob, bool flip);
void lovrImageDestroy(void* ref);
Color lovrImageGetPixel(Image* image, uint32_t x, uint32_t y);
void lovrImageSetPixel(Image* image, uint32_t x, uint32_t y, Color color);
struct Blob* lovrImageEncode(Image* image);
void lovrImagePaste(Image* image, Image* source, uint32_t dx, uint32_t dy, uint32_t sx, uint32_t sy, uint32_t w, uint32_t h);

View File

@ -1,6 +1,6 @@
#include "data/modelData.h"
#include "data/blob.h"
#include "data/textureData.h"
#include "data/image.h"
#include <stdlib.h>
ModelData* lovrModelDataCreate(Blob* source, ModelDataIO* io) {
@ -23,8 +23,8 @@ void lovrModelDataDestroy(void* ref) {
for (uint32_t i = 0; i < model->blobCount; i++) {
lovrRelease(model->blobs[i], lovrBlobDestroy);
}
for (uint32_t i = 0; i < model->textureCount; i++) {
lovrRelease(model->textures[i], lovrTextureDataDestroy);
for (uint32_t i = 0; i < model->imageCount; i++) {
lovrRelease(model->images[i], lovrImageDestroy);
}
map_free(&model->animationMap);
map_free(&model->materialMap);
@ -40,7 +40,7 @@ void lovrModelDataAllocate(ModelData* model) {
size_t alignment = 8;
totalSize += sizes[0] = ALIGN(model->blobCount * sizeof(Blob*), alignment);
totalSize += sizes[1] = ALIGN(model->bufferCount * sizeof(ModelBuffer), alignment);
totalSize += sizes[2] = ALIGN(model->textureCount * sizeof(TextureData*), alignment);
totalSize += sizes[2] = ALIGN(model->imageCount * sizeof(Image*), alignment);
totalSize += sizes[3] = ALIGN(model->materialCount * sizeof(ModelMaterial), alignment);
totalSize += sizes[4] = ALIGN(model->attributeCount * sizeof(ModelAttribute), alignment);
totalSize += sizes[5] = ALIGN(model->primitiveCount * sizeof(ModelPrimitive), alignment);
@ -57,7 +57,7 @@ void lovrModelDataAllocate(ModelData* model) {
lovrAssert(model->data, "Out of memory");
model->blobs = (Blob**) (p + offset), offset += sizes[0];
model->buffers = (ModelBuffer*) (p + offset), offset += sizes[1];
model->textures = (TextureData**) (p + offset), offset += sizes[2];
model->images = (Image**) (p + offset), offset += sizes[2];
model->materials = (ModelMaterial*) (p + offset), offset += sizes[3];
model->attributes = (ModelAttribute*) (p + offset), offset += sizes[4];
model->primitives = (ModelPrimitive*) (p + offset), offset += sizes[5];

View File

@ -8,8 +8,8 @@
#define MAX_BONES 48
struct TextureData;
struct Blob;
struct Image;
typedef enum {
ATTR_POSITION,
@ -142,7 +142,7 @@ typedef struct {
const char* name;
float scalars[MAX_MATERIAL_SCALARS];
Color colors[MAX_MATERIAL_COLORS];
uint32_t textures[MAX_MATERIAL_TEXTURES];
uint32_t images[MAX_MATERIAL_TEXTURES];
TextureFilter filters[MAX_MATERIAL_TEXTURES];
TextureWrap wraps[MAX_MATERIAL_TEXTURES];
} ModelMaterial;
@ -183,7 +183,7 @@ typedef struct ModelData {
void* data;
struct Blob** blobs;
ModelBuffer* buffers;
struct TextureData** textures;
struct Image** images;
ModelMaterial* materials;
ModelAttribute* attributes;
ModelPrimitive* primitives;
@ -194,7 +194,7 @@ typedef struct ModelData {
uint32_t blobCount;
uint32_t bufferCount;
uint32_t textureCount;
uint32_t imageCount;
uint32_t materialCount;
uint32_t attributeCount;
uint32_t primitiveCount;

View File

@ -1,6 +1,6 @@
#include "data/modelData.h"
#include "data/blob.h"
#include "data/textureData.h"
#include "data/image.h"
#include "core/maf.h"
#include "lib/jsmn/jsmn.h"
#include <stdbool.h>
@ -133,7 +133,7 @@ static jsmntok_t* resolveTexture(const char* json, jsmntok_t* token, ModelMateri
uint32_t index = NOM_INT(json, token);
gltfTexture* texture = &textures[index];
gltfSampler* sampler = texture->sampler == ~0u ? NULL : &samplers[texture->sampler];
material->textures[textureType] = texture->image;
material->images[textureType] = texture->image;
material->filters[textureType] = sampler ? sampler->filter : (TextureFilter) { .mode = FILTER_BILINEAR };
material->wraps[textureType] = sampler ? sampler->wrap : (TextureWrap) { .s = WRAP_REPEAT, .t = WRAP_REPEAT, .r = WRAP_REPEAT };
} else if (STR_EQ(key, "texCoord")) {
@ -303,7 +303,7 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
} else if (STR_EQ(key, "images")) {
info.images = token;
model->textureCount = token->size;
model->imageCount = token->size;
token += NOM_VALUE(json, token);
} else if (STR_EQ(key, "samplers")) {
@ -649,17 +649,17 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
}
}
// Textures (glTF images)
if (model->textureCount > 0) {
// Images
if (model->imageCount > 0) {
jsmntok_t* token = info.images;
TextureData** texture = model->textures;
for (int i = (token++)->size; i > 0; i--, texture++) {
Image** image = model->images;
for (int i = (token++)->size; i > 0; i--, image++) {
for (int k = (token++)->size; k > 0; k--) {
gltfString key = NOM_STR(json, token);
if (STR_EQ(key, "bufferView")) {
ModelBuffer* buffer = &model->buffers[NOM_INT(json, token)];
Blob* blob = lovrBlobCreate(buffer->data, buffer->size, NULL);
*texture = lovrTextureDataCreateFromBlob(blob, false);
*image = lovrImageCreateFromBlob(blob, false);
blob->data = NULL; // XXX Blob data ownership
lovrRelease(blob, lovrBlobDestroy);
} else if (STR_EQ(key, "uri")) {
@ -669,9 +669,9 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
lovrAssert(uri.length < maxPathLength, "Image filename is too long");
strncat(filename, uri.data, uri.length);
void* data = io(filename, &size);
lovrAssert(data && size > 0, "Unable to read texture from '%s'", filename);
lovrAssert(data && size > 0, "Unable to read image from '%s'", filename);
Blob* blob = lovrBlobCreate(data, size, NULL);
*texture = lovrTextureDataCreateFromBlob(blob, false);
*image = lovrImageCreateFromBlob(blob, false);
lovrRelease(blob, lovrBlobDestroy);
*root = '\0';
} else {
@ -690,7 +690,7 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
material->scalars[SCALAR_ROUGHNESS] = 1.f;
material->colors[COLOR_DIFFUSE] = (Color) { 1.f, 1.f, 1.f, 1.f };
material->colors[COLOR_EMISSIVE] = (Color) { 0.f, 0.f, 0.f, 0.f };
memset(material->textures, 0xff, MAX_MATERIAL_TEXTURES * sizeof(uint32_t));
memset(material->images, 0xff, MAX_MATERIAL_TEXTURES * sizeof(uint32_t));
for (int k = (token++)->size; k > 0; k--) {
gltfString key = NOM_STR(json, token);
@ -711,7 +711,7 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
material->scalars[SCALAR_ROUGHNESS] = NOM_FLOAT(json, token);
} else if (STR_EQ(key, "metallicRoughnessTexture")) {
token = resolveTexture(json, token, material, TEXTURE_METALNESS, textures, samplers);
material->textures[TEXTURE_ROUGHNESS] = material->textures[TEXTURE_METALNESS];
material->images[TEXTURE_ROUGHNESS] = material->images[TEXTURE_METALNESS];
material->filters[TEXTURE_ROUGHNESS] = material->filters[TEXTURE_METALNESS];
material->wraps[TEXTURE_ROUGHNESS] = material->wraps[TEXTURE_METALNESS];
} else {

View File

@ -1,6 +1,6 @@
#include "data/modelData.h"
#include "data/blob.h"
#include "data/textureData.h"
#include "data/image.h"
#include "core/maf.h"
#include "core/map.h"
#include "core/util.h"
@ -15,7 +15,7 @@ typedef struct {
} objGroup;
typedef arr_t(ModelMaterial) arr_material_t;
typedef arr_t(TextureData*) arr_texturedata_t;
typedef arr_t(Image*) arr_image_t;
typedef arr_t(objGroup) arr_group_t;
#define STARTS_WITH(a, b) !strncmp(a, b, strlen(b))
@ -27,7 +27,7 @@ static uint32_t nomu32(char* s, char** end) {
return n;
}
static void parseMtl(char* path, char* base, ModelDataIO* io, arr_texturedata_t* textures, arr_material_t* materials, map_t* names) {
static void parseMtl(char* path, char* base, ModelDataIO* io, arr_image_t* images, arr_material_t* materials, map_t* names) {
size_t size = 0;
char* p = io(path, &size);
lovrAssert(p && size > 0, "Unable to read mtl from '%s'", path);
@ -53,7 +53,7 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_texturedata_t*
.colors[COLOR_DIFFUSE] = { 1.f, 1.f, 1.f, 1.f },
.colors[COLOR_EMISSIVE] = { 0.f, 0.f, 0.f, 0.f }
}));
memset(&materials->data[materials->length - 1].textures, 0xff, MAX_MATERIAL_TEXTURES * sizeof(int));
memset(&materials->data[materials->length - 1].images, 0xff, MAX_MATERIAL_TEXTURES * sizeof(int));
} else if (line[0] == 'K' && line[1] == 'd' && line[2] == ' ') {
float r, g, b;
char* s = line + 3;
@ -63,22 +63,22 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_texturedata_t*
ModelMaterial* material = &materials->data[materials->length - 1];
material->colors[COLOR_DIFFUSE] = (Color) { r, g, b, 1.f };
} else if (STARTS_WITH(line, "map_Kd ")) {
lovrAssert(base - path + (length - 7) < 1024, "Bad OBJ: Material texture filename is too long");
lovrAssert(base - path + (length - 7) < 1024, "Bad OBJ: Material image filename is too long");
memcpy(base, line + 7, length - 7);
base[length - 7] = '\0';
size_t imageSize = 0;
void* image = io(path, &imageSize);
lovrAssert(image && imageSize > 0, "Unable to read texture from %s", path);
Blob* blob = lovrBlobCreate(image, imageSize, NULL);
void* pixels = io(path, &imageSize);
lovrAssert(pixels && imageSize > 0, "Unable to read image from %s", path);
Blob* blob = lovrBlobCreate(pixels, imageSize, NULL);
TextureData* texture = lovrTextureDataCreateFromBlob(blob, true);
Image* image = lovrImageCreateFromBlob(blob, true);
lovrAssert(materials->length > 0, "Tried to set a material property without declaring a material first");
ModelMaterial* material = &materials->data[materials->length - 1];
material->textures[TEXTURE_DIFFUSE] = (uint32_t) textures->length;
material->images[TEXTURE_DIFFUSE] = (uint32_t) images->length;
material->filters[TEXTURE_DIFFUSE].mode = FILTER_TRILINEAR;
material->wraps[TEXTURE_DIFFUSE] = (TextureWrap) { .s = WRAP_REPEAT, .t = WRAP_REPEAT };
arr_push(textures, texture);
arr_push(images, image);
lovrRelease(blob, lovrBlobDestroy);
}
@ -96,7 +96,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source, ModelDataIO* io)
size_t size = source->size;
arr_group_t groups;
arr_texturedata_t textures;
arr_image_t images;
arr_material_t materials;
arr_t(float) vertexBlob;
arr_t(int) indexBlob;
@ -107,7 +107,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source, ModelDataIO* io)
arr_t(float) uvs;
arr_init(&groups, realloc);
arr_init(&textures, realloc);
arr_init(&images, realloc);
arr_init(&materials, realloc);
map_init(&materialMap, 0);
arr_init(&vertexBlob, realloc);
@ -215,7 +215,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source, ModelDataIO* io)
lovrAssert(baseLength + filenameLength < sizeof(path), "Bad OBJ: Material filename is too long");
memcpy(path + baseLength, filename, filenameLength);
path[baseLength + filenameLength] = '\0';
parseMtl(path, base, io, &textures, &materials, &materialMap);
parseMtl(path, base, io, &images, &materials, &materialMap);
} else if (STARTS_WITH(line, "usemtl ")) {
uint64_t index = map_get(&materialMap, hash64(line + 7, length - 7));
int material = index == MAP_NIL ? -1 : index;
@ -244,7 +244,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source, ModelDataIO* io)
model->attributeCount = 3 + (uint32_t) groups.length;
model->primitiveCount = (uint32_t) groups.length;
model->nodeCount = 1;
model->textureCount = (uint32_t) textures.length;
model->imageCount = (uint32_t) images.length;
model->materialCount = (uint32_t) materials.length;
lovrModelDataAllocate(model);
@ -263,7 +263,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source, ModelDataIO* io)
.stride = sizeof(int)
};
memcpy(model->textures, textures.data, model->textureCount * sizeof(TextureData*));
memcpy(model->images, images.data, model->imageCount * sizeof(Image*));
memcpy(model->materials, materials.data, model->materialCount * sizeof(ModelMaterial));
memcpy(model->materialMap.hashes, materialMap.hashes, materialMap.size * sizeof(uint64_t));
memcpy(model->materialMap.values, materialMap.values, materialMap.size * sizeof(uint64_t));
@ -348,7 +348,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source, ModelDataIO* io)
finish:
arr_free(&groups);
arr_free(&textures);
arr_free(&images);
arr_free(&materials);
map_free(&materialMap);
map_free(&vertexMap);

View File

@ -1,6 +1,6 @@
#include "data/rasterizer.h"
#include "data/blob.h"
#include "data/textureData.h"
#include "data/image.h"
#include "resources/VarelaRound.ttf.h"
#include "core/utf.h"
#include "core/util.h"
@ -167,7 +167,7 @@ void lovrRasterizerLoadGlyph(Rasterizer* rasterizer, uint32_t character, Glyph*
glyph->dx = empty ? 0 : roundf(bearing * rasterizer->scale);
glyph->dy = empty ? 0 : roundf(y1 * rasterizer->scale);
glyph->advance = roundf(advance * rasterizer->scale);
glyph->data = lovrTextureDataCreate(glyph->tw, glyph->th, NULL, 0, FORMAT_RGB);
glyph->data = lovrImageCreate(glyph->tw, glyph->th, NULL, 0, FORMAT_RGB);
// Render SDF
float tx = GLYPH_PADDING + -glyph->dx;

View File

@ -6,7 +6,7 @@
#define GLYPH_PADDING 1
struct Blob;
struct TextureData;
struct Image;
typedef struct {
uint32_t x;
@ -18,7 +18,7 @@ typedef struct {
int32_t dx;
int32_t dy;
int32_t advance;
struct TextureData* data;
struct Image* data;
} Glyph;
typedef struct Rasterizer Rasterizer;

View File

@ -1,11 +1,11 @@
#include "data/textureData.h"
#include "data/image.h"
#pragma once
#define MAX_CANVAS_ATTACHMENTS 4
struct Image;
struct Texture;
struct TextureData;
typedef struct Attachment {
struct Texture* texture;
@ -39,4 +39,4 @@ void lovrCanvasSetWidth(Canvas* canvas, uint32_t width);
void lovrCanvasSetHeight(Canvas* canvas, uint32_t height);
uint32_t lovrCanvasGetMSAA(Canvas* canvas);
struct Texture* lovrCanvasGetDepthTexture(Canvas* canvas);
struct TextureData* lovrCanvasNewTextureData(Canvas* canvas, uint32_t index);
struct Image* lovrCanvasNewImage(Canvas* canvas, uint32_t index);

View File

@ -1,7 +1,7 @@
#include "graphics/font.h"
#include "graphics/texture.h"
#include "data/rasterizer.h"
#include "data/textureData.h"
#include "data/image.h"
#include "core/map.h"
#include "core/utf.h"
#include <string.h>
@ -85,7 +85,7 @@ void lovrFontDestroy(void* ref) {
lovrRelease(font->rasterizer, lovrRasterizerDestroy);
lovrRelease(font->texture, lovrTextureDestroy);
for (size_t i = 0; i < font->atlas.glyphs.length; i++) {
lovrRelease(font->atlas.glyphs.data[i].data, lovrTextureDataDestroy);
lovrRelease(font->atlas.glyphs.data[i].data, lovrImageDestroy);
}
arr_free(&font->atlas.glyphs);
map_free(&font->atlas.glyphMap);
@ -369,13 +369,13 @@ static void lovrFontExpandTexture(Font* font) {
}
}
// TODO we only need the TextureData here to clear the texture, but it's a big waste of memory.
// TODO we only need the Image here to clear the texture, but it's a big waste of memory.
// Could look into using glClearTexImage when supported to make this more efficient.
static void lovrFontCreateTexture(Font* font) {
lovrRelease(font->texture, lovrTextureDestroy);
TextureData* textureData = lovrTextureDataCreate(font->atlas.width, font->atlas.height, NULL, 0x0, FORMAT_RGB);
font->texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, false, false, 0);
Image* image = lovrImageCreate(font->atlas.width, font->atlas.height, NULL, 0x0, FORMAT_RGB);
font->texture = lovrTextureCreate(TEXTURE_2D, &image, 1, false, false, 0);
lovrTextureSetFilter(font->texture, (TextureFilter) { .mode = FILTER_BILINEAR });
lovrTextureSetWrap(font->texture, (TextureWrap) { .s = WRAP_CLAMP, .t = WRAP_CLAMP });
lovrRelease(textureData, lovrTextureDataDestroy);
lovrRelease(image, lovrImageDestroy);
}

View File

@ -86,8 +86,8 @@ Model* lovrModelCreate(ModelData* data) {
if (data->materialCount > 0) {
model->materials = malloc(data->materialCount * sizeof(Material*));
if (data->textureCount > 0) {
model->textures = calloc(data->textureCount, sizeof(Texture*));
if (data->imageCount > 0) {
model->textures = calloc(data->imageCount, sizeof(Texture*));
}
for (uint32_t i = 0; i < data->materialCount; i++) {
@ -102,13 +102,13 @@ Model* lovrModelCreate(ModelData* data) {
}
for (uint32_t j = 0; j < MAX_MATERIAL_TEXTURES; j++) {
uint32_t index = data->materials[i].textures[j];
uint32_t index = data->materials[i].images[j];
if (index != ~0u) {
if (!model->textures[index]) {
TextureData* textureData = data->textures[index];
Image* image = data->images[index];
bool srgb = j == TEXTURE_DIFFUSE || j == TEXTURE_EMISSIVE;
model->textures[index] = lovrTextureCreate(TEXTURE_2D, &textureData, 1, srgb, true, 0);
model->textures[index] = lovrTextureCreate(TEXTURE_2D, &image, 1, srgb, true, 0);
lovrTextureSetFilter(model->textures[index], data->materials[i].filters[j]);
lovrTextureSetWrap(model->textures[index], data->materials[i].wraps[j]);
}
@ -214,7 +214,7 @@ void lovrModelDestroy(void* ref) {
}
if (model->textures) {
for (uint32_t i = 0; i < model->data->textureCount; i++) {
for (uint32_t i = 0; i < model->data->imageCount; i++) {
lovrRelease(model->textures[i], lovrTextureDestroy);
}
free(model->textures);

View File

@ -189,7 +189,7 @@ static struct {
BlockBuffer blockBuffers[2][MAX_BLOCK_BUFFERS];
int activeTexture;
Texture* textures[MAX_TEXTURES];
Image images[MAX_IMAGES];
StorageImage images[MAX_IMAGES];
float viewports[2][4];
uint32_t viewportCount;
arr_t(void*) incoherents[MAX_BARRIERS];
@ -766,11 +766,11 @@ static void lovrGpuBindTexture(Texture* texture, int slot) {
}
#ifndef LOVR_WEBGL
static void lovrGpuBindImage(Image* image, int slot, const char* name) {
static void lovrGpuBindImage(StorageImage* image, int slot, const char* name) {
lovrAssert(slot >= 0 && slot < MAX_IMAGES, "Invalid image slot %d", slot);
// This is a risky way to compare the two structs
if (memcmp(state.images + slot, image, sizeof(Image))) {
if (memcmp(state.images + slot, image, sizeof(StorageImage))) {
Texture* texture = image->texture;
lovrAssert(texture, "No Texture bound to image uniform '%s'", name);
lovrAssert(texture->format != FORMAT_RGBA || !texture->srgb, "Attempt to bind sRGB texture to image uniform '%s'", name);
@ -786,7 +786,7 @@ static void lovrGpuBindImage(Image* image, int slot, const char* name) {
lovrRetain(texture);
lovrRelease(state.images[slot].texture, lovrTextureDestroy);
glBindImageTexture(slot, texture->id, image->mipmap, layered, slice, glAccess, glFormat);
memcpy(state.images + slot, image, sizeof(Image));
memcpy(state.images + slot, image, sizeof(StorageImage));
}
}
#endif
@ -1167,7 +1167,7 @@ static void lovrGpuBindShader(Shader* shader) {
case UNIFORM_IMAGE:
#ifndef LOVR_WEBGL
for (int j = 0; j < count; j++) {
Image* image = &uniform->value.images[j];
StorageImage* image = &uniform->value.images[j];
Texture* texture = image->texture;
lovrAssert(!texture || texture->type == uniform->textureType, "Uniform texture type mismatch for uniform '%s'", uniform->name);
@ -1348,11 +1348,11 @@ void lovrGpuInit(void* (*getProcAddress)(const char*), bool debug) {
arr_init(&state.incoherents[i], realloc);
}
TextureData* textureData = lovrTextureDataCreate(1, 1, NULL, 0xff, FORMAT_RGBA);
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false, 0);
Image* image = lovrImageCreate(1, 1, NULL, 0xff, FORMAT_RGBA);
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &image, 1, true, false, 0);
lovrTextureSetFilter(state.defaultTexture, (TextureFilter) { .mode = FILTER_NEAREST });
lovrTextureSetWrap(state.defaultTexture, (TextureWrap) { WRAP_CLAMP, WRAP_CLAMP, WRAP_CLAMP });
lovrRelease(textureData, lovrTextureDataDestroy);
lovrRelease(image, lovrImageDestroy);
map_init(&state.timerMap, 4);
state.queryPool.next = ~0u;
@ -1670,7 +1670,7 @@ const GpuStats* lovrGpuGetStats() {
// Texture
Texture* lovrTextureCreate(TextureType type, TextureData** slices, uint32_t sliceCount, bool srgb, bool mipmaps, uint32_t msaa) {
Texture* lovrTextureCreate(TextureType type, Image** slices, uint32_t sliceCount, bool srgb, bool mipmaps, uint32_t msaa) {
Texture* texture = calloc(1, sizeof(Texture));
lovrAssert(texture, "Out of memory");
texture->ref = 1;
@ -1814,7 +1814,7 @@ void lovrTextureAllocate(Texture* texture, uint32_t width, uint32_t height, uint
state.stats.textureMemory += getTextureMemorySize(texture);
}
void lovrTextureReplacePixels(Texture* texture, TextureData* textureData, uint32_t x, uint32_t y, uint32_t slice, uint32_t mipmap) {
void lovrTextureReplacePixels(Texture* texture, Image* image, uint32_t x, uint32_t y, uint32_t slice, uint32_t mipmap) {
lovrGraphicsFlush();
lovrAssert(texture->allocated, "Texture is not allocated");
@ -1826,21 +1826,21 @@ void lovrTextureReplacePixels(Texture* texture, TextureData* textureData, uint32
uint32_t maxWidth = lovrTextureGetWidth(texture, mipmap);
uint32_t maxHeight = lovrTextureGetHeight(texture, mipmap);
uint32_t width = textureData->width;
uint32_t height = textureData->height;
uint32_t width = image->width;
uint32_t height = image->height;
bool overflow = (x + width > maxWidth) || (y + height > maxHeight);
lovrAssert(!overflow, "Trying to replace pixels outside the texture's bounds");
lovrAssert(mipmap < texture->mipmapCount, "Invalid mipmap level %d", mipmap);
GLenum glFormat = convertTextureFormat(textureData->format);
GLenum glInternalFormat = convertTextureFormatInternal(textureData->format, texture->srgb);
GLenum glFormat = convertTextureFormat(image->format);
GLenum glInternalFormat = convertTextureFormatInternal(image->format, texture->srgb);
GLenum binding = (texture->type == TEXTURE_CUBE) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice : texture->target;
lovrGpuBindTexture(texture, 0);
if (isTextureFormatCompressed(textureData->format)) {
if (isTextureFormatCompressed(image->format)) {
lovrAssert(width == maxWidth && height == maxHeight, "Compressed texture pixels must be fully replaced");
lovrAssert(mipmap == 0, "Unable to replace a specific mipmap of a compressed texture");
for (uint32_t i = 0; i < textureData->mipmapCount; i++) {
Mipmap* m = textureData->mipmaps + i;
for (uint32_t i = 0; i < image->mipmapCount; i++) {
Mipmap* m = image->mipmaps + i;
switch (texture->type) {
case TEXTURE_2D:
case TEXTURE_CUBE:
@ -1853,17 +1853,17 @@ void lovrTextureReplacePixels(Texture* texture, TextureData* textureData, uint32
}
}
} else {
lovrAssert(textureData->blob->data, "Trying to replace Texture pixels with empty pixel data");
GLenum glType = convertTextureFormatType(textureData->format);
lovrAssert(image->blob->data, "Trying to replace Texture pixels with empty pixel data");
GLenum glType = convertTextureFormatType(image->format);
switch (texture->type) {
case TEXTURE_2D:
case TEXTURE_CUBE:
glTexSubImage2D(binding, mipmap, x, y, width, height, glFormat, glType, textureData->blob->data);
glTexSubImage2D(binding, mipmap, x, y, width, height, glFormat, glType, image->blob->data);
break;
case TEXTURE_ARRAY:
case TEXTURE_VOLUME:
glTexSubImage3D(binding, mipmap, x, y, slice, width, height, 1, glFormat, glType, textureData->blob->data);
glTexSubImage3D(binding, mipmap, x, y, slice, width, height, 1, glFormat, glType, image->blob->data);
break;
}
@ -2110,7 +2110,7 @@ void lovrCanvasResolve(Canvas* canvas) {
canvas->needsResolve = false;
}
TextureData* lovrCanvasNewTextureData(Canvas* canvas, uint32_t index) {
Image* lovrCanvasNewImage(Canvas* canvas, uint32_t index) {
lovrGraphicsFlushCanvas(canvas);
lovrGpuBindCanvas(canvas, false);
@ -2129,14 +2129,14 @@ TextureData* lovrCanvasNewTextureData(Canvas* canvas, uint32_t index) {
glReadBuffer(index);
}
TextureData* textureData = lovrTextureDataCreate(canvas->width, canvas->height, NULL, 0x0, FORMAT_RGBA);
glReadPixels(0, 0, canvas->width, canvas->height, GL_RGBA, GL_UNSIGNED_BYTE, textureData->blob->data);
Image* image = lovrImageCreate(canvas->width, canvas->height, NULL, 0x0, FORMAT_RGBA);
glReadPixels(0, 0, canvas->width, canvas->height, GL_RGBA, GL_UNSIGNED_BYTE, image->blob->data);
if (index != 0) {
glReadBuffer(0);
}
return textureData;
return image;
}
const Attachment* lovrCanvasGetAttachments(Canvas* canvas, uint32_t* count) {
@ -2536,7 +2536,7 @@ static void lovrShaderSetupUniforms(Shader* shader) {
case UNIFORM_SAMPLER:
case UNIFORM_IMAGE:
uniform.size = uniform.count * (uniform.type == UNIFORM_SAMPLER ? sizeof(Texture*) : sizeof(Image));
uniform.size = uniform.count * (uniform.type == UNIFORM_SAMPLER ? sizeof(Texture*) : sizeof(StorageImage));
uniform.value.data = calloc(1, uniform.size);
lovrAssert(uniform.value.data, "Out of memory");
@ -2815,8 +2815,8 @@ void lovrShaderSetTextures(Shader* shader, const char* name, Texture** data, int
lovrShaderSetUniform(shader, name, UNIFORM_SAMPLER, data, start, count, sizeof(Texture*), "texture");
}
void lovrShaderSetImages(Shader* shader, const char* name, Image* data, int start, int count) {
lovrShaderSetUniform(shader, name, UNIFORM_IMAGE, data, start, count, sizeof(Image), "image");
void lovrShaderSetImages(Shader* shader, const char* name, StorageImage* data, int start, int count) {
lovrShaderSetUniform(shader, name, UNIFORM_IMAGE, data, start, count, sizeof(StorageImage), "image");
}
void lovrShaderSetColor(Shader* shader, const char* name, Color color) {

View File

@ -64,7 +64,7 @@ typedef struct {
int slice;
int mipmap;
UniformAccess access;
} Image;
} StorageImage;
typedef struct Uniform {
char name[LOVR_MAX_UNIFORM_LENGTH];
@ -80,7 +80,7 @@ typedef struct Uniform {
int* ints;
float* floats;
struct Texture** textures;
Image* images;
StorageImage* images;
} value;
TextureType textureType;
int baseSlot;
@ -118,7 +118,7 @@ void lovrShaderSetFloats(Shader* shader, const char* name, float* data, int star
void lovrShaderSetInts(Shader* shader, const char* name, int* data, int start, int count);
void lovrShaderSetMatrices(Shader* shader, const char* name, float* data, int start, int count);
void lovrShaderSetTextures(Shader* shader, const char* name, struct Texture** data, int start, int count);
void lovrShaderSetImages(Shader* shader, const char* name, Image* data, int start, int count);
void lovrShaderSetImages(Shader* shader, const char* name, StorageImage* data, int start, int count);
void lovrShaderSetColor(Shader* shader, const char* name, Color color);
void lovrShaderSetBlock(Shader* shader, const char* name, struct Buffer* buffer, size_t offset, size_t size, UniformAccess access);

View File

@ -1,11 +1,11 @@
#include "data/textureData.h"
#include "data/image.h"
#include "graphics/graphics.h"
#include "data/modelData.h"
#include <stdbool.h>
#pragma once
struct TextureData;
struct Image;
typedef enum {
TEXTURE_2D,
@ -15,11 +15,11 @@ typedef enum {
} TextureType;
typedef struct Texture Texture;
Texture* lovrTextureCreate(TextureType type, struct TextureData** slices, uint32_t sliceCount, bool srgb, bool mipmaps, uint32_t msaa);
Texture* lovrTextureCreate(TextureType type, struct Image** slices, uint32_t sliceCount, bool srgb, bool mipmaps, uint32_t msaa);
Texture* lovrTextureCreateFromHandle(uint32_t handle, TextureType type, uint32_t depth, uint32_t msaa);
void lovrTextureDestroy(void* ref);
void lovrTextureAllocate(Texture* texture, uint32_t width, uint32_t height, uint32_t depth, TextureFormat format);
void lovrTextureReplacePixels(Texture* texture, struct TextureData* data, uint32_t x, uint32_t y, uint32_t slice, uint32_t mipmap);
void lovrTextureReplacePixels(Texture* texture, struct Image* data, uint32_t x, uint32_t y, uint32_t slice, uint32_t mipmap);
uint64_t lovrTextureGetId(Texture* texture);
uint32_t lovrTextureGetWidth(Texture* texture, uint32_t mipmap);
uint32_t lovrTextureGetHeight(Texture* texture, uint32_t mipmap);

View File

@ -626,7 +626,7 @@ static ModelData* openvr_newModelData(Device device, bool animated) {
model->nodeCount = animated ? (1 + modelCount) : 1;
model->bufferCount = 2 * modelCount;
model->attributeCount = 4 * modelCount;
model->textureCount = modelCount;
model->imageCount = modelCount;
model->materialCount = modelCount;
model->primitiveCount = modelCount;
model->childCount = animated ? modelCount : 0;
@ -702,12 +702,12 @@ static ModelData* openvr_newModelData(Device device, bool animated) {
};
RenderModel_TextureMap_t* texture = renderModelTextures[i];
model->textures[i] = lovrTextureDataCreate(texture->unWidth, texture->unHeight, NULL, 0, FORMAT_RGBA);
memcpy(model->textures[i]->blob->data, texture->rubTextureMapData, texture->unWidth * texture->unHeight * 4);
model->images[i] = lovrImageCreate(texture->unWidth, texture->unHeight, NULL, 0, FORMAT_RGBA);
memcpy(model->images[i]->blob->data, texture->rubTextureMapData, texture->unWidth * texture->unHeight * 4);
model->materials[i] = (ModelMaterial) {
.colors[COLOR_DIFFUSE] = { 1.f, 1.f, 1.f, 1.f },
.textures[TEXTURE_DIFFUSE] = i,
.images[TEXTURE_DIFFUSE] = i,
.filters[TEXTURE_DIFFUSE] = lovrGraphicsGetDefaultFilter()
};