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
*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)
{
u8 * sB = (u8 *)sP;
......@@ -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)
{
u8 * sB = (u8 *)sP;
......
......@@ -67,6 +67,7 @@ public:
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_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_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP);
......@@ -76,6 +77,7 @@ public:
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_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_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP);
......
......@@ -458,7 +458,12 @@ public:
}
}
// Shaders
// Shaders calls.
void getProgram(GLuint& programID) const
{
programID = ProgramID;
}
void setProgram(GLuint programID)
{
......@@ -471,6 +476,11 @@ public:
// Texture calls.
void getActiveTexture(GLenum& texture) const
{
texture = ActiveTexture;
}
void setActiveTexture(GLenum texture)
{
if (ActiveTexture != texture)
......@@ -482,6 +492,14 @@ public:
// 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)
{
if (ViewportX != viewportX || ViewportY != viewportY || ViewportWidth != viewportWidth || ViewportHeight != viewportHeight)
......
......@@ -14,6 +14,7 @@
#include "ITexture.h"
#include "EDriverFeatures.h"
#include "os.h"
#include "CColorConverter.h"
namespace irr
{
......@@ -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),
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)
{
_IRR_DEBUG_BREAK_IF(image.size() == 0)
......@@ -158,11 +159,11 @@ public:
if (TextureName)
glDeleteTextures(1, &TextureName);
for (u32 i = 0; i < Image.size(); ++i)
Image[i]->drop();
if (LockImage)
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_
......@@ -175,9 +176,86 @@ public:
LockReadOnly |= (mode == ETLM_READ_ONLY);
LockLevel = mipmapLevel;
LockImage = Image[0];
if (LockImage)
return LockImage->getData();
return LockImage->getData();
if (KeepImage && mipmapLevel == 0)
{
LockImage = Image[0];
LockImage->grab();
}
else
{
const core::dimension2d<u32> lockImageSize(Size.Width >> mipmapLevel, Size.Height >> mipmapLevel);
LockImage = Driver->createImage(ColorFormat, lockImageSize);
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_
......@@ -198,8 +276,7 @@ public:
regenerateMipMapLevels(LockImage->getMipMapsData());
}
if (!KeepImage || LockLevel != 0)
LockImage->drop();
LockImage->drop();
LockReadOnly = false;
LockImage = 0;
......
This diff is collapsed.
......@@ -151,6 +151,16 @@ namespace video
//! \param material: Material to be used from now on.
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
//! texture if desired.
void draw2DImageBatch(const video::ITexture* texture,
......@@ -160,11 +170,6 @@ namespace video
SColor color,
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
/** channel of the texture if desired. The images are drawn
beginning at pos and concatenated in one line. All drawings
......@@ -190,11 +195,6 @@ namespace video
SColor color=SColor(255,255,255,255),
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
virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
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