Add basic texture array support
Add TextureBuilder overloads for array texturesmaster
parent
43cd23b8dc
commit
d29cdd1437
|
@ -430,7 +430,7 @@ bool GasGiant::AddTextureFaceResult(GasGiantJobs::STextureFaceResult *res)
|
|||
if (bCreateTexture) {
|
||||
// create texture
|
||||
const vector2f texSize(1.0f, 1.0f);
|
||||
const vector2f dataSize(uvDims, uvDims);
|
||||
const vector3f dataSize(uvDims, uvDims, 0.0f);
|
||||
const Graphics::TextureDescriptor texDesc(
|
||||
Graphics::TEXTURE_RGBA_8888,
|
||||
dataSize, texSize, Graphics::LINEAR_CLAMP,
|
||||
|
@ -533,7 +533,7 @@ void GasGiant::GenerateTexture()
|
|||
// scope the small texture generation
|
||||
{
|
||||
const vector2f texSize(1.0f, 1.0f);
|
||||
const vector2f dataSize(s_texture_size_small, s_texture_size_small);
|
||||
const vector3f dataSize(s_texture_size_small, s_texture_size_small, 0.0f);
|
||||
const Graphics::TextureDescriptor texDesc(
|
||||
Graphics::TEXTURE_RGBA_8888,
|
||||
dataSize, texSize, Graphics::LINEAR_CLAMP,
|
||||
|
@ -592,7 +592,7 @@ void GasGiant::GenerateTexture()
|
|||
// use m_surfaceTexture texture?
|
||||
// create texture
|
||||
const vector2f texSize(1.0f, 1.0f);
|
||||
const vector2f dataSize(s_texture_size_gpu[Pi::detail.planets], s_texture_size_gpu[Pi::detail.planets]);
|
||||
const vector3f dataSize(s_texture_size_gpu[Pi::detail.planets], s_texture_size_gpu[Pi::detail.planets], 0.0f);
|
||||
const Graphics::TextureDescriptor texDesc(
|
||||
Graphics::TEXTURE_RGBA_8888,
|
||||
dataSize, texSize, Graphics::LINEAR_CLAMP,
|
||||
|
|
|
@ -227,7 +227,7 @@ void Planet::GenerateRings(Graphics::Renderer *renderer)
|
|||
memset(row, 0, RING_TEXTURE_WIDTH * 4);
|
||||
}
|
||||
|
||||
const vector2f texSize(RING_TEXTURE_WIDTH, RING_TEXTURE_LENGTH);
|
||||
const vector3f texSize(RING_TEXTURE_WIDTH, RING_TEXTURE_LENGTH, 0.0f);
|
||||
const Graphics::TextureDescriptor texDesc(
|
||||
Graphics::TEXTURE_RGBA_8888, texSize, Graphics::LINEAR_REPEAT, true, true, true, 0, Graphics::TEXTURE_2D);
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
#define _TEXTURE_H
|
||||
|
||||
#include "RefCounted.h"
|
||||
#include <vector>
|
||||
#include "vector2.h"
|
||||
#include "vector3.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
|
@ -35,7 +37,8 @@ namespace Graphics {
|
|||
|
||||
enum TextureType {
|
||||
TEXTURE_2D,
|
||||
TEXTURE_CUBE_MAP
|
||||
TEXTURE_CUBE_MAP,
|
||||
TEXTURE_2D_ARRAY
|
||||
};
|
||||
|
||||
struct TextureCubeData {
|
||||
|
@ -61,7 +64,7 @@ namespace Graphics {
|
|||
type(TEXTURE_2D)
|
||||
{}
|
||||
|
||||
TextureDescriptor(TextureFormat _format, const vector2f &_dataSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) :
|
||||
TextureDescriptor(TextureFormat _format, const vector3f &_dataSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) :
|
||||
format(_format),
|
||||
dataSize(_dataSize),
|
||||
texSize(1.0f),
|
||||
|
@ -73,7 +76,7 @@ namespace Graphics {
|
|||
type(_textureType)
|
||||
{}
|
||||
|
||||
TextureDescriptor(TextureFormat _format, const vector2f &_dataSize, const vector2f &_texSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) :
|
||||
TextureDescriptor(TextureFormat _format, const vector3f &_dataSize, const vector2f &_texSize, TextureSampleMode _sampleMode, bool _generateMipmaps, bool _allowCompression, bool _useAnisotropicFiltering, unsigned int _numberOfMipMaps, TextureType _textureType) :
|
||||
format(_format),
|
||||
dataSize(_dataSize),
|
||||
texSize(_texSize),
|
||||
|
@ -88,7 +91,7 @@ namespace Graphics {
|
|||
vector2f GetOriginalSize() const { return vector2f(dataSize.x * texSize.x, dataSize.y * texSize.y); }
|
||||
|
||||
const TextureFormat format;
|
||||
const vector2f dataSize;
|
||||
const vector3f dataSize;
|
||||
const vector2f texSize;
|
||||
const TextureSampleMode sampleMode;
|
||||
const bool generateMipmaps;
|
||||
|
@ -100,7 +103,7 @@ namespace Graphics {
|
|||
TextureDescriptor &operator=(const TextureDescriptor &o)
|
||||
{
|
||||
const_cast<TextureFormat &>(format) = o.format;
|
||||
const_cast<vector2f &>(dataSize) = o.dataSize;
|
||||
const_cast<vector3f&>(dataSize) = o.dataSize;
|
||||
const_cast<vector2f &>(texSize) = o.texSize;
|
||||
const_cast<TextureSampleMode &>(sampleMode) = o.sampleMode;
|
||||
const_cast<bool &>(generateMipmaps) = o.generateMipmaps;
|
||||
|
@ -116,12 +119,14 @@ namespace Graphics {
|
|||
public:
|
||||
const TextureDescriptor &GetDescriptor() const { return m_descriptor; }
|
||||
|
||||
virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0;
|
||||
virtual void Update(const void *data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0)
|
||||
virtual void Update(const void *data, const vector2f &pos, const vector3f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0;
|
||||
virtual void Update(const void *data, const vector3f &dataSize, TextureFormat format, const unsigned int numMips = 0)
|
||||
{
|
||||
Update(data, vector2f(0, 0), dataSize, format, numMips);
|
||||
}
|
||||
virtual void Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0;
|
||||
virtual void Update(const TextureCubeData &data, const vector3f &dataSize, TextureFormat format, const unsigned int numMips = 0) = 0;
|
||||
typedef std::vector<void *> vecDataPtr;
|
||||
virtual void Update(const vecDataPtr &data, const vector3f &dataSize, const TextureFormat format, const unsigned int numMips = 0) = 0;
|
||||
virtual void SetSampleMode(TextureSampleMode) = 0;
|
||||
virtual void BuildMipmaps() = 0;
|
||||
virtual uint32_t GetTextureID() const = 0;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "utils.h"
|
||||
#include <SDL_image.h>
|
||||
#include <SDL_rwops.h>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
// XXX SDL2 can all this be replaced with SDL_GL_BindTexture?
|
||||
|
@ -24,12 +25,12 @@ namespace Graphics {
|
|||
m_compressTextures(compressTextures),
|
||||
m_anisotropicFiltering(anisoFiltering),
|
||||
m_textureType(TEXTURE_2D),
|
||||
m_prepared(false)
|
||||
m_prepared(false),
|
||||
m_layers(1)
|
||||
{
|
||||
}
|
||||
|
||||
TextureBuilder::TextureBuilder(const std::string &filename, TextureSampleMode sampleMode, bool generateMipmaps, bool potExtend, bool forceRGBA, bool compressTextures, bool anisoFiltering, TextureType textureType) :
|
||||
m_filename(filename),
|
||||
TextureBuilder::TextureBuilder(const std::string &filename, TextureSampleMode sampleMode, bool generateMipmaps, bool potExtend, bool forceRGBA, bool compressTextures, bool anisoFiltering, TextureType textureType, const size_t layers) :
|
||||
m_sampleMode(sampleMode),
|
||||
m_generateMipmaps(generateMipmaps),
|
||||
m_potExtend(potExtend),
|
||||
|
@ -37,7 +38,23 @@ namespace Graphics {
|
|||
m_compressTextures(compressTextures),
|
||||
m_anisotropicFiltering(anisoFiltering),
|
||||
m_textureType(textureType),
|
||||
m_prepared(false)
|
||||
m_prepared(false),
|
||||
m_layers(layers)
|
||||
{
|
||||
m_filenames.push_back(filename);
|
||||
}
|
||||
|
||||
TextureBuilder::TextureBuilder(const std::vector<std::string> &filenames, TextureSampleMode sampleMode, bool generateMipmaps, bool potExtend, bool forceRGBA, bool compressTextures, bool anisoFiltering, TextureType textureType, const size_t layers) :
|
||||
m_filenames(filenames),
|
||||
m_sampleMode(sampleMode),
|
||||
m_generateMipmaps(generateMipmaps),
|
||||
m_potExtend(potExtend),
|
||||
m_forceRGBA(forceRGBA),
|
||||
m_compressTextures(compressTextures),
|
||||
m_anisotropicFiltering(anisoFiltering),
|
||||
m_textureType(textureType),
|
||||
m_prepared(false),
|
||||
m_layers(layers)
|
||||
{
|
||||
assert(!m_filename.empty());
|
||||
}
|
||||
|
@ -114,8 +131,8 @@ namespace Graphics {
|
|||
PROFILE_SCOPED()
|
||||
if (m_prepared) return;
|
||||
|
||||
if (!m_surface && !m_filename.empty()) {
|
||||
std::string filename = m_filename;
|
||||
if (!m_surface && !m_filenames.empty()) {
|
||||
std::string filename = m_filenames.front();
|
||||
std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower);
|
||||
if (ends_with_ci(filename, ".dds")) {
|
||||
LoadDDS();
|
||||
|
@ -174,37 +191,58 @@ namespace Graphics {
|
|||
assert(0);
|
||||
}
|
||||
}
|
||||
} else if (!m_filename.empty()) {
|
||||
} else if (!m_filenames.front().empty()) {
|
||||
// power-of-two check
|
||||
unsigned long width = ceil_pow2(m_surface->w);
|
||||
unsigned long height = ceil_pow2(m_surface->h);
|
||||
|
||||
if (width != virtualWidth || height != virtualHeight)
|
||||
Output("WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filename.c_str());
|
||||
Output("WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filenames.front().c_str());
|
||||
}
|
||||
} else {
|
||||
switch (m_dds.GetTextureFormat()) {
|
||||
case PicoDDS::FORMAT_DXT1: targetTextureFormat = TEXTURE_DXT1; break;
|
||||
case PicoDDS::FORMAT_DXT5: targetTextureFormat = TEXTURE_DXT5; break;
|
||||
default:
|
||||
Output("ERROR: DDS texture with invalid format '%s' (only DXT1 and DXT5 are supported)\n", m_filename.c_str());
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
if(m_textureType != TEXTURE_2D_ARRAY) {
|
||||
switch (m_dds.GetTextureFormat()) {
|
||||
case PicoDDS::FORMAT_DXT1: targetTextureFormat = TEXTURE_DXT1; break;
|
||||
case PicoDDS::FORMAT_DXT5: targetTextureFormat = TEXTURE_DXT5; break;
|
||||
default:
|
||||
Output("ERROR: DDS texture with invalid format '%s' (only DXT1 and DXT5 are supported)\n", m_filenames.front().c_str());
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
virtualWidth = actualWidth = m_dds.imgdata_.width;
|
||||
virtualHeight = actualHeight = m_dds.imgdata_.height;
|
||||
numberOfMipMaps = m_dds.imgdata_.numMipMaps;
|
||||
numberOfImages = m_dds.imgdata_.numImages;
|
||||
if (m_textureType == TEXTURE_CUBE_MAP) {
|
||||
// Cube map must be fully defined (6 images) to be used correctly
|
||||
assert(numberOfImages == 6);
|
||||
virtualWidth = actualWidth = m_dds.imgdata_.width;
|
||||
virtualHeight = actualHeight = m_dds.imgdata_.height;
|
||||
numberOfMipMaps = m_dds.imgdata_.numMipMaps;
|
||||
numberOfImages = m_dds.imgdata_.numImages;
|
||||
if (m_textureType == TEXTURE_CUBE_MAP) {
|
||||
// Cube map must be fully defined (6 images) to be used correctly
|
||||
assert(numberOfImages == 6);
|
||||
}
|
||||
} else if(m_textureType == TEXTURE_2D_ARRAY) {
|
||||
assert(m_ddsarray.size() == m_layers);
|
||||
assert(m_layers>0);
|
||||
switch(m_ddsarray[0].GetTextureFormat()) {
|
||||
case PicoDDS::FORMAT_DXT1: targetTextureFormat = TEXTURE_DXT1; break;
|
||||
case PicoDDS::FORMAT_DXT5: targetTextureFormat = TEXTURE_DXT5; break;
|
||||
default:
|
||||
Output("ERROR: DDS texture with invalid format '%s' (only DXT1 and DXT5 are supported)\n", m_filenames.front().c_str());
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
for(size_t i=0; i<m_layers; i++) {
|
||||
const PicoDDS::DDSImage &dds = m_ddsarray[0];
|
||||
virtualWidth = actualWidth = dds.imgdata_.width;
|
||||
virtualHeight = actualHeight = dds.imgdata_.height;
|
||||
numberOfMipMaps = dds.imgdata_.numMipMaps;
|
||||
numberOfImages += dds.imgdata_.numImages;
|
||||
}
|
||||
assert((numberOfImages-1) == m_layers);
|
||||
}
|
||||
}
|
||||
|
||||
m_descriptor = TextureDescriptor(
|
||||
targetTextureFormat,
|
||||
vector2f(actualWidth, actualHeight),
|
||||
vector3f(actualWidth,actualHeight,m_layers),
|
||||
vector2f(float(virtualWidth) / float(actualWidth), float(virtualHeight) / float(actualHeight)),
|
||||
m_sampleMode, m_generateMipmaps, m_compressTextures, m_anisotropicFiltering, numberOfMipMaps, m_textureType);
|
||||
|
||||
|
@ -230,12 +268,14 @@ namespace Graphics {
|
|||
|
||||
SDLSurfacePtr s;
|
||||
if (m_textureType == TEXTURE_2D) {
|
||||
s = LoadSurfaceFromFile(m_filename);
|
||||
s = LoadSurfaceFromFile(m_filenames.front());
|
||||
if (!s) {
|
||||
s = LoadSurfaceFromFile("textures/unknown.png");
|
||||
}
|
||||
} else if (m_textureType == TEXTURE_CUBE_MAP) {
|
||||
Output("LoadSurface: %s: cannot load non-DDS cubemaps\n", m_filename.c_str());
|
||||
Output("LoadSurface: %s: cannot load non-DDS cubemaps\n", m_filenames.front().c_str());
|
||||
} else if(m_textureType == TEXTURE_2D_ARRAY) {
|
||||
Output("LoadSurface: %s: cannot load non-DDS texture array files\n", m_filenames.front().c_str());
|
||||
}
|
||||
|
||||
// XXX if we can't load the fallback texture, then what?
|
||||
|
@ -245,11 +285,25 @@ namespace Graphics {
|
|||
|
||||
void TextureBuilder::LoadDDS()
|
||||
{
|
||||
assert(!m_surface);
|
||||
assert(!m_dds.headerdone_);
|
||||
LoadDDSFromFile(m_filename, m_dds);
|
||||
if(m_textureType != TEXTURE_2D_ARRAY)
|
||||
{
|
||||
LoadDDSFromFile(m_filenames.front(), m_dds);
|
||||
|
||||
if (!m_dds.headerdone_) {
|
||||
m_surface = LoadSurfaceFromFile("textures/unknown.png");
|
||||
if (!m_dds.headerdone_) {
|
||||
m_surface = LoadSurfaceFromFile("textures/unknown.png");
|
||||
}
|
||||
} else if(m_textureType == TEXTURE_2D_ARRAY)
|
||||
{
|
||||
m_ddsarray.clear();
|
||||
const size_t layers = m_layers;
|
||||
m_ddsarray.resize(layers);
|
||||
|
||||
for (int i = 0; i < layers; i++)
|
||||
{
|
||||
PiVerify(LoadDDSFromFile(m_filenames[i], m_ddsarray[i]));
|
||||
}
|
||||
}
|
||||
// XXX if we can't load the fallback texture, then what?
|
||||
}
|
||||
|
@ -258,7 +312,7 @@ namespace Graphics {
|
|||
{
|
||||
if (m_surface) {
|
||||
if (texture->GetDescriptor().type == TEXTURE_2D && m_textureType == TEXTURE_2D) {
|
||||
texture->Update(m_surface->pixels, vector2f(m_surface->w, m_surface->h), m_descriptor.format, 0);
|
||||
texture->Update(m_surface->pixels, vector3f(m_surface->w,m_surface->h,0.0f), m_descriptor.format, 0);
|
||||
} else if (texture->GetDescriptor().type == TEXTURE_CUBE_MAP && m_textureType == TEXTURE_CUBE_MAP) {
|
||||
assert(m_cubemap.size() == 6);
|
||||
TextureCubeData tcd;
|
||||
|
@ -269,16 +323,16 @@ namespace Graphics {
|
|||
tcd.negY = m_cubemap[3]->pixels;
|
||||
tcd.posZ = m_cubemap[4]->pixels;
|
||||
tcd.negZ = m_cubemap[5]->pixels;
|
||||
texture->Update(tcd, vector2f(m_cubemap[0]->w, m_cubemap[0]->h), m_descriptor.format, 0);
|
||||
texture->Update(tcd, vector3f(m_cubemap[0]->w, m_cubemap[0]->h,0.0f), m_descriptor.format, 0);
|
||||
} else {
|
||||
// Given texture and current texture don't have the same type!
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
} else if( m_dds.headerdone_ ) {
|
||||
assert(m_dds.headerdone_);
|
||||
assert(m_descriptor.format == TEXTURE_DXT1 || m_descriptor.format == TEXTURE_DXT5);
|
||||
if (texture->GetDescriptor().type == TEXTURE_2D && m_textureType == TEXTURE_2D) {
|
||||
texture->Update(m_dds.imgdata_.imgData, vector2f(m_dds.imgdata_.width, m_dds.imgdata_.height), m_descriptor.format, m_dds.imgdata_.numMipMaps);
|
||||
texture->Update(m_dds.imgdata_.imgData, vector3f(m_dds.imgdata_.width,m_dds.imgdata_.height,0.0f), m_descriptor.format, m_dds.imgdata_.numMipMaps);
|
||||
} else if (texture->GetDescriptor().type == TEXTURE_CUBE_MAP && m_textureType == TEXTURE_CUBE_MAP) {
|
||||
TextureCubeData tcd;
|
||||
// Size in bytes of each cube map face
|
||||
|
@ -290,11 +344,22 @@ namespace Graphics {
|
|||
tcd.negY = static_cast<void *>(m_dds.imgdata_.imgData + (3 * face_size));
|
||||
tcd.posZ = static_cast<void *>(m_dds.imgdata_.imgData + (4 * face_size));
|
||||
tcd.negZ = static_cast<void *>(m_dds.imgdata_.imgData + (5 * face_size));
|
||||
texture->Update(tcd, vector2f(m_dds.imgdata_.width, m_dds.imgdata_.height), m_descriptor.format, m_dds.imgdata_.numMipMaps);
|
||||
texture->Update(tcd, vector3f(m_dds.imgdata_.width, m_dds.imgdata_.height,0.0f), m_descriptor.format, m_dds.imgdata_.numMipMaps);
|
||||
} else {
|
||||
// Given texture and current texture don't have the same type!
|
||||
assert(0);
|
||||
}
|
||||
} else if( !m_ddsarray.empty() ) {
|
||||
// texture array
|
||||
assert(m_textureType == TEXTURE_2D_ARRAY);
|
||||
const TextureDescriptor &desc = texture->GetDescriptor();
|
||||
// virtual void Update(const vecDataPtr &data, const vector3f &dataSize, const TextureFormat format, const unsigned int numMips = 0) = 0;
|
||||
Texture::vecDataPtr dataPtrs;
|
||||
dataPtrs.reserve(m_layers);
|
||||
for(size_t i=0; i<m_layers; i++) {
|
||||
dataPtrs.push_back( m_ddsarray[i].imgdata_.imgData );
|
||||
}
|
||||
texture->Update(dataPtrs, desc.dataSize, desc.format, desc.numberOfMipMaps);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,14 @@ namespace Graphics {
|
|||
|
||||
class TextureBuilder {
|
||||
public:
|
||||
TextureBuilder(const SDLSurfacePtr &surface, TextureSampleMode sampleMode = LINEAR_CLAMP, bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true);
|
||||
TextureBuilder(const std::string &filename, TextureSampleMode sampleMode = LINEAR_CLAMP, bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true, TextureType textureType = TEXTURE_2D);
|
||||
TextureBuilder(const SDLSurfacePtr &surface, TextureSampleMode sampleMode = LINEAR_CLAMP,
|
||||
bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true);
|
||||
TextureBuilder(const std::string &filename, TextureSampleMode sampleMode = LINEAR_CLAMP,
|
||||
bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true,
|
||||
TextureType textureType = TEXTURE_2D, const size_t layers = 1);
|
||||
TextureBuilder(const std::vector<std::string> &filenames, TextureSampleMode sampleMode = LINEAR_CLAMP,
|
||||
bool generateMipmaps = false, bool potExtend = false, bool forceRGBA = true, bool compressTextures = true, bool anisoFiltering = true,
|
||||
TextureType textureType = TEXTURE_2D, const size_t layers = 1);
|
||||
~TextureBuilder();
|
||||
|
||||
static void Init();
|
||||
|
@ -51,6 +57,14 @@ namespace Graphics {
|
|||
{
|
||||
return TextureBuilder(filename, LINEAR_CLAMP, true, true, false, true, false, TEXTURE_CUBE_MAP);
|
||||
}
|
||||
static TextureBuilder LookUpTable(const std::string &filename)
|
||||
{
|
||||
return TextureBuilder(filename, NEAREST_CLAMP, false, true, true, false, false);
|
||||
}
|
||||
static TextureBuilder Array(const std::vector<std::string> &filenames, const size_t layers)
|
||||
{
|
||||
return TextureBuilder(filenames, LINEAR_REPEAT, true, true, false, true, true, TEXTURE_2D_ARRAY, layers);
|
||||
}
|
||||
|
||||
const TextureDescriptor &GetDescriptor()
|
||||
{
|
||||
|
@ -60,18 +74,17 @@ namespace Graphics {
|
|||
|
||||
Texture *GetOrCreateTexture(Renderer *r, const std::string &type)
|
||||
{
|
||||
PROFILE_SCOPED()
|
||||
if (m_filename.empty()) {
|
||||
if (m_filenames.empty()) {
|
||||
return CreateTexture(r);
|
||||
}
|
||||
SDL_LockMutex(m_textureLock);
|
||||
Texture *t = r->GetCachedTexture(type, m_filename);
|
||||
Texture *t = r->GetCachedTexture(type, m_filenames.front());
|
||||
if (t) {
|
||||
SDL_UnlockMutex(m_textureLock);
|
||||
return t;
|
||||
}
|
||||
t = CreateTexture(r);
|
||||
r->AddCachedTexture(type, m_filename, t);
|
||||
r->AddCachedTexture(type, m_filenames.front(), t);
|
||||
SDL_UnlockMutex(m_textureLock);
|
||||
return t;
|
||||
}
|
||||
|
@ -84,7 +97,8 @@ namespace Graphics {
|
|||
SDLSurfacePtr m_surface;
|
||||
std::vector<SDLSurfacePtr> m_cubemap;
|
||||
PicoDDS::DDSImage m_dds;
|
||||
std::string m_filename;
|
||||
std::vector<PicoDDS::DDSImage> m_ddsarray;
|
||||
std::vector<std::string> m_filenames;
|
||||
|
||||
TextureSampleMode m_sampleMode;
|
||||
bool m_generateMipmaps;
|
||||
|
@ -94,6 +108,7 @@ namespace Graphics {
|
|||
bool m_compressTextures;
|
||||
bool m_anisotropicFiltering;
|
||||
TextureType m_textureType;
|
||||
size_t m_layers;
|
||||
|
||||
TextureDescriptor m_descriptor;
|
||||
|
||||
|
|
|
@ -10,8 +10,9 @@ namespace Graphics {
|
|||
|
||||
class TextureDummy : public Texture {
|
||||
public:
|
||||
virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override {}
|
||||
virtual void Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override {}
|
||||
virtual void Update(const void *data, const vector2f &pos, const vector3f &dataSize, TextureFormat format, const unsigned int numMips) override final {}
|
||||
virtual void Update(const TextureCubeData &data, const vector3f &dataSize, TextureFormat format, const unsigned int numMips) override final {}
|
||||
virtual void Update(const vecDataPtr &data, const vector3f &dataSize, const TextureFormat format, const unsigned int numMips) override final {}
|
||||
|
||||
void Bind() override {}
|
||||
void Unbind() override {}
|
||||
|
|
|
@ -1073,7 +1073,7 @@ namespace Graphics {
|
|||
if (desc.colorFormat != TEXTURE_NONE) {
|
||||
Graphics::TextureDescriptor cdesc(
|
||||
desc.colorFormat,
|
||||
vector2f(desc.width, desc.height),
|
||||
vector3f(desc.width, desc.height, 0.0f),
|
||||
vector2f(desc.width, desc.height),
|
||||
LINEAR_CLAMP,
|
||||
false,
|
||||
|
@ -1087,7 +1087,7 @@ namespace Graphics {
|
|||
if (desc.allowDepthTexture) {
|
||||
Graphics::TextureDescriptor ddesc(
|
||||
TEXTURE_DEPTH,
|
||||
vector2f(desc.width, desc.height),
|
||||
vector3f(desc.width, desc.height, 0.0f),
|
||||
vector2f(desc.width, desc.height),
|
||||
LINEAR_CLAMP,
|
||||
false,
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace Graphics {
|
|||
switch (type) {
|
||||
case TEXTURE_2D: return GL_TEXTURE_2D;
|
||||
case TEXTURE_CUBE_MAP: return GL_TEXTURE_CUBE_MAP;
|
||||
case TEXTURE_2D_ARRAY: return GL_TEXTURE_2D_ARRAY;
|
||||
default: assert(0); return 0;
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +198,46 @@ namespace Graphics {
|
|||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
if(!IsCompressed(descriptor.format)) {
|
||||
if(descriptor.generateMipmaps) {
|
||||
glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
}
|
||||
RendererOGL::CheckErrors();
|
||||
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format),
|
||||
descriptor.dataSize.x, descriptor.dataSize.y, descriptor.dataSize.z, 0,
|
||||
GLImageFormat(descriptor.format),
|
||||
GLImageType(descriptor.format), nullptr);
|
||||
RendererOGL::CheckErrors();
|
||||
|
||||
if (descriptor.generateMipmaps) {
|
||||
glGenerateMipmap(m_target);
|
||||
}
|
||||
} else {
|
||||
const GLint oglFormatMinSize = GetMinSize(descriptor.format);
|
||||
size_t Width = descriptor.dataSize.x;
|
||||
size_t Height = descriptor.dataSize.y;
|
||||
const size_t Layers = descriptor.dataSize.z;
|
||||
size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * oglFormatMinSize;
|
||||
|
||||
GLint maxMip = 0;
|
||||
for( unsigned int i=0; i < descriptor.numberOfMipMaps; ++i ) {
|
||||
maxMip = i;
|
||||
glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, i, GLInternalFormat(descriptor.format), Width, Height, Layers, 0, bufSize * Layers, nullptr);
|
||||
RendererOGL::CheckErrors();
|
||||
if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) {
|
||||
break;
|
||||
}
|
||||
bufSize /= 4;
|
||||
Width /= 2;
|
||||
Height /= 2;
|
||||
}
|
||||
glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, maxMip);
|
||||
}
|
||||
RendererOGL::CheckErrors();
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
@ -251,7 +292,7 @@ namespace Graphics {
|
|||
glDeleteTextures(1, &m_texture);
|
||||
}
|
||||
|
||||
void TextureGL::Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips)
|
||||
void TextureGL::Update(const void *data, const vector2f &pos, const vector3f &dataSize, TextureFormat format, const unsigned int numMips)
|
||||
{
|
||||
PROFILE_SCOPED()
|
||||
assert(m_target == GL_TEXTURE_2D);
|
||||
|
@ -294,7 +335,7 @@ namespace Graphics {
|
|||
CHECKERRORS();
|
||||
}
|
||||
|
||||
void TextureGL::Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips)
|
||||
void TextureGL::Update(const TextureCubeData &data, const vector3f &dataSize, TextureFormat format, const unsigned int numMips)
|
||||
{
|
||||
PROFILE_SCOPED()
|
||||
assert(m_target == GL_TEXTURE_CUBE_MAP);
|
||||
|
@ -352,6 +393,73 @@ namespace Graphics {
|
|||
CHECKERRORS();
|
||||
}
|
||||
|
||||
void TextureGL::Update(const vecDataPtr &data, const vector3f &dataSize, const TextureFormat format, const unsigned int numMips)
|
||||
{
|
||||
assert(m_target == GL_TEXTURE_2D_ARRAY);
|
||||
|
||||
glBindTexture(m_target, m_texture);
|
||||
RendererOGL::CheckErrors();
|
||||
|
||||
const size_t Layers = dataSize.z;
|
||||
assert(Layers == data.size());
|
||||
|
||||
if (!IsCompressed(format)) {
|
||||
for(size_t i = 0; i < Layers; i++) {
|
||||
glTexSubImage3D(
|
||||
GL_TEXTURE_2D_ARRAY, // GLenum target,
|
||||
0, // GLint level, // mip
|
||||
0, // GLint xoffset,
|
||||
0, // GLint yoffset,
|
||||
i, // GLint zoffset,
|
||||
dataSize.x, // GLsizei width,
|
||||
dataSize.y, // GLsizei height,
|
||||
1, // GLsizei depth,
|
||||
GLImageFormat(format), // GLenum format,
|
||||
GLImageType(format), // GLenum type,
|
||||
data[i]); // const GLvoid * data);
|
||||
}
|
||||
RendererOGL::CheckErrors();
|
||||
} else {
|
||||
const GLint oglInternalFormat = GLImageFormat(format);
|
||||
for(size_t ilayer = 0; ilayer < Layers; ilayer++) {
|
||||
size_t Offset = 0;
|
||||
size_t Width = dataSize.x;
|
||||
size_t Height = dataSize.y;
|
||||
size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * GetMinSize(format);
|
||||
|
||||
const unsigned char *pData = static_cast<const unsigned char*>(data[ilayer]);
|
||||
for( unsigned int i = 0; i < numMips; ++i ) {
|
||||
glCompressedTexSubImage3D(
|
||||
m_target, // GLenum target,
|
||||
i, // GLint level,
|
||||
0, // GLint xoffset,
|
||||
0, // GLint yoffset,
|
||||
ilayer, // GLint zoffset,
|
||||
Width, // GLsizei width,
|
||||
Height, // GLsizei height,
|
||||
1, // GLsizei depth,
|
||||
oglInternalFormat, // GLenum format,
|
||||
bufSize, // GLsizei imageSize,
|
||||
&pData[Offset]); // const GLvoid * data);
|
||||
if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) {
|
||||
break;
|
||||
}
|
||||
Offset += bufSize;
|
||||
bufSize /= 4;
|
||||
Width /= 2;
|
||||
Height /= 2;
|
||||
}
|
||||
RendererOGL::CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
if (GetDescriptor().generateMipmaps)
|
||||
glGenerateMipmap(m_target);
|
||||
|
||||
RendererOGL::CheckErrors();
|
||||
glBindTexture(m_target, 0);
|
||||
}
|
||||
|
||||
void TextureGL::Bind()
|
||||
{
|
||||
glBindTexture(m_target, m_texture);
|
||||
|
|
|
@ -11,8 +11,9 @@ namespace Graphics {
|
|||
namespace OGL {
|
||||
class TextureGL : public Texture {
|
||||
public:
|
||||
virtual void Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override final;
|
||||
virtual void Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) override final;
|
||||
virtual void Update(const void *data, const vector2f &pos, const vector3f &dataSize, TextureFormat format, const unsigned int numMips) override final;
|
||||
virtual void Update(const TextureCubeData &data, const vector3f &dataSize, TextureFormat format, const unsigned int numMips) override final;
|
||||
virtual void Update(const vecDataPtr &data, const vector3f &dataSize, const TextureFormat format, const unsigned int numMips) override final;
|
||||
|
||||
TextureGL(const TextureDescriptor &descriptor, const bool useCompressed, const bool useAnisoFiltering);
|
||||
virtual ~TextureGL();
|
||||
|
|
|
@ -356,7 +356,7 @@ void *PiGui::makeTexture(unsigned char *pixels, int width, int height)
|
|||
// Texture descriptor defines the size, type.
|
||||
// Gone for LINEAR_CLAMP here and RGBA like the original code
|
||||
const vector2f texSize(1.0f, 1.0f);
|
||||
const vector2f dataSize(width, height);
|
||||
const vector3f dataSize(width, height, 0.0f);
|
||||
const Graphics::TextureDescriptor texDesc(Graphics::TEXTURE_RGBA_8888,
|
||||
dataSize, texSize, Graphics::LINEAR_CLAMP,
|
||||
false, false, false, 0, Graphics::TEXTURE_2D);
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace SceneGraph {
|
|||
AddColor(w, a, colors);
|
||||
AddColor(w, b, colors);
|
||||
AddColor(w, c, colors);
|
||||
vector2f size(colors.size() / 3, 1.f);
|
||||
const vector3f size(colors.size() / 3, 1.f, 0.0f);
|
||||
|
||||
const Graphics::TextureFormat format = Graphics::TEXTURE_RGB_888;
|
||||
|
||||
|
|
|
@ -527,7 +527,7 @@ namespace Text {
|
|||
glyph.texWidth = float(glyph.width) / float(ATLAS_SIZE);
|
||||
glyph.texHeight = float(glyph.height) / float(ATLAS_SIZE);
|
||||
|
||||
m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector2f(glyph.width, glyph.height), m_texFormat);
|
||||
m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector3f(glyph.width, glyph.height, 0.0f), m_texFormat);
|
||||
|
||||
m_atlasU += bmStrokeGlyph->bitmap.width;
|
||||
|
||||
|
@ -566,7 +566,7 @@ namespace Text {
|
|||
glyph.texWidth = float(glyph.width) / float(ATLAS_SIZE);
|
||||
glyph.texHeight = float(glyph.height) / float(ATLAS_SIZE);
|
||||
|
||||
m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector2f(glyph.width, glyph.height), m_texFormat);
|
||||
m_texture->Update(&m_buf[0], vector2f(m_atlasU, m_atlasV), vector3f(glyph.width, glyph.height, 0.0f), m_texFormat);
|
||||
|
||||
m_atlasU += glyph.width;
|
||||
}
|
||||
|
@ -624,13 +624,13 @@ namespace Text {
|
|||
desc.vertexColors = true; //to allow per-character colors
|
||||
desc.textures = 1;
|
||||
m_mat.reset(m_renderer->CreateMaterial(desc));
|
||||
Graphics::TextureDescriptor textureDescriptor(m_texFormat, vector2f(ATLAS_SIZE), Graphics::NEAREST_CLAMP, false, false, false, 0, Graphics::TEXTURE_2D);
|
||||
Graphics::TextureDescriptor textureDescriptor(m_texFormat, vector3f(ATLAS_SIZE, ATLAS_SIZE, 0.0f), Graphics::NEAREST_CLAMP, false, false, false, 0, Graphics::TEXTURE_2D);
|
||||
m_texture.Reset(m_renderer->CreateTexture(textureDescriptor));
|
||||
{
|
||||
const size_t sz = m_bpp * ATLAS_SIZE * ATLAS_SIZE;
|
||||
char *buf = static_cast<char *>(malloc(sz));
|
||||
memset(buf, 0, sz);
|
||||
m_texture->Update(buf, vector2f(0.0f, 0.0f), vector2f(ATLAS_SIZE, ATLAS_SIZE), m_texFormat);
|
||||
m_texture->Update(buf, vector2f(0.0f, 0.0f), vector3f(ATLAS_SIZE, ATLAS_SIZE, 0.0f), m_texFormat);
|
||||
free(buf);
|
||||
}
|
||||
m_mat->texture0 = m_texture.Get();
|
||||
|
|
Loading…
Reference in New Issue