image load and save
parent
39ec13501a
commit
6e59750ff2
|
@ -45,12 +45,14 @@ add_definitions(
|
||||||
add_library(Refresh
|
add_library(Refresh
|
||||||
# Public Headers
|
# Public Headers
|
||||||
include/Refresh.h
|
include/Refresh.h
|
||||||
|
include/Refresh_Image.h
|
||||||
# Internal Headers
|
# Internal Headers
|
||||||
src/Refresh_Driver.h
|
src/Refresh_Driver.h
|
||||||
src/Refresh_Driver_Vulkan_vkfuncs.h
|
src/Refresh_Driver_Vulkan_vkfuncs.h
|
||||||
# Source Files
|
# Source Files
|
||||||
src/Refresh.c
|
src/Refresh.c
|
||||||
src/Refresh_Driver_Vulkan.c
|
src/Refresh_Driver_Vulkan.c
|
||||||
|
src/Refresh_Image.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build flags
|
# Build flags
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/* Refresh - XNA-inspired 3D Graphics Library with modern capabilities
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ethan Lee and Evan Hemsley
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in a
|
||||||
|
* product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
|
||||||
|
* Evan "cosmonaut" Hemsley <evan@moonside.games>
|
||||||
|
*
|
||||||
|
* This source file is heavily borrowed from FNA3D_Image.h and was originally
|
||||||
|
* written by Ethan Lee.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REFRESH_IMAGE_H
|
||||||
|
#define REFRESH_IMAGE_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define REFRESHAPI __declspec(dllexport)
|
||||||
|
#define REFRESHCALL __cdecl
|
||||||
|
#else
|
||||||
|
#define REFRESHAPI
|
||||||
|
#define REFRESHCALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* Decodes PNG data into raw RGBA8 texture data.
|
||||||
|
*
|
||||||
|
* w: Filled with the width of the image.
|
||||||
|
* h: Filled with the height of the image.
|
||||||
|
* numChannels: Filled with the number of channels in the image.
|
||||||
|
*
|
||||||
|
* Returns a block of memory suitable for use with REFRESH_SetTextureData2D.
|
||||||
|
* Be sure to free the memory with REFRESH_Image_Free after use!
|
||||||
|
*/
|
||||||
|
REFRESHAPI uint8_t* REFRESH_Image_Load(
|
||||||
|
char const *filename,
|
||||||
|
int32_t *w,
|
||||||
|
int32_t *h,
|
||||||
|
int32_t *numChannels
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Frees memory returned by REFRESH_Image_Load. (Do NOT free the memory yourself!)
|
||||||
|
*
|
||||||
|
* mem: A pointer previously returned by REFRESH_Image_Load.
|
||||||
|
*/
|
||||||
|
REFRESHAPI void REFRESH_Image_Free(uint8_t *mem);
|
||||||
|
|
||||||
|
/* Image Write API */
|
||||||
|
|
||||||
|
/* Encodes RGBA8 image data into PNG data.
|
||||||
|
*
|
||||||
|
* filename: The filename that the image will be written to.
|
||||||
|
* w: The width of the PNG data.
|
||||||
|
* h: The height of the PNG data.
|
||||||
|
* data: The raw RGBA8 image data.
|
||||||
|
*/
|
||||||
|
REFRESHAPI void REFRESH_Image_SavePNG(
|
||||||
|
char const *filename,
|
||||||
|
int32_t w,
|
||||||
|
int32_t h,
|
||||||
|
uint8_t *data
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* REFRESH_IMAGE_H */
|
||||||
|
|
||||||
|
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
|
|
@ -2896,11 +2896,26 @@ static SamplerDescriptorSetCache* VULKAN_INTERNAL_CreateSamplerDescriptorSetCach
|
||||||
VkDescriptorSetLayout descriptorSetLayout,
|
VkDescriptorSetLayout descriptorSetLayout,
|
||||||
uint32_t samplerBindingCount
|
uint32_t samplerBindingCount
|
||||||
) {
|
) {
|
||||||
SamplerDescriptorSetCache *samplerDescriptorSetCache = SDL_malloc(sizeof(samplerDescriptorSetCache));
|
uint32_t i;
|
||||||
|
SamplerDescriptorSetCache *samplerDescriptorSetCache = SDL_malloc(sizeof(SamplerDescriptorSetCache));
|
||||||
|
|
||||||
|
samplerDescriptorSetCache->elements = SDL_malloc(sizeof(SamplerDescriptorSetHashMap) * 16);
|
||||||
|
samplerDescriptorSetCache->count = 0;
|
||||||
|
samplerDescriptorSetCache->capacity = 16;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_DESCRIPTOR_SET_HASH_BUCKETS; i += 1)
|
||||||
|
{
|
||||||
|
samplerDescriptorSetCache->buckets[i].elements = NULL;
|
||||||
|
samplerDescriptorSetCache->buckets[i].count = 0;
|
||||||
|
samplerDescriptorSetCache->buckets[i].capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
samplerDescriptorSetCache->descriptorSetLayout = descriptorSetLayout;
|
samplerDescriptorSetCache->descriptorSetLayout = descriptorSetLayout;
|
||||||
samplerDescriptorSetCache->samplerBindingCount = samplerBindingCount;
|
samplerDescriptorSetCache->samplerBindingCount = samplerBindingCount;
|
||||||
|
|
||||||
|
samplerDescriptorSetCache->samplerDescriptorPools = SDL_malloc(sizeof(VkDescriptorPool));
|
||||||
|
samplerDescriptorSetCache->samplerDescriptorPoolCount = 1;
|
||||||
|
|
||||||
VULKAN_INTERNAL_CreateSamplerDescriptorPool(
|
VULKAN_INTERNAL_CreateSamplerDescriptorPool(
|
||||||
renderer,
|
renderer,
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
|
@ -5057,7 +5072,7 @@ static void VULKAN_SetFragmentSamplers(
|
||||||
VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline;
|
VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline;
|
||||||
SamplerDescriptorSetData fragmentSamplerDescriptorSetData;
|
SamplerDescriptorSetData fragmentSamplerDescriptorSetData;
|
||||||
|
|
||||||
if (graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL)
|
if (graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5067,6 +5082,20 @@ static void VULKAN_SetFragmentSamplers(
|
||||||
for (i = 0; i < samplerCount; i += 1)
|
for (i = 0; i < samplerCount; i += 1)
|
||||||
{
|
{
|
||||||
currentTexture = (VulkanTexture*) pTextures[i];
|
currentTexture = (VulkanTexture*) pTextures[i];
|
||||||
|
|
||||||
|
VULKAN_INTERNAL_ImageMemoryBarrier(
|
||||||
|
renderer,
|
||||||
|
RESOURCE_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE,
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
0,
|
||||||
|
currentTexture->layerCount,
|
||||||
|
0,
|
||||||
|
currentTexture->levelCount,
|
||||||
|
0,
|
||||||
|
currentTexture->image,
|
||||||
|
¤tTexture->resourceAccessType
|
||||||
|
);
|
||||||
|
|
||||||
fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageView = currentTexture->view;
|
fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageView = currentTexture->view;
|
||||||
fragmentSamplerDescriptorSetData.descriptorImageInfo[i].sampler = (VkSampler) pSamplers[i];
|
fragmentSamplerDescriptorSetData.descriptorImageInfo[i].sampler = (VkSampler) pSamplers[i];
|
||||||
fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
|
@ -0,0 +1,217 @@
|
||||||
|
/* Refresh - XNA-inspired 3D Graphics Library with modern capabilities
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ethan Lee and Evan Hemsley
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in a
|
||||||
|
* product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
|
||||||
|
* Evan "cosmonaut" Hemsley <evan@moonside.games>
|
||||||
|
*
|
||||||
|
* This source file is heavily borrowed from FNA3D_Image.h and was originally
|
||||||
|
* written by Ethan Lee.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Refresh_Image.h"
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
|
#ifndef __clang__
|
||||||
|
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __STDC_WANT_SECURE_LIB__
|
||||||
|
#define __STDC_WANT_SECURE_LIB__ 1
|
||||||
|
#endif
|
||||||
|
#define sprintf_s SDL_snprintf
|
||||||
|
|
||||||
|
#define abs SDL_abs
|
||||||
|
#define ceilf SDL_ceilf
|
||||||
|
#define floorf SDL_floorf
|
||||||
|
#define ldexp SDL_scalbn
|
||||||
|
#define pow SDL_pow
|
||||||
|
#define strtol SDL_strtol
|
||||||
|
|
||||||
|
#ifdef memcmp
|
||||||
|
#undef memcmp
|
||||||
|
#endif
|
||||||
|
#define memcmp SDL_memcmp
|
||||||
|
#ifdef memcpy
|
||||||
|
#undef memcpy
|
||||||
|
#endif
|
||||||
|
#define memcpy SDL_memcpy
|
||||||
|
#ifdef memmove
|
||||||
|
#undef memmove
|
||||||
|
#endif
|
||||||
|
#define memmove SDL_memmove
|
||||||
|
#ifdef memset
|
||||||
|
#undef memset
|
||||||
|
#endif
|
||||||
|
#define memset SDL_memset
|
||||||
|
#ifdef strcmp
|
||||||
|
#undef strcmp
|
||||||
|
#endif
|
||||||
|
#define strcmp SDL_strcmp
|
||||||
|
#ifdef strlen
|
||||||
|
#undef strlen
|
||||||
|
#endif
|
||||||
|
#define strlen SDL_strlen
|
||||||
|
#ifdef strncmp
|
||||||
|
#undef strncmp
|
||||||
|
#endif
|
||||||
|
#define strncmp SDL_strncmp
|
||||||
|
|
||||||
|
/* These are per the Texture2D.FromStream spec */
|
||||||
|
#define STBI_ONLY_PNG
|
||||||
|
|
||||||
|
/* These are per the Texture2D.SaveAs* spec */
|
||||||
|
#define STBIW_ONLY_PNG
|
||||||
|
|
||||||
|
#if !SDL_VERSION_ATLEAST(2, 0, 13)
|
||||||
|
static void *
|
||||||
|
SDL_SIMDRealloc(void *mem, const size_t len)
|
||||||
|
{
|
||||||
|
const size_t alignment = SDL_SIMDGetAlignment();
|
||||||
|
const size_t padding = alignment - (len % alignment);
|
||||||
|
const size_t padded = (padding != alignment) ? (len + padding) : len;
|
||||||
|
Uint8 *retval = (Uint8*) mem;
|
||||||
|
void *oldmem = mem;
|
||||||
|
size_t memdiff, ptrdiff;
|
||||||
|
Uint8 *ptr;
|
||||||
|
|
||||||
|
if (mem) {
|
||||||
|
void **realptr = (void **) mem;
|
||||||
|
realptr--;
|
||||||
|
mem = *(((void **) mem) - 1);
|
||||||
|
|
||||||
|
/* Check the delta between the real pointer and user pointer */
|
||||||
|
memdiff = ((size_t) oldmem) - ((size_t) mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *));
|
||||||
|
|
||||||
|
if (ptr == mem) {
|
||||||
|
return retval; /* Pointer didn't change, nothing to do */
|
||||||
|
}
|
||||||
|
if (ptr == NULL) {
|
||||||
|
return NULL; /* Out of memory, bail! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the actual malloc pointer right before our aligned pointer. */
|
||||||
|
retval = ptr + sizeof (void *);
|
||||||
|
retval += alignment - (((size_t) retval) % alignment);
|
||||||
|
|
||||||
|
/* Make sure the delta is the same! */
|
||||||
|
if (mem) {
|
||||||
|
ptrdiff = ((size_t) retval) - ((size_t) ptr);
|
||||||
|
if (memdiff != ptrdiff) { /* Delta has changed, copy to new offset! */
|
||||||
|
oldmem = (void*) (((size_t) ptr) + memdiff);
|
||||||
|
|
||||||
|
/* Even though the data past the old `len` is undefined, this is the
|
||||||
|
* only length value we have, and it guarantees that we copy all the
|
||||||
|
* previous memory anyhow.
|
||||||
|
*/
|
||||||
|
SDL_memmove(retval, oldmem, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Actually store the malloc pointer, finally. */
|
||||||
|
*(((void **) retval) - 1) = ptr;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STB_IMAGE_STATIC
|
||||||
|
#define STBI_ASSERT SDL_assert
|
||||||
|
#define STBI_MALLOC SDL_SIMDAlloc
|
||||||
|
#define STBI_REALLOC SDL_SIMDRealloc
|
||||||
|
#define STBI_FREE SDL_SIMDFree
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#define STBI_NO_THREAD_LOCALS /* FIXME: Port to SDL_TLS -flibit */
|
||||||
|
#endif
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
|
#define MINIZ_NO_STDIO
|
||||||
|
#define MINIZ_NO_TIME
|
||||||
|
#define MINIZ_SDL_MALLOC
|
||||||
|
#define MZ_ASSERT(x) SDL_assert(x)
|
||||||
|
#include "miniz.h"
|
||||||
|
|
||||||
|
/* Thanks Daniel Gibson! */
|
||||||
|
static unsigned char* dgibson_stbi_zlib_compress(
|
||||||
|
unsigned char *data,
|
||||||
|
int data_len,
|
||||||
|
int *out_len,
|
||||||
|
int quality
|
||||||
|
) {
|
||||||
|
mz_ulong buflen = mz_compressBound(data_len);
|
||||||
|
unsigned char *buf = SDL_malloc(buflen);
|
||||||
|
|
||||||
|
if ( buf == NULL ||
|
||||||
|
mz_compress2(buf, &buflen, data, data_len, quality) != 0 )
|
||||||
|
{
|
||||||
|
SDL_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*out_len = buflen;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define STB_IMAGE_WRITE_STATIC
|
||||||
|
#define STBIW_ASSERT SDL_assert
|
||||||
|
#define STBIW_MALLOC SDL_malloc
|
||||||
|
#define STBIW_REALLOC SDL_realloc
|
||||||
|
#define STBIW_FREE SDL_free
|
||||||
|
#define STBIW_ZLIB_COMPRESS dgibson_stbi_zlib_compress
|
||||||
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
/* Image Read API */
|
||||||
|
|
||||||
|
uint8_t* REFRESH_Image_Load(
|
||||||
|
char const *filename,
|
||||||
|
int32_t *w,
|
||||||
|
int32_t *h,
|
||||||
|
int32_t *numChannels
|
||||||
|
) {
|
||||||
|
return stbi_load(filename, w, h, numChannels, STBI_rgb_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
void REFRESH_Image_Free(uint8_t *mem)
|
||||||
|
{
|
||||||
|
stbi_image_free(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Image Write API */
|
||||||
|
|
||||||
|
void REFRESH_Image_SavePNG(
|
||||||
|
const char *filename,
|
||||||
|
int32_t w,
|
||||||
|
int32_t h,
|
||||||
|
uint8_t *data
|
||||||
|
) {
|
||||||
|
stbi_write_png(filename, w, h, 4, data, w * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue