mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Implement support for array textures in GL driver
note: feature detection was not implemented in the legacy driver, but the code itself probably works.
This commit is contained in:
parent
d5bf094f9a
commit
46db688cc8
14 changed files with 111 additions and 72 deletions
|
@ -132,6 +132,9 @@ enum E_VIDEO_DRIVER_FEATURE
|
||||||
//! Support for multisample textures.
|
//! Support for multisample textures.
|
||||||
EVDF_TEXTURE_MULTISAMPLE,
|
EVDF_TEXTURE_MULTISAMPLE,
|
||||||
|
|
||||||
|
//! Support for 2D array textures.
|
||||||
|
EVDF_TEXTURE_2D_ARRAY,
|
||||||
|
|
||||||
//! Only used for counting the elements of this enum
|
//! Only used for counting the elements of this enum
|
||||||
EVDF_COUNT
|
EVDF_COUNT
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,7 +129,10 @@ enum E_TEXTURE_TYPE
|
||||||
ETT_2D_MS,
|
ETT_2D_MS,
|
||||||
|
|
||||||
//! Cubemap texture.
|
//! Cubemap texture.
|
||||||
ETT_CUBEMAP
|
ETT_CUBEMAP,
|
||||||
|
|
||||||
|
//! 2D array texture
|
||||||
|
ETT_2D_ARRAY
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Interface of a Video Driver dependent Texture.
|
//! Interface of a Video Driver dependent Texture.
|
||||||
|
|
|
@ -232,6 +232,15 @@ public:
|
||||||
information. */
|
information. */
|
||||||
virtual ITexture *addTexture(const io::path &name, IImage *image) = 0;
|
virtual ITexture *addTexture(const io::path &name, IImage *image) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an array texture from IImages.
|
||||||
|
* @param name A name for the texture.
|
||||||
|
* @param images Pointer to array of images
|
||||||
|
* @param count Number of images (must be at least 1)
|
||||||
|
* @return Pointer to the newly created texture
|
||||||
|
*/
|
||||||
|
virtual ITexture *addArrayTexture(const io::path &name, IImage **images, u32 count) = 0;
|
||||||
|
|
||||||
//! Creates a cubemap texture from loaded IImages.
|
//! Creates a cubemap texture from loaded IImages.
|
||||||
/** \param name A name for the texture. Later calls of getTexture() with this name will return this texture.
|
/** \param name A name for the texture. Later calls of getTexture() with this name will return this texture.
|
||||||
The name can _not_ be empty.
|
The name can _not_ be empty.
|
||||||
|
|
|
@ -294,25 +294,9 @@ u32 CNullDriver::getTextureCount() const
|
||||||
|
|
||||||
ITexture *CNullDriver::addTexture(const core::dimension2d<u32> &size, const io::path &name, ECOLOR_FORMAT format)
|
ITexture *CNullDriver::addTexture(const core::dimension2d<u32> &size, const io::path &name, ECOLOR_FORMAT format)
|
||||||
{
|
{
|
||||||
if (0 == name.size()) {
|
|
||||||
os::Printer::log("Could not create ITexture, texture needs to have a non-empty name.", ELL_WARNING);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
IImage *image = new CImage(format, size);
|
IImage *image = new CImage(format, size);
|
||||||
ITexture *t = 0;
|
ITexture *t = addTexture(name, image);
|
||||||
|
|
||||||
if (checkImage(image)) {
|
|
||||||
t = createDeviceDependentTexture(name, image);
|
|
||||||
}
|
|
||||||
|
|
||||||
image->drop();
|
image->drop();
|
||||||
|
|
||||||
if (t) {
|
|
||||||
addTexture(t);
|
|
||||||
t->drop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +313,8 @@ ITexture *CNullDriver::addTexture(const io::path &name, IImage *image)
|
||||||
ITexture *t = 0;
|
ITexture *t = 0;
|
||||||
|
|
||||||
if (checkImage(image)) {
|
if (checkImage(image)) {
|
||||||
t = createDeviceDependentTexture(name, image);
|
std::vector tmp { image };
|
||||||
|
t = createDeviceDependentTexture(name, ETT_2D, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t) {
|
if (t) {
|
||||||
|
@ -340,6 +325,27 @@ ITexture *CNullDriver::addTexture(const io::path &name, IImage *image)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ITexture *CNullDriver::addArrayTexture(const io::path &name, IImage **images, u32 count)
|
||||||
|
{
|
||||||
|
if (0 == name.size()) {
|
||||||
|
os::Printer::log("Could not create ITexture, texture needs to have a non-empty name.", ELL_WARNING);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is stupid but who cares
|
||||||
|
std::vector<IImage*> tmp(images, images + count);
|
||||||
|
|
||||||
|
ITexture *t = nullptr;
|
||||||
|
if (checkImage(tmp)) {
|
||||||
|
t = createDeviceDependentTexture(name, ETT_2D_ARRAY, tmp);
|
||||||
|
}
|
||||||
|
if (t) {
|
||||||
|
addTexture(t);
|
||||||
|
t->drop();
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
ITexture *CNullDriver::addTextureCubemap(const io::path &name, IImage *imagePosX, IImage *imageNegX, IImage *imagePosY,
|
ITexture *CNullDriver::addTextureCubemap(const io::path &name, IImage *imagePosX, IImage *imageNegX, IImage *imagePosY,
|
||||||
IImage *imageNegY, IImage *imagePosZ, IImage *imageNegZ)
|
IImage *imageNegY, IImage *imagePosZ, IImage *imageNegZ)
|
||||||
{
|
{
|
||||||
|
@ -357,7 +363,7 @@ ITexture *CNullDriver::addTextureCubemap(const io::path &name, IImage *imagePosX
|
||||||
imageArray.push_back(imageNegZ);
|
imageArray.push_back(imageNegZ);
|
||||||
|
|
||||||
if (checkImage(imageArray)) {
|
if (checkImage(imageArray)) {
|
||||||
t = createDeviceDependentTextureCubemap(name, imageArray);
|
t = createDeviceDependentTexture(name, ETT_CUBEMAP, imageArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t) {
|
if (t) {
|
||||||
|
@ -384,7 +390,7 @@ ITexture *CNullDriver::addTextureCubemap(const irr::u32 sideLen, const io::path
|
||||||
|
|
||||||
ITexture *t = 0;
|
ITexture *t = 0;
|
||||||
if (checkImage(imageArray)) {
|
if (checkImage(imageArray)) {
|
||||||
t = createDeviceDependentTextureCubemap(name, imageArray);
|
t = createDeviceDependentTexture(name, ETT_CUBEMAP, imageArray);
|
||||||
|
|
||||||
if (t) {
|
if (t) {
|
||||||
addTexture(t);
|
addTexture(t);
|
||||||
|
@ -479,7 +485,8 @@ video::ITexture *CNullDriver::loadTextureFromFile(io::IReadFile *file, const io:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (checkImage(image)) {
|
if (checkImage(image)) {
|
||||||
texture = createDeviceDependentTexture(hashName.size() ? hashName : file->getFileName(), image);
|
std::vector tmp { image };
|
||||||
|
texture = createDeviceDependentTexture(hashName.size() ? hashName : file->getFileName(), ETT_2D, tmp);
|
||||||
if (texture)
|
if (texture)
|
||||||
os::Printer::log("Loaded texture", file->getFileName(), ELL_DEBUG);
|
os::Printer::log("Loaded texture", file->getFileName(), ELL_DEBUG);
|
||||||
}
|
}
|
||||||
|
@ -519,18 +526,16 @@ video::ITexture *CNullDriver::findTexture(const io::path &filename)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITexture *CNullDriver::createDeviceDependentTexture(const io::path &name, IImage *image)
|
ITexture *CNullDriver::createDeviceDependentTexture(const io::path &name, E_TEXTURE_TYPE type,
|
||||||
|
const std::vector<IImage*> &images)
|
||||||
{
|
{
|
||||||
SDummyTexture *dummy = new SDummyTexture(name, ETT_2D);
|
if (type != ETT_2D && type != ETT_CUBEMAP)
|
||||||
dummy->setSize(image->getDimension());
|
return nullptr;
|
||||||
|
SDummyTexture *dummy = new SDummyTexture(name, type);
|
||||||
|
dummy->setSize(images[0]->getDimension());
|
||||||
return dummy;
|
return dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITexture *CNullDriver::createDeviceDependentTextureCubemap(const io::path &name, const std::vector<IImage*> &image)
|
|
||||||
{
|
|
||||||
return new SDummyTexture(name, ETT_CUBEMAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNullDriver::setRenderTargetEx(IRenderTarget *target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
|
bool CNullDriver::setRenderTargetEx(IRenderTarget *target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -883,6 +888,9 @@ bool CNullDriver::checkImage(const std::vector<IImage*> &image) const
|
||||||
auto lastSize = image[0]->getDimension();
|
auto lastSize = image[0]->getDimension();
|
||||||
|
|
||||||
for (size_t i = 0; i < image.size(); ++i) {
|
for (size_t i = 0; i < image.size(); ++i) {
|
||||||
|
if (!image[i])
|
||||||
|
return false;
|
||||||
|
|
||||||
ECOLOR_FORMAT format = image[i]->getColorFormat();
|
ECOLOR_FORMAT format = image[i]->getColorFormat();
|
||||||
auto size = image[i]->getDimension();
|
auto size = image[i]->getDimension();
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ public:
|
||||||
|
|
||||||
ITexture *addTexture(const io::path &name, IImage *image) override;
|
ITexture *addTexture(const io::path &name, IImage *image) override;
|
||||||
|
|
||||||
|
ITexture *addArrayTexture(const io::path &name, IImage **images, u32 count) override;
|
||||||
|
|
||||||
virtual ITexture *addTextureCubemap(const io::path &name, IImage *imagePosX, IImage *imageNegX, IImage *imagePosY,
|
virtual ITexture *addTextureCubemap(const io::path &name, IImage *imagePosX, IImage *imageNegX, IImage *imagePosY,
|
||||||
IImage *imageNegY, IImage *imagePosZ, IImage *imageNegZ) override;
|
IImage *imageNegY, IImage *imagePosZ, IImage *imageNegZ) override;
|
||||||
|
|
||||||
|
@ -549,9 +551,8 @@ protected:
|
||||||
//! adds a surface, not loaded or created by the Irrlicht Engine
|
//! adds a surface, not loaded or created by the Irrlicht Engine
|
||||||
void addTexture(ITexture *surface);
|
void addTexture(ITexture *surface);
|
||||||
|
|
||||||
virtual ITexture *createDeviceDependentTexture(const io::path &name, IImage *image);
|
virtual ITexture *createDeviceDependentTexture(const io::path &name, E_TEXTURE_TYPE type,
|
||||||
|
const std::vector<IImage*> &images);
|
||||||
virtual ITexture *createDeviceDependentTextureCubemap(const io::path &name, const std::vector<IImage*> &image);
|
|
||||||
|
|
||||||
//! checks triangle count and print warning if wrong
|
//! checks triangle count and print warning if wrong
|
||||||
bool checkPrimitiveCount(u32 prmcnt) const;
|
bool checkPrimitiveCount(u32 prmcnt) const;
|
||||||
|
|
|
@ -39,7 +39,8 @@ public:
|
||||||
|
|
||||||
COGLESCoreExtensionHandler() :
|
COGLESCoreExtensionHandler() :
|
||||||
MaxAnisotropy(1), MaxIndices(0xffff),
|
MaxAnisotropy(1), MaxIndices(0xffff),
|
||||||
MaxTextureSize(1), MaxTextureLODBias(0.f), StencilBuffer(false)
|
MaxTextureSize(1), MaxArrayTextureLayers(1),
|
||||||
|
MaxTextureLODBias(0.f), StencilBuffer(false)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < IRR_OGLES_Feature_Count; ++i)
|
for (u32 i = 0; i < IRR_OGLES_Feature_Count; ++i)
|
||||||
FeatureAvailable[i] = false;
|
FeatureAvailable[i] = false;
|
||||||
|
@ -87,6 +88,7 @@ protected:
|
||||||
u8 MaxAnisotropy;
|
u8 MaxAnisotropy;
|
||||||
u32 MaxIndices;
|
u32 MaxIndices;
|
||||||
u32 MaxTextureSize;
|
u32 MaxTextureSize;
|
||||||
|
u32 MaxArrayTextureLayers;
|
||||||
f32 MaxTextureLODBias;
|
f32 MaxTextureLODBias;
|
||||||
//! Minimal and maximal supported thickness for lines without smoothing
|
//! Minimal and maximal supported thickness for lines without smoothing
|
||||||
float DimAliasedLine[2];
|
float DimAliasedLine[2];
|
||||||
|
|
|
@ -110,7 +110,7 @@ public:
|
||||||
}
|
}
|
||||||
TEST_GL_ERROR(Driver);
|
TEST_GL_ERROR(Driver);
|
||||||
|
|
||||||
initTexture();
|
initTexture(tmpImages->size());
|
||||||
|
|
||||||
for (size_t i = 0; i < tmpImages->size(); ++i)
|
for (size_t i = 0; i < tmpImages->size(); ++i)
|
||||||
uploadTexture(i, 0, (*tmpImages)[i]->getData());
|
uploadTexture(i, 0, (*tmpImages)[i]->getData());
|
||||||
|
@ -142,6 +142,7 @@ public:
|
||||||
MipLevelStored(0)
|
MipLevelStored(0)
|
||||||
{
|
{
|
||||||
DriverType = Driver->getDriverType();
|
DriverType = Driver->getDriverType();
|
||||||
|
_IRR_DEBUG_BREAK_IF(Type == ETT_2D_ARRAY) // not supported by this constructor
|
||||||
TextureType = TextureTypeIrrToGL(Type);
|
TextureType = TextureTypeIrrToGL(Type);
|
||||||
HasMipMaps = false;
|
HasMipMaps = false;
|
||||||
IsRenderTarget = true;
|
IsRenderTarget = true;
|
||||||
|
@ -208,7 +209,7 @@ public:
|
||||||
StatesCache.WrapW = ETC_CLAMP_TO_EDGE;
|
StatesCache.WrapW = ETC_CLAMP_TO_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
initTexture();
|
initTexture(0);
|
||||||
|
|
||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
Driver->irrGlObjectLabel(GL_TEXTURE, TextureName, name.c_str());
|
Driver->irrGlObjectLabel(GL_TEXTURE, TextureName, name.c_str());
|
||||||
|
@ -265,7 +266,19 @@ public:
|
||||||
const bool use_gl_impl = Driver->Version.Spec != OpenGLSpec::ES;
|
const bool use_gl_impl = Driver->Version.Spec != OpenGLSpec::ES;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (use_gl_impl) {
|
if (Type == ETT_2D_ARRAY) {
|
||||||
|
|
||||||
|
// For OpenGL an array texture is basically just a 3D texture internally.
|
||||||
|
// So if we call glGetTexImage() we would download the entire array,
|
||||||
|
// except the caller only wants a single layer.
|
||||||
|
// To do this properly we could have to use glGetTextureSubImage() [4.5]
|
||||||
|
// or some trickery with glTextureView() [4.3].
|
||||||
|
// Also neither of those will work on GLES.
|
||||||
|
|
||||||
|
os::Printer::log("lock: read or read/write unimplemented for ETT_2D_ARRAY", ELL_WARNING);
|
||||||
|
passed = false;
|
||||||
|
|
||||||
|
} else if (use_gl_impl) {
|
||||||
|
|
||||||
IImage *tmpImage = LockImage;
|
IImage *tmpImage = LockImage;
|
||||||
|
|
||||||
|
@ -495,7 +508,7 @@ protected:
|
||||||
Pitch = Size.Width * IImage::getBitsPerPixelFromFormat(ColorFormat) / 8;
|
Pitch = Size.Width * IImage::getBitsPerPixelFromFormat(ColorFormat) / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initTexture()
|
void initTexture(u32 layers)
|
||||||
{
|
{
|
||||||
// Compressed textures cannot be pre-allocated and are initialized on upload
|
// Compressed textures cannot be pre-allocated and are initialized on upload
|
||||||
if (IImage::isCompressedFormat(ColorFormat)) {
|
if (IImage::isCompressedFormat(ColorFormat)) {
|
||||||
|
@ -554,6 +567,16 @@ protected:
|
||||||
TEST_GL_ERROR(Driver);
|
TEST_GL_ERROR(Driver);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ETT_2D_ARRAY:
|
||||||
|
if (Driver->getFeature().TexStorage) {
|
||||||
|
GL.TexStorage3D(TextureType, levels, InternalFormat,
|
||||||
|
Size.Width, Size.Height, layers);
|
||||||
|
} else {
|
||||||
|
GL.TexImage3D(TextureType, 0, InternalFormat,
|
||||||
|
Size.Width, Size.Height, layers, 0, PixelFormat, PixelType, 0);
|
||||||
|
}
|
||||||
|
TEST_GL_ERROR(Driver);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_IRR_DEBUG_BREAK_IF(1)
|
_IRR_DEBUG_BREAK_IF(1)
|
||||||
break;
|
break;
|
||||||
|
@ -591,12 +614,15 @@ protected:
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
case GL_TEXTURE_CUBE_MAP:
|
case GL_TEXTURE_CUBE_MAP:
|
||||||
GL.TexSubImage2D(tmpTextureType, level, 0, 0, width, height, PixelFormat, PixelType, tmpData);
|
GL.TexSubImage2D(tmpTextureType, level, 0, 0, width, height, PixelFormat, PixelType, tmpData);
|
||||||
TEST_GL_ERROR(Driver);
|
break;
|
||||||
|
case GL_TEXTURE_2D_ARRAY:
|
||||||
|
GL.TexSubImage3D(tmpTextureType, level, 0, 0, layer, width, height, 1, PixelFormat, PixelType, tmpData);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_IRR_DEBUG_BREAK_IF(1)
|
_IRR_DEBUG_BREAK_IF(1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
TEST_GL_ERROR(Driver);
|
||||||
|
|
||||||
delete tmpImage;
|
delete tmpImage;
|
||||||
} else {
|
} else {
|
||||||
|
@ -606,12 +632,12 @@ protected:
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
case GL_TEXTURE_CUBE_MAP:
|
case GL_TEXTURE_CUBE_MAP:
|
||||||
Driver->irrGlCompressedTexImage2D(tmpTextureType, level, InternalFormat, width, height, 0, dataSize, data);
|
Driver->irrGlCompressedTexImage2D(tmpTextureType, level, InternalFormat, width, height, 0, dataSize, data);
|
||||||
TEST_GL_ERROR(Driver);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_IRR_DEBUG_BREAK_IF(1)
|
_IRR_DEBUG_BREAK_IF(1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
TEST_GL_ERROR(Driver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,6 +650,8 @@ protected:
|
||||||
return GL_TEXTURE_2D_MULTISAMPLE;
|
return GL_TEXTURE_2D_MULTISAMPLE;
|
||||||
case ETT_CUBEMAP:
|
case ETT_CUBEMAP:
|
||||||
return GL_TEXTURE_CUBE_MAP;
|
return GL_TEXTURE_CUBE_MAP;
|
||||||
|
case ETT_2D_ARRAY:
|
||||||
|
return GL_TEXTURE_2D_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
os::Printer::log("COpenGLCoreTexture::TextureTypeIrrToGL unknown texture type", ELL_WARNING);
|
os::Printer::log("COpenGLCoreTexture::TextureTypeIrrToGL unknown texture type", ELL_WARNING);
|
||||||
|
|
|
@ -1609,20 +1609,9 @@ inline void COpenGLDriver::getGLTextureMatrix(GLfloat *o, const core::matrix4 &m
|
||||||
o[15] = 1.f;
|
o[15] = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITexture *COpenGLDriver::createDeviceDependentTexture(const io::path &name, IImage *image)
|
ITexture *COpenGLDriver::createDeviceDependentTexture(const io::path &name, E_TEXTURE_TYPE type, const std::vector<IImage*> &images)
|
||||||
{
|
{
|
||||||
std::vector tmp { image };
|
return new COpenGLTexture(name, images, ETT_2D, this);
|
||||||
|
|
||||||
COpenGLTexture *texture = new COpenGLTexture(name, tmp, ETT_2D, this);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
ITexture *COpenGLDriver::createDeviceDependentTextureCubemap(const io::path &name, const std::vector<IImage *> &image)
|
|
||||||
{
|
|
||||||
COpenGLTexture *texture = new COpenGLTexture(name, image, ETT_CUBEMAP, this);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void COpenGLDriver::disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag)
|
void COpenGLDriver::disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag)
|
||||||
|
|
|
@ -326,9 +326,7 @@ private:
|
||||||
//! inits the parts of the open gl driver used on all platforms
|
//! inits the parts of the open gl driver used on all platforms
|
||||||
bool genericDriverInit();
|
bool genericDriverInit();
|
||||||
|
|
||||||
ITexture *createDeviceDependentTexture(const io::path &name, IImage *image) override;
|
ITexture *createDeviceDependentTexture(const io::path &name, E_TEXTURE_TYPE type, const std::vector<IImage*> &images) override;
|
||||||
|
|
||||||
ITexture *createDeviceDependentTextureCubemap(const io::path &name, const std::vector<IImage *> &image) override;
|
|
||||||
|
|
||||||
//! creates a transposed matrix in supplied GLfloat array to pass to OpenGL
|
//! creates a transposed matrix in supplied GLfloat array to pass to OpenGL
|
||||||
inline void getGLMatrix(GLfloat gl_matrix[16], const core::matrix4 &m);
|
inline void getGLMatrix(GLfloat gl_matrix[16], const core::matrix4 &m);
|
||||||
|
|
|
@ -267,6 +267,7 @@ bool COpenGL3DriverBase::genericDriverInit(const core::dimension2d<u32> &screenS
|
||||||
DriverAttributes->setAttribute("MaxAnisotropy", MaxAnisotropy);
|
DriverAttributes->setAttribute("MaxAnisotropy", MaxAnisotropy);
|
||||||
DriverAttributes->setAttribute("MaxIndices", (s32)MaxIndices);
|
DriverAttributes->setAttribute("MaxIndices", (s32)MaxIndices);
|
||||||
DriverAttributes->setAttribute("MaxTextureSize", (s32)MaxTextureSize);
|
DriverAttributes->setAttribute("MaxTextureSize", (s32)MaxTextureSize);
|
||||||
|
DriverAttributes->setAttribute("MaxArrayTextureLayers", (s32)MaxArrayTextureLayers);
|
||||||
DriverAttributes->setAttribute("MaxTextureLODBias", MaxTextureLODBias);
|
DriverAttributes->setAttribute("MaxTextureLODBias", MaxTextureLODBias);
|
||||||
DriverAttributes->setAttribute("Version", 100 * Version.Major + Version.Minor);
|
DriverAttributes->setAttribute("Version", 100 * Version.Major + Version.Minor);
|
||||||
DriverAttributes->setAttribute("AntiAlias", AntiAlias);
|
DriverAttributes->setAttribute("AntiAlias", AntiAlias);
|
||||||
|
@ -1072,20 +1073,9 @@ void COpenGL3DriverBase::endDraw(const VertexType &vertexType)
|
||||||
GL.DisableVertexAttribArray(attr.Index);
|
GL.DisableVertexAttribArray(attr.Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
ITexture *COpenGL3DriverBase::createDeviceDependentTexture(const io::path &name, IImage *image)
|
ITexture *COpenGL3DriverBase::createDeviceDependentTexture(const io::path &name, E_TEXTURE_TYPE type, const std::vector<IImage*> &images)
|
||||||
{
|
{
|
||||||
std::vector<IImage*> tmp { image };
|
return new COpenGL3Texture(name, images, type, this);
|
||||||
|
|
||||||
COpenGL3Texture *texture = new COpenGL3Texture(name, tmp, ETT_2D, this);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
ITexture *COpenGL3DriverBase::createDeviceDependentTextureCubemap(const io::path &name, const std::vector<IImage*> &image)
|
|
||||||
{
|
|
||||||
COpenGL3Texture *texture = new COpenGL3Texture(name, image, ETT_CUBEMAP, this);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as COpenGLDriver::TextureFlipMatrix
|
// Same as COpenGLDriver::TextureFlipMatrix
|
||||||
|
|
|
@ -267,9 +267,8 @@ protected:
|
||||||
|
|
||||||
void chooseMaterial2D();
|
void chooseMaterial2D();
|
||||||
|
|
||||||
ITexture *createDeviceDependentTexture(const io::path &name, IImage *image) override;
|
ITexture *createDeviceDependentTexture(const io::path &name, E_TEXTURE_TYPE type,
|
||||||
|
const std::vector<IImage*> &images) override;
|
||||||
ITexture *createDeviceDependentTextureCubemap(const io::path &name, const std::vector<IImage*> &image) override;
|
|
||||||
|
|
||||||
//! Map Irrlicht wrap mode to OpenGL enum
|
//! Map Irrlicht wrap mode to OpenGL enum
|
||||||
GLint getTextureWrapMode(u8 clamp) const;
|
GLint getTextureWrapMode(u8 clamp) const;
|
||||||
|
|
|
@ -76,6 +76,8 @@ public:
|
||||||
return StencilBuffer;
|
return StencilBuffer;
|
||||||
case EVDF_TEXTURE_MULTISAMPLE:
|
case EVDF_TEXTURE_MULTISAMPLE:
|
||||||
return TextureMultisampleSupported;
|
return TextureMultisampleSupported;
|
||||||
|
case EVDF_TEXTURE_2D_ARRAY:
|
||||||
|
return Texture2DArraySupported;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -176,6 +178,7 @@ public:
|
||||||
bool AnisotropicFilterSupported = false;
|
bool AnisotropicFilterSupported = false;
|
||||||
bool BlendMinMaxSupported = false;
|
bool BlendMinMaxSupported = false;
|
||||||
bool TextureMultisampleSupported = false;
|
bool TextureMultisampleSupported = false;
|
||||||
|
bool Texture2DArraySupported = false;
|
||||||
bool KHRDebugSupported = false;
|
bool KHRDebugSupported = false;
|
||||||
u32 MaxLabelLength = 0;
|
u32 MaxLabelLength = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,6 +71,7 @@ void COpenGL3Driver::initFeatures()
|
||||||
LODBiasSupported = true;
|
LODBiasSupported = true;
|
||||||
BlendMinMaxSupported = true;
|
BlendMinMaxSupported = true;
|
||||||
TextureMultisampleSupported = true;
|
TextureMultisampleSupported = true;
|
||||||
|
Texture2DArraySupported = Version.Major >= 3 || queryExtension("GL_EXT_texture_array");
|
||||||
KHRDebugSupported = isVersionAtLeast(4, 6) || queryExtension("GL_KHR_debug");
|
KHRDebugSupported = isVersionAtLeast(4, 6) || queryExtension("GL_KHR_debug");
|
||||||
if (KHRDebugSupported)
|
if (KHRDebugSupported)
|
||||||
MaxLabelLength = GetInteger(GL.MAX_LABEL_LENGTH);
|
MaxLabelLength = GetInteger(GL.MAX_LABEL_LENGTH);
|
||||||
|
@ -88,6 +89,8 @@ void COpenGL3Driver::initFeatures()
|
||||||
MaxAnisotropy = GetInteger(GL.MAX_TEXTURE_MAX_ANISOTROPY);
|
MaxAnisotropy = GetInteger(GL.MAX_TEXTURE_MAX_ANISOTROPY);
|
||||||
MaxIndices = GetInteger(GL_MAX_ELEMENTS_INDICES);
|
MaxIndices = GetInteger(GL_MAX_ELEMENTS_INDICES);
|
||||||
MaxTextureSize = GetInteger(GL_MAX_TEXTURE_SIZE);
|
MaxTextureSize = GetInteger(GL_MAX_TEXTURE_SIZE);
|
||||||
|
if (Texture2DArraySupported)
|
||||||
|
MaxArrayTextureLayers = GetInteger(GL_MAX_ARRAY_TEXTURE_LAYERS);
|
||||||
GL.GetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &MaxTextureLODBias);
|
GL.GetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &MaxTextureLODBias);
|
||||||
GL.GetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);
|
GL.GetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);
|
||||||
DimAliasedPoint[0] = 1.0f;
|
DimAliasedPoint[0] = 1.0f;
|
||||||
|
|
|
@ -124,6 +124,7 @@ void COpenGLES2Driver::initFeatures()
|
||||||
AnisotropicFilterSupported = queryExtension("GL_EXT_texture_filter_anisotropic");
|
AnisotropicFilterSupported = queryExtension("GL_EXT_texture_filter_anisotropic");
|
||||||
BlendMinMaxSupported = (Version.Major >= 3) || FeatureAvailable[IRR_GL_EXT_blend_minmax];
|
BlendMinMaxSupported = (Version.Major >= 3) || FeatureAvailable[IRR_GL_EXT_blend_minmax];
|
||||||
TextureMultisampleSupported = isVersionAtLeast(3, 1);
|
TextureMultisampleSupported = isVersionAtLeast(3, 1);
|
||||||
|
Texture2DArraySupported = Version.Major >= 3 || queryExtension("GL_EXT_texture_array");
|
||||||
KHRDebugSupported = queryExtension("GL_KHR_debug");
|
KHRDebugSupported = queryExtension("GL_KHR_debug");
|
||||||
if (KHRDebugSupported)
|
if (KHRDebugSupported)
|
||||||
MaxLabelLength = GetInteger(GL.MAX_LABEL_LENGTH);
|
MaxLabelLength = GetInteger(GL.MAX_LABEL_LENGTH);
|
||||||
|
@ -145,6 +146,8 @@ void COpenGLES2Driver::initFeatures()
|
||||||
if (Version.Major >= 3 || queryExtension("GL_EXT_draw_range_elements"))
|
if (Version.Major >= 3 || queryExtension("GL_EXT_draw_range_elements"))
|
||||||
MaxIndices = GetInteger(GL_MAX_ELEMENTS_INDICES);
|
MaxIndices = GetInteger(GL_MAX_ELEMENTS_INDICES);
|
||||||
MaxTextureSize = GetInteger(GL_MAX_TEXTURE_SIZE);
|
MaxTextureSize = GetInteger(GL_MAX_TEXTURE_SIZE);
|
||||||
|
if (Texture2DArraySupported)
|
||||||
|
MaxArrayTextureLayers = GetInteger(GL_MAX_ARRAY_TEXTURE_LAYERS);
|
||||||
if (LODBiasSupported)
|
if (LODBiasSupported)
|
||||||
GL.GetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &MaxTextureLODBias);
|
GL.GetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &MaxTextureLODBias);
|
||||||
GL.GetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);
|
GL.GetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue