Commit ab5bf465 authored by hybrid's avatar hybrid

Add InitMaterial2D member, which will be used to alter 2d render state...

Add InitMaterial2D member, which will be used to alter 2d render state settings. Not yet functional, though, as we need to do more performance tests and API additions.
Added the 2d batch render function to OpenGL as it reduces the amount of render state changes. This makes text rendering far better scaling.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3023 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 557ccff8
...@@ -74,7 +74,7 @@ IImageWriter* createImageWriterPPM(); ...@@ -74,7 +74,7 @@ IImageWriter* createImageWriterPPM();
CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize) CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
: FileSystem(io), MeshManipulator(0), ViewPort(0,0,0,0), ScreenSize(screenSize), : FileSystem(io), MeshManipulator(0), ViewPort(0,0,0,0), ScreenSize(screenSize),
PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0), PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0),
AllowZWriteOnTransparent(false) InitMaterial2DEnabled(false), AllowZWriteOnTransparent(false)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CNullDriver"); setDebugName("CNullDriver");
...@@ -150,6 +150,17 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre ...@@ -150,6 +150,17 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre
memset(&ExposedData, 0, sizeof(ExposedData)); memset(&ExposedData, 0, sizeof(ExposedData));
for (u32 i=0; i<video::EVDF_COUNT; ++i) for (u32 i=0; i<video::EVDF_COUNT; ++i)
FeatureEnabled[i]=true; FeatureEnabled[i]=true;
InitMaterial2D.AntiAliasing=video::EAAM_OFF;
InitMaterial2D.Lighting=false;
InitMaterial2D.ZWriteEnable=false;
InitMaterial2D.ZBuffer=video::ECFN_NEVER;
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
{
InitMaterial2D.TextureLayer[i].BilinearFilter=false;
InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT;
InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT;
}
} }
......
...@@ -704,6 +704,8 @@ namespace video ...@@ -704,6 +704,8 @@ namespace video
SExposedVideoData ExposedData; SExposedVideoData ExposedData;
SOverrideMaterial OverrideMaterial; SOverrideMaterial OverrideMaterial;
SMaterial InitMaterial2D;
bool InitMaterial2DEnabled;
E_FOG_TYPE FogType; E_FOG_TYPE FogType;
bool PixelFog; bool PixelFog;
......
...@@ -1574,6 +1574,144 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo ...@@ -1574,6 +1574,144 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
} }
//! 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());
// texcoords need to be flipped horizontally for RTTs
const bool isRTT = texture->isRenderTarget();
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 (!setActiveTexture(0, texture))
return;
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
glBegin(GL_QUADS);
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,
(isRTT?(sourcePos.Y + sourceSize.Height):sourcePos.Y) * invH,
(sourcePos.X + sourceSize.Width) * invW,
(isRTT?sourcePos.Y:(sourcePos.Y + sourceSize.Height)) * invH);
const core::rect<s32> poss(targetPos, sourceSize);
glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y));
glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y));
glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y));
glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y));
}
glEnd();
}
//! draws a 2d image, using a color and the alpha channel of the texture if //! 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). //! desired. The image is drawn at pos, clipped against clipRect (if != 0).
//! Only the subtexture defined by sourceRect is used. //! Only the subtexture defined by sourceRect is used.
...@@ -2593,11 +2731,10 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh ...@@ -2593,11 +2731,10 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
{ {
if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
SMaterial mat; SMaterial mat(InitMaterial2D);
mat.ZBuffer=ECFN_NEVER;
mat.Lighting=false; mat.Lighting=false;
mat.AntiAliasing=video::EAAM_OFF; mat.ZBuffer=ECFN_NEVER;
mat.TextureLayer[0].BilinearFilter=false; mat.ZWriteEnable=false;
setBasicRenderStates(mat, LastMaterial, true); setBasicRenderStates(mat, LastMaterial, true);
LastMaterial = mat; LastMaterial = mat;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
...@@ -2623,6 +2760,15 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh ...@@ -2623,6 +2760,15 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
Transformation3DChanged = false; Transformation3DChanged = false;
} }
else if (InitMaterial2DEnabled)
{
SMaterial mat(InitMaterial2D);
mat.Lighting=false;
mat.ZBuffer=ECFN_NEVER;
mat.ZWriteEnable=false;
setBasicRenderStates(mat, LastMaterial, false);
LastMaterial = mat;
}
if (alphaChannel || alpha) if (alphaChannel || alpha)
{ {
...@@ -2638,11 +2784,13 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh ...@@ -2638,11 +2784,13 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
if (texture) if (texture)
{ {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if (!InitMaterial2DEnabled)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
if (alphaChannel) if (alphaChannel)
{ {
......
...@@ -115,6 +115,15 @@ namespace video ...@@ -115,6 +115,15 @@ 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); virtual void setMaterial(const SMaterial& material);
//! draws a set of 2d images, using a color and the alpha channel of the
//! texture if desired.
void 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);
//! 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. //! 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, virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
......
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