Add basic texture array support

Add TextureBuilder overloads for array textures
master
Andrew Copland 2019-03-05 20:51:39 +00:00 committed by Webster Sheets
parent 43cd23b8dc
commit d29cdd1437
12 changed files with 262 additions and 67 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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 {}

View File

@ -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,

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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();