You need to sign in or sign up before continuing.
Commit c6fd504c authored by nadro's avatar nadro

- Improved COGLCoreTexture::lock method.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5177 dfc29bdd-3216-0410-991c-e03cc46cb475
parent e5b6e6af
...@@ -429,6 +429,25 @@ void CColorConverter::convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* d ...@@ -429,6 +429,25 @@ void CColorConverter::convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* d
*dB++ = A8R8G8B8toA1R5G5B5(*sB++); *dB++ = A8R8G8B8toA1R5G5B5(*sB++);
} }
void CColorConverter::convert_A8R8G8B8toA1B5G5R5(const void* sP, s32 sN, void* dP)
{
u8 * sB = (u8 *)sP;
u16* dB = (u16*)dP;
for (s32 x = 0; x < sN; ++x)
{
s32 r = sB[0] >> 3;
s32 g = sB[1] >> 3;
s32 b = sB[2] >> 3;
s32 a = sB[3] >> 3;
dB[0] = (a << 15) | (r << 10) | (g << 5) | (b);
sB += 4;
dB += 1;
}
}
void CColorConverter::convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP) void CColorConverter::convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP)
{ {
u8 * sB = (u8 *)sP; u8 * sB = (u8 *)sP;
...@@ -534,6 +553,18 @@ void CColorConverter::convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* d ...@@ -534,6 +553,18 @@ void CColorConverter::convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* d
} }
void CColorConverter::convert_A8R8G8B8toA8B8G8R8(const void* sP, s32 sN, void* dP)
{
const u32* sB = (const u32*)sP;
u32* dB = (u32*)dP;
for (s32 x = 0; x < sN; ++x)
{
*dB++ = (*sB & 0xff00ff00) | ((*sB & 0x00ff0000) >> 16) | ((*sB & 0x000000ff) << 16);
++sB;
}
}
void CColorConverter::convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP) void CColorConverter::convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP)
{ {
u8 * sB = (u8 *)sP; u8 * sB = (u8 *)sP;
......
...@@ -67,6 +67,7 @@ public: ...@@ -67,6 +67,7 @@ public:
static void convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP); static void convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP); static void convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP); static void convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA1B5G5R5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP); static void convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP); static void convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP);
...@@ -76,6 +77,7 @@ public: ...@@ -76,6 +77,7 @@ public:
static void convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP); static void convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP); static void convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP); static void convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA8B8G8R8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP); static void convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP); static void convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP);
......
...@@ -458,7 +458,12 @@ public: ...@@ -458,7 +458,12 @@ public:
} }
} }
// Shaders // Shaders calls.
void getProgram(GLuint& programID) const
{
programID = ProgramID;
}
void setProgram(GLuint programID) void setProgram(GLuint programID)
{ {
...@@ -471,6 +476,11 @@ public: ...@@ -471,6 +476,11 @@ public:
// Texture calls. // Texture calls.
void getActiveTexture(GLenum& texture) const
{
texture = ActiveTexture;
}
void setActiveTexture(GLenum texture) void setActiveTexture(GLenum texture)
{ {
if (ActiveTexture != texture) if (ActiveTexture != texture)
...@@ -482,6 +492,14 @@ public: ...@@ -482,6 +492,14 @@ public:
// Viewport calls. // Viewport calls.
void getViewport(GLint& viewportX, GLint& viewportY, GLsizei& viewportWidth, GLsizei& viewportHeight) const
{
viewportX = ViewportX;
viewportY = ViewportY;
viewportWidth = ViewportWidth;
viewportHeight = ViewportHeight;
}
void setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight) void setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight)
{ {
if (ViewportX != viewportX || ViewportY != viewportY || ViewportWidth != viewportWidth || ViewportHeight != viewportHeight) if (ViewportX != viewportX || ViewportY != viewportY || ViewportWidth != viewportWidth || ViewportHeight != viewportHeight)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "ITexture.h" #include "ITexture.h"
#include "EDriverFeatures.h" #include "EDriverFeatures.h"
#include "os.h" #include "os.h"
#include "CColorConverter.h"
namespace irr namespace irr
{ {
...@@ -44,7 +45,7 @@ public: ...@@ -44,7 +45,7 @@ public:
}; };
COGLCoreTexture(const io::path& name, const core::array<IImage*>& image, TOGLDriver* driver) : ITexture(name), Driver(driver), TextureType(GL_TEXTURE_2D), COGLCoreTexture(const io::path& name, const core::array<IImage*>& image, TOGLDriver* driver) : ITexture(name), Driver(driver), TextureType(GL_TEXTURE_2D),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), LockReadOnly(false), LockImage(0), LockLevel(0), KeepImage(true), TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), LockReadOnly(false), LockImage(0), LockLevel(0), KeepImage(false),
AutoGenerateMipMaps(false) AutoGenerateMipMaps(false)
{ {
_IRR_DEBUG_BREAK_IF(image.size() == 0) _IRR_DEBUG_BREAK_IF(image.size() == 0)
...@@ -158,11 +159,11 @@ public: ...@@ -158,11 +159,11 @@ public:
if (TextureName) if (TextureName)
glDeleteTextures(1, &TextureName); glDeleteTextures(1, &TextureName);
for (u32 i = 0; i < Image.size(); ++i)
Image[i]->drop();
if (LockImage) if (LockImage)
LockImage->drop(); LockImage->drop();
for (u32 i = 0; i < Image.size(); ++i)
Image[i]->drop();
} }
virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel = 0) _IRR_OVERRIDE_ virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel = 0) _IRR_OVERRIDE_
...@@ -175,9 +176,86 @@ public: ...@@ -175,9 +176,86 @@ public:
LockReadOnly |= (mode == ETLM_READ_ONLY); LockReadOnly |= (mode == ETLM_READ_ONLY);
LockLevel = mipmapLevel; LockLevel = mipmapLevel;
if (LockImage)
return LockImage->getData();
if (KeepImage && mipmapLevel == 0)
{
LockImage = Image[0]; LockImage = Image[0];
LockImage->grab();
}
else
{
const core::dimension2d<u32> lockImageSize(Size.Width >> mipmapLevel, Size.Height >> mipmapLevel);
LockImage = Driver->createImage(ColorFormat, lockImageSize);
return LockImage->getData(); if (LockImage && mode != ETLM_WRITE_ONLY)
{
COGLCoreTexture* tmpTexture = new COGLCoreTexture("OGL_CORE_LOCK_TEXTURE", lockImageSize, ColorFormat, Driver);
GLuint tmpFBO = 0;
Driver->irrGlGenFramebuffers(1, &tmpFBO);
GLint prevViewportX = 0;
GLint prevViewportY = 0;
GLsizei prevViewportWidth = 0;
GLsizei prevViewportHeight = 0;
Driver->getCacheHandler()->getViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight);
Driver->getCacheHandler()->setViewport(0, 0, lockImageSize.Width, lockImageSize.Height);
GLuint prevFBO = 0;
Driver->getCacheHandler()->getFBO(prevFBO);
Driver->getCacheHandler()->setFBO(tmpFBO);
Driver->irrGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmpTexture->getOpenGLTextureName(), 0);
Driver->draw2DImage(this, true);
IImage* tmpImage = Driver->createImage(ECF_A8R8G8B8, lockImageSize);
glReadPixels(0, 0, lockImageSize.Width, lockImageSize.Height, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->getData());
Driver->getCacheHandler()->setFBO(prevFBO);
Driver->getCacheHandler()->setViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight);
Driver->irrGlDeleteFramebuffers(1, &tmpFBO);
delete tmpTexture;
void* src = tmpImage->getData();
void* dest = LockImage->getData();
bool passed = true;
switch (ColorFormat)
{
case ECF_A1R5G5B5:
CColorConverter::convert_A8R8G8B8toA1B5G5R5(src, tmpImage->getDimension().getArea(), dest);
break;
case ECF_R5G6B5:
CColorConverter::convert_A8R8G8B8toR5G6B5(src, tmpImage->getDimension().getArea(), dest);
break;
case ECF_R8G8B8:
CColorConverter::convert_A8R8G8B8toB8G8R8(src, tmpImage->getDimension().getArea(), dest);
break;
case ECF_A8R8G8B8:
CColorConverter::convert_A8R8G8B8toA8B8G8R8(src, tmpImage->getDimension().getArea(), dest);
break;
default:
passed = false;
break;
}
tmpImage->drop();
if (!passed)
{
LockImage->drop();
LockImage = 0;
}
}
}
return (LockImage) ? LockImage->getData() : 0;
} }
virtual void unlock() _IRR_OVERRIDE_ virtual void unlock() _IRR_OVERRIDE_
...@@ -198,7 +276,6 @@ public: ...@@ -198,7 +276,6 @@ public:
regenerateMipMapLevels(LockImage->getMipMapsData()); regenerateMipMapLevels(LockImage->getMipMapsData());
} }
if (!KeepImage || LockLevel != 0)
LockImage->drop(); LockImage->drop();
LockReadOnly = false; LockReadOnly = false;
......
This diff is collapsed.
...@@ -151,6 +151,16 @@ namespace video ...@@ -151,6 +151,16 @@ namespace video
//! \param material: Material to be used from now on. //! \param material: Material to be used from now on.
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_; virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color = SColor(255, 255, 255, 255), bool useAlphaChannelOfTexture = false) _IRR_OVERRIDE_;
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors = 0, bool useAlphaChannelOfTexture = false) _IRR_OVERRIDE_;
virtual void draw2DImage(const video::ITexture* texture, bool flip);
//! draws a set of 2d images, using a color and the alpha channel of the //! draws a set of 2d images, using a color and the alpha channel of the
//! texture if desired. //! texture if desired.
void draw2DImageBatch(const video::ITexture* texture, void draw2DImageBatch(const video::ITexture* texture,
...@@ -160,11 +170,6 @@ namespace video ...@@ -160,11 +170,6 @@ namespace video
SColor color, SColor color,
bool useAlphaChannelOfTexture) _IRR_OVERRIDE_; bool useAlphaChannelOfTexture) _IRR_OVERRIDE_;
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
//! draws a set of 2d images, using a color and the alpha //! draws a set of 2d images, using a color and the alpha
/** channel of the texture if desired. The images are drawn /** channel of the texture if desired. The images are drawn
beginning at pos and concatenated in one line. All drawings beginning at pos and concatenated in one line. All drawings
...@@ -190,11 +195,6 @@ namespace video ...@@ -190,11 +195,6 @@ namespace video
SColor color=SColor(255,255,255,255), SColor color=SColor(255,255,255,255),
bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_; bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
//! Draws a part of the texture into the rectangle.
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
//! draw an 2d rectangle //! draw an 2d rectangle
virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos, virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip = 0) _IRR_OVERRIDE_; const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment