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;
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_ virtual void unlock() _IRR_OVERRIDE_
...@@ -198,8 +276,7 @@ public: ...@@ -198,8 +276,7 @@ public:
regenerateMipMapLevels(LockImage->getMipMapsData()); regenerateMipMapLevels(LockImage->getMipMapsData());
} }
if (!KeepImage || LockLevel != 0) LockImage->drop();
LockImage->drop();
LockReadOnly = false; LockReadOnly = false;
LockImage = 0; LockImage = 0;
......
...@@ -1826,172 +1826,9 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo ...@@ -1826,172 +1826,9 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
} }
//! draws a set of 2d images, using a color and the alpha channel of the void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
//! texture if desired. const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, SColor color,
void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture, bool useAlphaChannelOfTexture)
const core::array<core::position2d<s32> >& positions,
const core::array<core::rect<s32> >& sourceRects,
const core::rect<s32>* clipRect,
SColor color,
bool useAlphaChannelOfTexture)
{
if (!texture)
return;
const u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
const core::dimension2d<u32>& ss = texture->getOriginalSize();
const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
disableTextures(1);
if (!CacheHandler->getTextureCache().set(0, texture))
return;
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
Quad2DVertices[0].Color = color;
Quad2DVertices[1].Color = color;
Quad2DVertices[2].Color = color;
Quad2DVertices[3].Color = color;
if (!FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra])
getColorBuffer(Quad2DVertices, 4, EVT_STANDARD);
CacheHandler->setClientState(true, false, true, true);
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].TCoords);
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos);
#ifdef GL_BGRA
const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4;
#else
const GLint colorSize=4;
#endif
if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Color);
else
{
_IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0);
glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
}
for (u32 i=0; i<drawCount; ++i)
{
if (!sourceRects[i].isValid())
continue;
core::position2d<s32> targetPos(positions[i]);
core::position2d<s32> sourcePos(sourceRects[i].UpperLeftCorner);
// This needs to be signed as it may go negative.
core::dimension2d<s32> sourceSize(sourceRects[i].getSize());
if (clipRect)
{
if (targetPos.X < clipRect->UpperLeftCorner.X)
{
sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
if (sourceSize.Width <= 0)
continue;
sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
targetPos.X = clipRect->UpperLeftCorner.X;
}
if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X)
{
sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
if (sourceSize.Width <= 0)
continue;
}
if (targetPos.Y < clipRect->UpperLeftCorner.Y)
{
sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
if (sourceSize.Height <= 0)
continue;
sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
targetPos.Y = clipRect->UpperLeftCorner.Y;
}
if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y)
{
sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
if (sourceSize.Height <= 0)
continue;
}
}
// clip these coordinates
if (targetPos.X<0)
{
sourceSize.Width += targetPos.X;
if (sourceSize.Width <= 0)
continue;
sourcePos.X -= targetPos.X;
targetPos.X = 0;
}
if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
{
sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
if (sourceSize.Width <= 0)
continue;
}
if (targetPos.Y<0)
{
sourceSize.Height += targetPos.Y;
if (sourceSize.Height <= 0)
continue;
sourcePos.Y -= targetPos.Y;
targetPos.Y = 0;
}
if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
{
sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
if (sourceSize.Height <= 0)
continue;
}
// ok, we've clipped everything.
// now draw it.
const core::rect<f32> tcoords(
sourcePos.X * invW,
sourcePos.Y * invH,
(sourcePos.X + sourceSize.Width) * invW,
(sourcePos.Y + sourceSize.Height) * invH);
const core::rect<s32> poss(targetPos, sourceSize);
Quad2DVertices[0].Pos = core::vector3df((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f);
Quad2DVertices[1].Pos = core::vector3df((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f);
Quad2DVertices[2].Pos = core::vector3df((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f);
Quad2DVertices[3].Pos = core::vector3df((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f);
Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, Quad2DIndices);
}
}
//! draws a 2d image, using a color and the alpha channel of the texture if
//! desired. The image is drawn at pos, clipped against clipRect (if != 0).
//! Only the subtexture defined by sourceRect is used.
void COpenGLDriver::draw2DImage(const video::ITexture* texture,
const core::position2d<s32>& pos,
const core::rect<s32>& sourceRect,
const core::rect<s32>* clipRect, SColor color,
bool useAlphaChannelOfTexture)
{ {
if (!texture) if (!texture)
return; return;
...@@ -1999,7 +1836,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, ...@@ -1999,7 +1836,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
if (!sourceRect.isValid()) if (!sourceRect.isValid())
return; return;
core::position2d<s32> targetPos(pos); core::position2d<s32> targetPos(destPos);
core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner); core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner);
// This needs to be signed as it may go negative. // This needs to be signed as it may go negative.
core::dimension2d<s32> sourceSize(sourceRect.getSize()); core::dimension2d<s32> sourceSize(sourceRect.getSize());
...@@ -2071,7 +1908,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, ...@@ -2071,7 +1908,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
targetPos.Y = 0; targetPos.Y = 0;
} }
if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) if (targetPos.Y + sourceSize.Height >(s32)renderTargetSize.Height)
{ {
sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
if (sourceSize.Height <= 0) if (sourceSize.Height <= 0)
...@@ -2085,10 +1922,10 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, ...@@ -2085,10 +1922,10 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords( const core::rect<f32> tcoords(
sourcePos.X * invW, sourcePos.X * invW,
sourcePos.Y * invH, sourcePos.Y * invH,
(sourcePos.X + sourceSize.Width) * invW, (sourcePos.X + sourceSize.Width) * invW,
(sourcePos.Y + sourceSize.Height) * invH); (sourcePos.Y + sourceSize.Height) * invH);
const core::rect<s32> poss(targetPos, sourceSize); const core::rect<s32> poss(targetPos, sourceSize);
...@@ -2121,15 +1958,15 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, ...@@ -2121,15 +1958,15 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos); glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos);
#ifdef GL_BGRA #ifdef GL_BGRA
const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4; const GLint colorSize = (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) ? GL_BGRA : 4;
#else #else
const GLint colorSize=4; const GLint colorSize = 4;
#endif #endif
if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Color); glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Color);
else else
{ {
_IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0); _IRR_DEBUG_BREAK_IF(ColorBuffer.size() == 0);
glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
} }
...@@ -2137,10 +1974,9 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, ...@@ -2137,10 +1974,9 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
} }
//! The same, but with a four element array of colors, one for each vertex
void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture) const video::SColor* const colors, bool useAlphaChannelOfTexture)
{ {
if (!texture) if (!texture)
return; return;
...@@ -2149,10 +1985,10 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect ...@@ -2149,10 +1985,10 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords( const core::rect<f32> tcoords(
sourceRect.UpperLeftCorner.X * invW, sourceRect.UpperLeftCorner.X * invW,
sourceRect.UpperLeftCorner.Y * invH, sourceRect.UpperLeftCorner.Y * invH,
sourceRect.LowerRightCorner.X * invW, sourceRect.LowerRightCorner.X * invW,
sourceRect.LowerRightCorner.Y *invH); sourceRect.LowerRightCorner.Y *invH);
const video::SColor temp[4] = const video::SColor temp[4] =
{ {
...@@ -2168,8 +2004,8 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect ...@@ -2168,8 +2004,8 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
if (!CacheHandler->getTextureCache().set(0, texture)) if (!CacheHandler->getTextureCache().set(0, texture))
return; return;
setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 ||
useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255,
true, useAlphaChannelOfTexture); true, useAlphaChannelOfTexture);
if (clipRect) if (clipRect)
{ {
...@@ -2178,7 +2014,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect ...@@ -2178,7 +2014,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
clipRect->getWidth(), clipRect->getHeight()); clipRect->getWidth(), clipRect->getHeight());
} }
...@@ -2206,15 +2042,15 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect ...@@ -2206,15 +2042,15 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos); glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos);
#ifdef GL_BGRA #ifdef GL_BGRA
const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4; const GLint colorSize = (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) ? GL_BGRA : 4;
#else #else
const GLint colorSize=4; const GLint colorSize = 4;
#endif #endif
if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Color); glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Color);
else else
{ {
_IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0); _IRR_DEBUG_BREAK_IF(ColorBuffer.size() == 0);
glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
} }
...@@ -2225,6 +2061,201 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect ...@@ -2225,6 +2061,201 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
} }
void COpenGLDriver::draw2DImage(const video::ITexture* texture, bool flip)
{
if (!texture || !CacheHandler->getTextureCache().set(0, texture))
return;
disableTextures(1);
setRenderStates2DMode(false, true, true);
CacheHandler->setMatrixMode(GL_PROJECTION);
glLoadIdentity();
CacheHandler->setMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Transformation3DChanged = true;
Quad2DVertices[0].Pos = core::vector3df(-1.f, 1.f, 0.f);
Quad2DVertices[1].Pos = core::vector3df(1.f, 1.f, 0.f);
Quad2DVertices[2].Pos = core::vector3df(1.f, -1.f, 0.f);
Quad2DVertices[3].Pos = core::vector3df(-1.f, -1.f, 0.f);
f32 modificator = (flip) ? 1.f : 0.f;
Quad2DVertices[0].TCoords = core::vector2df(0.f, 0.f + modificator);
Quad2DVertices[1].TCoords = core::vector2df(1.f, 0.f + modificator);
Quad2DVertices[2].TCoords = core::vector2df(1.f, 1.f - modificator);
Quad2DVertices[3].TCoords = core::vector2df(0.f, 1.f - modificator);
CacheHandler->setClientState(true, false, false, true);
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].TCoords);
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, Quad2DIndices);
}
//! draws a set of 2d images, using a color and the alpha channel of the
//! texture if desired.
void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture,
const core::array<core::position2d<s32> >& positions,
const core::array<core::rect<s32> >& sourceRects,
const core::rect<s32>* clipRect,
SColor color,
bool useAlphaChannelOfTexture)
{
if (!texture)
return;
const u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
const core::dimension2d<u32>& ss = texture->getOriginalSize();
const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
disableTextures(1);
if (!CacheHandler->getTextureCache().set(0, texture))
return;
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
Quad2DVertices[0].Color = color;
Quad2DVertices[1].Color = color;
Quad2DVertices[2].Color = color;
Quad2DVertices[3].Color = color;
if (!FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra])
getColorBuffer(Quad2DVertices, 4, EVT_STANDARD);
CacheHandler->setClientState(true, false, true, true);
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].TCoords);
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos);
#ifdef GL_BGRA
const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4;
#else
const GLint colorSize=4;
#endif
if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Color);
else
{
_IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0);
glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
}
for (u32 i=0; i<drawCount; ++i)
{
if (!sourceRects[i].isValid())
continue;
core::position2d<s32> targetPos(positions[i]);
core::position2d<s32> sourcePos(sourceRects[i].UpperLeftCorner);
// This needs to be signed as it may go negative.
core::dimension2d<s32> sourceSize(sourceRects[i].getSize());
if (clipRect)
{
if (targetPos.X < clipRect->UpperLeftCorner.X)
{
sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
if (sourceSize.Width <= 0)
continue;
sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
targetPos.X = clipRect->UpperLeftCorner.X;
}
if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X)
{
sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
if (sourceSize.Width <= 0)
continue;
}
if (targetPos.Y < clipRect->UpperLeftCorner.Y)
{
sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
if (sourceSize.Height <= 0)
continue;
sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
targetPos.Y = clipRect->UpperLeftCorner.Y;
}
if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y)
{
sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
if (sourceSize.Height <= 0)
continue;
}
}
// clip these coordinates
if (targetPos.X<0)
{
sourceSize.Width += targetPos.X;
if (sourceSize.Width <= 0)
continue;
sourcePos.X -= targetPos.X;
targetPos.X = 0;
}
if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
{
sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
if (sourceSize.Width <= 0)
continue;
}
if (targetPos.Y<0)
{
sourceSize.Height += targetPos.Y;
if (sourceSize.Height <= 0)
continue;
sourcePos.Y -= targetPos.Y;
targetPos.Y = 0;
}
if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
{
sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
if (sourceSize.Height <= 0)
continue;
}
// ok, we've clipped everything.
// now draw it.
const core::rect<f32> tcoords(
sourcePos.X * invW,
sourcePos.Y * invH,
(sourcePos.X + sourceSize.Width) * invW,
(sourcePos.Y + sourceSize.Height) * invH);
const core::rect<s32> poss(targetPos, sourceSize);
Quad2DVertices[0].Pos = core::vector3df((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f);
Quad2DVertices[1].Pos = core::vector3df((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f);
Quad2DVertices[2].Pos = core::vector3df((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f);
Quad2DVertices[3].Pos = core::vector3df((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f);
Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, Quad2DIndices);
}
}
//! 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. The images are drawn beginning at pos and concatenated //! texture if desired. The images are drawn beginning at pos and concatenated
//! in one line. All drawings are clipped against clipRect (if != 0). //! in one line. All drawings are clipped against clipRect (if != 0).
......
...@@ -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