diff --git a/project/Build.xml b/project/Build.xml
index 41d4a5f0a..fd6d3dde0 100644
--- a/project/Build.xml
+++ b/project/Build.xml
@@ -357,7 +357,7 @@
-
+
diff --git a/project/include/Display.h b/project/include/Display.h
index d2b39ff2d..b5571851b 100644
--- a/project/include/Display.h
+++ b/project/include/Display.h
@@ -436,6 +436,8 @@ public:
virtual bool getMultitouchSupported() { return false; }
virtual void setMultitouchActive(bool inActive) { }
virtual bool getMultitouchActive() { return false; }
+
+ virtual uint32 getBackgroundMask() { return 0xffffffff; }
Matrix GetFullMatrix(bool inStageScaling);
bool FinishEditOnEnter();
diff --git a/project/include/Graphics.h b/project/include/Graphics.h
index f64829063..7e2eb0fb2 100644
--- a/project/include/Graphics.h
+++ b/project/include/Graphics.h
@@ -456,84 +456,10 @@ struct RenderState
};
-void ResetHardwareContext();
+class HardwareData;
+class HardwareContext;
-
-enum PrimType { ptTriangleFan, ptTriangleStrip, ptTriangles, ptLineStrip, ptPoints, ptLines };
-
-struct DrawElement
-{
- uint8 mPrimType;
- bool mBitmapRepeat;
- bool mBitmapSmooth;
- int mFirst;
- int mCount;
- uint32 mColour;
- float mWidth;
- StrokeScaleMode mScaleMode;
-};
-
-typedef QuickVec DrawElements;
-typedef QuickVec Vertices;
-typedef QuickVec TexCoords;
-typedef QuickVec Colours;
-
-void ReleaseVertexBufferObject(unsigned int inVBO);
-
-void ConvertOutlineToTriangles(Vertices &ioOutline,const QuickVec &inSubPolys);
-
-struct HardwareArrays
-{
- enum
- {
- BM_ADD = 0x00000001,
- PERSPECTIVE = 0x00000002,
- RADIAL = 0x00000004,
- BM_MULTIPLY = 0x00000008,
- BM_SCREEN = 0x00000010,
-
- AM_PREMULTIPLIED = 0x00000100,
-
- FOCAL_MASK = 0x0000ff00,
- FOCAL_SIGN = 0x00010000,
- };
-
- HardwareArrays(Surface *inSurface,unsigned int inFlags);
- ~HardwareArrays();
- bool ColourMatch(bool inWantColour);
-
-
- DrawElements mElements;
- Vertices mVertices;
- TexCoords mTexCoords;
- Colours mColours;
- Surface *mSurface;
- unsigned int mFlags;
- //unsigned int mVertexBO;
-};
-
-typedef QuickVec HardwareCalls;
-
-class HardwareData
-{
-public:
- ~HardwareData();
-
- HardwareArrays &GetArrays(Surface *inSurface,bool inWithColour,unsigned int inFlags);
-
- HardwareCalls mCalls;
-
-};
-
-
-
-
-extern HardwareContext *gDirectRenderContext;
-
-void BuildHardwareJob(const class GraphicsJob &inJob,const GraphicsPath &inPath,
- HardwareData &ioData, HardwareContext &inHardware);
-
int UpToPower2(int inX);
inline int IsPower2(unsigned int inX) { return (inX & (inX-1))==0; }
diff --git a/project/include/Hardware.h b/project/include/Hardware.h
new file mode 100644
index 000000000..6c21513da
--- /dev/null
+++ b/project/include/Hardware.h
@@ -0,0 +1,89 @@
+#ifndef LIME_HARDWARE_H
+#define LIME_HARDWARE_H
+
+#include "Graphics.h"
+
+namespace lime
+{
+
+void ResetHardwareContext();
+
+typedef QuickVec Vertices;
+
+enum PrimType { ptTriangleFan, ptTriangleStrip, ptTriangles, ptLineStrip, ptPoints, ptLines };
+
+enum
+{
+ DRAW_HAS_COLOUR = 0x00000001,
+ DRAW_HAS_NORMAL = 0x00000002,
+ DRAW_HAS_PERSPECTIVE = 0x00000004,
+ DRAW_RADIAL = 0x00000008,
+
+ DRAW_HAS_TEX = 0x00000010,
+ DRAW_BMP_REPEAT = 0x00000020,
+ DRAW_BMP_SMOOTH = 0x00000040,
+};
+
+
+
+
+struct DrawElement
+{
+ uint8 mFlags;
+ uint8 mPrimType;
+ uint8 mBlendMode;
+ uint8 mScaleMode;
+ short mRadialPos;
+
+ uint8 mStride;
+ int mCount;
+
+ int mVertexOffset;
+ int mTexOffset;
+ int mColourOffset;
+ int mNormalOffset;
+
+ uint32 mColour;
+ Surface *mSurface;
+
+ // For ptLineStrip/ptLines
+ float mWidth;
+
+};
+
+typedef QuickVec DrawElements;
+
+class HardwareData
+{
+public:
+ HardwareData();
+ ~HardwareData();
+
+ void releaseVbo();
+ float scaleOf(const RenderState &inState) const;
+ bool isScaleOk(const RenderState &inState) const;
+ void clear();
+
+ DrawElements mElements;
+ QuickVec mArray;
+ float mMinScale;
+ float mMaxScale;
+
+ mutable HardwareContext *mVboOwner;
+ mutable int mRendersWithoutVbo;
+ mutable unsigned int mVertexBo;
+ mutable int mContextId;
+};
+
+
+void ConvertOutlineToTriangles(Vertices &ioOutline,const QuickVec &inSubPolys);
+
+extern HardwareContext *gDirectRenderContext;
+
+void BuildHardwareJob(const class GraphicsJob &inJob,const GraphicsPath &inPath,
+ HardwareData &ioData, HardwareContext &inHardware,const RenderState &inState);
+
+
+}
+
+#endif
diff --git a/project/include/Pixel.h b/project/include/Pixel.h
index cc8ccddce..4328135bb 100644
--- a/project/include/Pixel.h
+++ b/project/include/Pixel.h
@@ -27,14 +27,6 @@ enum PixelFormat
pfSwapRB = 0x02,
};
-enum AlphaMode
-{
- amUnknown = 0x00,
- amPremultiplied = 0x01,
- amStraight = 0x02,
- amIgnore = 0x03,
-};
-
typedef unsigned char Uint8;
diff --git a/project/include/renderer/common/HardwareContext.h b/project/include/renderer/common/HardwareContext.h
index d4a6e9310..9f9e292cb 100644
--- a/project/include/renderer/common/HardwareContext.h
+++ b/project/include/renderer/common/HardwareContext.h
@@ -23,12 +23,13 @@ namespace lime {
virtual void Clear (uint32 inColour, const Rect *inRect = 0) = 0;
virtual class Texture *CreateTexture (class Surface *inSurface, unsigned int inFlags) = 0;
virtual void DestroyNativeTexture (void *inNativeTexture) = 0;
+ virtual void DestroyVbo (unsigned int inVbo) = 0;
virtual void EndBitmapRender () = 0;
virtual void EndRender () = 0;
virtual void Flip () = 0;
virtual int Height () const = 0;
- virtual bool Hits (const RenderState &inState, const HardwareCalls &inCalls);
- virtual void Render (const RenderState &inState, const HardwareCalls &inCalls) = 0;
+ virtual bool Hits (const RenderState &inState, const HardwareData &inData);
+ virtual void Render (const RenderState &inState, const HardwareData &inData) = 0;
virtual void RenderBitmap (const Rect &inSrc, int inX, int inY) = 0;
virtual void SetQuality (StageQuality inQuality) = 0;
virtual void SetViewport (const Rect &inRect) = 0;
@@ -41,4 +42,4 @@ namespace lime {
};
-#endif
\ No newline at end of file
+#endif
diff --git a/project/include/renderer/common/HardwareSurface.h b/project/include/renderer/common/HardwareSurface.h
index df3bc0bdf..8f7b53b20 100644
--- a/project/include/renderer/common/HardwareSurface.h
+++ b/project/include/renderer/common/HardwareSurface.h
@@ -21,7 +21,6 @@ namespace lime {
void Clear (uint32 inColour, const Rect *inRect = 0) { mHardware->Clear (inColour, inRect); }
void EndRender () { mHardware->EndRender (); }
PixelFormat Format () const { return pfHardware; }
- AlphaMode GetAlphaMode () const { return mAlphaMode; }
const uint8 *GetBase () const { return 0; }
int GetStride () const { return 0; }
int Height () const { return mHardware->Height (); }
@@ -38,7 +37,6 @@ namespace lime {
private:
- AlphaMode mAlphaMode;
HardwareContext *mHardware;
};
diff --git a/project/include/renderer/common/SimpleSurface.h b/project/include/renderer/common/SimpleSurface.h
index dc4dcb140..846fb0239 100644
--- a/project/include/renderer/common/SimpleSurface.h
+++ b/project/include/renderer/common/SimpleSurface.h
@@ -19,7 +19,6 @@ namespace lime {
virtual void colorTransform (const Rect &inRect, ColorTransform &inTransform);
virtual void StretchTo (const RenderTarget &outTarget, const Rect &inSrcRect, const DRect &inDestRect) const;
- virtual void setAlphaMode (AlphaMode am) { mAlphaMode = am; }
virtual void setGPUFormat (PixelFormat pf) { mGPUPixelFormat = pf; }
void applyFilter (Surface *inSrc, const Rect &inRect, ImagePoint inOffset, Filter *inFilter);
@@ -43,7 +42,6 @@ namespace lime {
void Zero ();
PixelFormat Format () const { return mPixelFormat; }
- AlphaMode GetAlphaMode () const { return mAlphaMode; }
const uint8 *GetBase () const { return mBase; }
int GetStride () const { return mStride; }
int GPUFormat () const { return mGPUPixelFormat; }
@@ -54,7 +52,6 @@ namespace lime {
~SimpleSurface ();
- AlphaMode mAlphaMode;
uint8 *mBase;
int mGPUPixelFormat;
int mHeight;
diff --git a/project/include/renderer/common/Surface.h b/project/include/renderer/common/Surface.h
index 03673f6ec..126d59a1c 100644
--- a/project/include/renderer/common/Surface.h
+++ b/project/include/renderer/common/Surface.h
@@ -7,6 +7,7 @@
#include
#include "renderer/common/Texture.h"
#include "renderer/common/HardwareContext.h"
+#include
namespace lime {
@@ -28,7 +29,6 @@ namespace lime {
virtual void Clear (uint32 inColour, const Rect *inRect = 0) = 0;
virtual void EndRender () = 0;
virtual PixelFormat Format () const = 0;
- virtual AlphaMode GetAlphaMode () const = 0;
virtual const uint8 *GetBase () const = 0;
virtual int GetStride () const = 0;
virtual int Height () const = 0;
@@ -49,7 +49,6 @@ namespace lime {
virtual int GPUFormat () const { return Format (); }
virtual void multiplyAlpha () {}
virtual void noise (unsigned int randomSeed, unsigned int low, unsigned int high, int channelOptions, bool grayScale) {}
- virtual void setAlphaMode (AlphaMode am) {}
virtual void SetAllowTrans (bool inAllowTrans) { mAllowTrans = inAllowTrans; }
virtual void SetFlags (unsigned int inFlags) { mFlags = inFlags; }
virtual void setGPUFormat (PixelFormat pf) {}
diff --git a/project/include/renderer/opengl/OGL.h b/project/include/renderer/opengl/OGL.h
index 8048b4f41..842d5dea1 100644
--- a/project/include/renderer/opengl/OGL.h
+++ b/project/include/renderer/opengl/OGL.h
@@ -200,20 +200,18 @@ namespace lime
Texture *OGLCreateTexture(Surface *inSurface,unsigned int inFlags);
-enum GPUProgID
+enum
{
- gpuNone = -1,
- gpuSolid,
- gpuColour,
- gpuColourTransform,
- gpuTexture,
- gpuTextureColourArray,
- gpuTextureTransform,
- gpuBitmap,
- gpuBitmapAlpha,
- gpuRadialGradient,
- gpuRadialFocusGradient,
- gpuSIZE,
+ PROG_TEXTURE = 0x0001,
+ PROG_ALPHA_TEXTURE = 0x0002,
+ PROG_COLOUR_PER_VERTEX = 0x0004,
+ PROG_NORMAL_DATA = 0x0008,
+ PROG_RADIAL = 0x0010,
+ PROG_RADIAL_FOCUS = 0x0020,
+ PROG_TINT = 0x0040,
+ PROG_COLOUR_OFFSET = 0x0080,
+
+ PROG_COUNT = 0x0100,
};
typedef float Trans4x4[4][4];
@@ -221,22 +219,22 @@ typedef float Trans4x4[4][4];
class GPUProg
{
public:
- static GPUProg *create(GPUProgID inID, AlphaMode inAlphaMode);
+ static GPUProg *create(unsigned int inID);
virtual ~GPUProg() {}
virtual bool bind() = 0;
- virtual void setPositionData(const float *inData, bool inIsPerspective) = 0;
- virtual void setTexCoordData(const float *inData) = 0;
- virtual void setColourData(const int *inData) = 0;
- virtual void setColourTransform(const ColorTransform *inTransform) = 0;
- virtual int getTextureSlot() = 0;
-
+ virtual void disableSlots() = 0;
virtual void setTransform(const Trans4x4 &inTrans) = 0;
- virtual void setTint(unsigned int inColour) = 0;
+ virtual void setColourTransform(const ColorTransform *inTransform, unsigned int inColour) = 0;
virtual void setGradientFocus(float inFocus) = 0;
- virtual void finishDrawing() = 0;
+
+ int vertexSlot;
+ int textureSlot;
+ int normalSlot;
+ int colourSlot;
+
};
void InitOGL2Extensions();
diff --git a/project/include/renderer/opengl/OpenGL2Context.h b/project/include/renderer/opengl/OpenGL2Context.h
deleted file mode 100644
index f081e586d..000000000
--- a/project/include/renderer/opengl/OpenGL2Context.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef RENDERER_OPENGL2_CONTEXT_H
-#define RENDERER_OPENGL2_CONTEXT_H
-
-
-#include "OpenGLContext.h"
-
-
-namespace lime {
-
-
- class OpenGL2Context : public OpenGLContext {
-
- public:
-
- OpenGL2Context (WinDC inDC, GLCtx inOGLCtx);
- ~OpenGL2Context ();
-
- virtual void CombineModelView (const Matrix &inModelView);
- virtual void FinishBitmapRender ();
- virtual void FinishDrawing ();
- virtual void OnBeginRender ();
- virtual void PopBitmapMatrix ();
- virtual void PrepareBitmapRender ();
- virtual bool PrepareDrawing ();
- virtual void PushBitmapMatrix ();
- virtual void SetBitmapData (const float *inPos, const float *inTex);
- virtual void SetColourArray (const int *inData);
- virtual void SetModulatingTransform (const ColorTransform *inTransform);
- virtual void setOrtho (float x0, float x1, float y0, float y1);
- virtual void SetPositionData (const float *inData, bool inPerspective);
- virtual void SetRadialGradient (bool inIsRadial, float inFocus);
- virtual void SetSolidColour (unsigned int col);
- virtual void SetTexture (Surface *inSurface, const float *inTexCoords);
-
- Trans4x4 mBitmapTrans;
- const int *mColourArray;
- GPUProg *mCurrentProg;
- const ColorTransform *mColourTransform;
- bool mIsRadial;
- double mOffsetX;
- double mOffsetY;
- const float *mPosition;
- bool mPositionPerspective;
- GPUProg *mProg[gpuSIZE];
- float mRadialFocus;
- double mScaleX;
- double mScaleY;
- const float *mTexCoords;
- Surface *mTextureSurface;
- Trans4x4 mTrans;
-
- };
-
-
-}
-
-
-#endif
diff --git a/project/include/renderer/opengl/OpenGLContext.h b/project/include/renderer/opengl/OpenGLContext.h
index 55d86f731..079b0663c 100644
--- a/project/include/renderer/opengl/OpenGLContext.h
+++ b/project/include/renderer/opengl/OpenGLContext.h
@@ -17,34 +17,21 @@ namespace lime {
OpenGLContext (WinDC inDC, GLCtx inOGLCtx);
~OpenGLContext ();
- virtual void CombineModelView (const Matrix &inModelView);
- virtual void FinishDrawing ();
- virtual void FinishBitmapRender ();
- virtual void OnBeginRender ();
- virtual void PopBitmapMatrix ();
- virtual void PrepareBitmapRender ();
- virtual bool PrepareDrawing ();
- virtual void PushBitmapMatrix ();
- virtual void SetBitmapData (const float *inPos, const float *inTex);
- virtual void SetColourArray (const int *inData);
- virtual void SetModulatingTransform (const ColorTransform *inTransform);
- virtual void setOrtho (float x0,float x1, float y0, float y1);
- virtual void SetPositionData (const float *inData, bool inPerspective);
- virtual void SetRadialGradient (bool inIsRadial, float inFocus);
- virtual void SetSolidColour (unsigned int col);
- virtual void SetTexture (Surface *inSurface, const float *inTexCoords);
-
void BeginBitmapRender (Surface *inSurface, uint32 inTint, bool inRepeat, bool inSmooth);
void BeginRender (const Rect &inRect, bool inForHitTest);
void Clear (uint32 inColour, const Rect *inRect);
+ void CombineModelView (const Matrix &inModelView);
Texture *CreateTexture (Surface *inSurface, unsigned int inFlags);
void DestroyNativeTexture (void *inNativeTexture);
+ void DestroyVbo (unsigned int inVbo);
void EndBitmapRender ();
void EndRender ();
void Flip ();
- void Render (const RenderState &inState, const HardwareCalls &inCalls);
+ void Render (const RenderState &inState, const HardwareData &inData);
void RenderBitmap (const Rect &inSrc, int inX, int inY);
+ void RenderData (const HardwareData &inData, const ColorTransform *ctrans, const Trans4x4 &inTrans);
void SetLineWidth (double inWidth);
+ void setOrtho (float x0, float x1, float y0, float y1);
void SetQuality (StageQuality inQ);
void SetViewport (const Rect &inRect);
void SetWindowSize (int inWidth, int inHeight);
@@ -52,10 +39,9 @@ namespace lime {
int Height () const { return mHeight; }
int Width () const { return mWidth; }
- AlphaMode mAlphaMode;
- Surface *mBitmapSurface;
+ HardwareData mBitmapBuffer;
Texture *mBitmapTexture;
- bool mColourArrayEnabled;
+ Trans4x4 mBitmapTrans;
WinDC mDC;
int mHeight;
double mLineScaleH;
@@ -63,21 +49,25 @@ namespace lime {
double mLineScaleV;
double mLineWidth;
Matrix mModelView;
+ double mOffsetX;
+ double mOffsetY;
GLCtx mOGLCtx;
- bool mPointSmooth;
- bool mPointsToo;
+ GPUProg *mProg[PROG_COUNT];
StageQuality mQuality;
+ double mScaleX;
+ double mScaleY;
ThreadId mThreadId;
- uint32 mTint;
- bool mUsingBitmapMatrix;
+ Trans4x4 mTrans;
Rect mViewport;
int mWidth;
QuickVec mZombieTextures;
-
+ QuickVec mZombieVbos;
+
};
const double one_on_255 = 1.0 / 255.0;
+ const double one_on_256 = 1.0 / 256.0;
static GLuint sgOpenglType[] = { GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, GL_TRIANGLES, GL_LINE_STRIP, GL_POINTS, GL_LINES };
diff --git a/project/include/renderer/opengl/OpenGLProgram.h b/project/include/renderer/opengl/OpenGLProgram.h
index a51228aec..1e6d5ffcf 100644
--- a/project/include/renderer/opengl/OpenGLProgram.h
+++ b/project/include/renderer/opengl/OpenGLProgram.h
@@ -12,24 +12,19 @@ namespace lime {
public:
- OpenGLProgram (const char *inVertProg, const char *inFragProg, AlphaMode inAlphaMode);
+ OpenGLProgram (const std::string &inVertProg, const std::string &inFragProg);
virtual ~OpenGLProgram ();
virtual bool bind ();
virtual void setGradientFocus (float inFocus);
GLuint createShader (GLuint inType, const char *inShader);
- void finishDrawing ();
+ void disableSlots ();
int getTextureSlot ();
void recreate ();
- void setColourData (const int *inData);
- void setColourTransform (const ColorTransform *inTransform);
- void setPositionData (const float *inData, bool inIsPerspective);
- void setTexCoordData (const float *inData);
- void setTint (unsigned int inColour);
+ void setColourTransform (const ColorTransform *inTransform, unsigned int inColour);
void setTransform (const Trans4x4 &inTrans);
- AlphaMode mAlphaMode;
GLint mASlot;
GLint mColourArraySlot;
GLint mColourOffsetSlot;
@@ -37,17 +32,19 @@ namespace lime {
const ColorTransform *mColourTransform;
int mContextVersion;
GLuint mFragId;
- const char *mFragProg;
+ std::string mFragProg;
GLint mFXSlot;
+ GLint mImageSlot;
GLint mOn2ASlot;
GLuint mProgramId;
- GLint mTexCoordSlot;
- GLint mTextureSlot;
- GLint mTintSlot;
GLint mTransformSlot;
GLuint mVertId;
- const char *mVertProg;
- GLint mVertexSlot;
+ std::string mVertProg;
+
+ //GLint colourSlot;
+ //GLint normalSlot;
+ //GLint textureSlot;
+ //GLint vertexSlot;
};
diff --git a/project/src/backend/sdl/SDLStage.cpp b/project/src/backend/sdl/SDLStage.cpp
index aa1b18e15..b9b66b76d 100644
--- a/project/src/backend/sdl/SDLStage.cpp
+++ b/project/src/backend/sdl/SDLStage.cpp
@@ -148,7 +148,6 @@ public:
return swap ? pfARGBSwap : pfARGB;
return swap ? pfXRGBSwap : pfXRGB;
}
- AlphaMode GetAlphaMode() const { return amStraight; }
const uint8 *GetBase() const { return (const uint8 *)mSurf->pixels; }
int GetStride() const { return mSurf->pitch; }
diff --git a/project/src/backend/sdl2/SDL2Stage.cpp b/project/src/backend/sdl2/SDL2Stage.cpp
index c10cd63f8..d474137d7 100644
--- a/project/src/backend/sdl2/SDL2Stage.cpp
+++ b/project/src/backend/sdl2/SDL2Stage.cpp
@@ -73,10 +73,6 @@ public:
return swap ? pfARGBSwap : pfARGB;
return swap ? pfXRGBSwap : pfXRGB;
}
- AlphaMode GetAlphaMode() const
- {
- return amStraight;
- }
const uint8 *GetBase() const { return (const uint8 *)mSurf->pixels; }
int GetStride() const { return mSurf->pitch; }
diff --git a/project/src/common/Display.cpp b/project/src/common/Display.cpp
index 9b20b258e..fb1ae2753 100644
--- a/project/src/common/Display.cpp
+++ b/project/src/common/Display.cpp
@@ -1494,7 +1494,8 @@ public:
mSurface = inStage->GetPrimarySurface();
mToFlip = inStage;
mTarget = mSurface->BeginRender( Rect(mSurface->Width(),mSurface->Height()),false );
- mSurface->Clear(inRGB | 0xff000000 );
+
+ mSurface->Clear( (inRGB | 0xff000000) & inStage->getBackgroundMask() );
}
int Width() const { return mSurface->Width(); }
int Height() const { return mSurface->Height(); }
diff --git a/project/src/common/ExternalInterface.cpp b/project/src/common/ExternalInterface.cpp
index 791fb2c0b..87fbe1c2a 100644
--- a/project/src/common/ExternalInterface.cpp
+++ b/project/src/common/ExternalInterface.cpp
@@ -3588,25 +3588,6 @@ value lime_bitmap_data_multiply_alpha(value inSurface)
DEFINE_PRIM(lime_bitmap_data_multiply_alpha,1);
-value lime_bitmap_data_set_alpha_mode(value inHandle, value inAlphaMode)
-{
- Surface *surface;
- if (AbstractToObject(inHandle,surface))
- {
- if ( val_int( inAlphaMode ) == 0 )
- surface->setAlphaMode( amUnknown );
- else if ( val_int( inAlphaMode ) == 1 )
- surface->setAlphaMode( amPremultiplied );
- else if ( val_int( inAlphaMode ) == 2 )
- surface->setAlphaMode( amStraight );
- else if ( val_int( inAlphaMode ) == 4 )
- surface->setAlphaMode( amIgnore );
- }
- return alloc_null();
-}
-DEFINE_PRIM(lime_bitmap_data_set_alpha_mode,2);
-
-
value lime_render_surface_to_surface(value* arg, int nargs)
{
enum { aTarget, aSurface, aMatrix, aColourTransform, aBlendMode, aClipRect, aSmooth, aSIZE};
diff --git a/project/src/common/Graphics.cpp b/project/src/common/Graphics.cpp
index c60c54756..c8c4ee498 100644
--- a/project/src/common/Graphics.cpp
+++ b/project/src/common/Graphics.cpp
@@ -2,6 +2,7 @@
#include "renderer/common/Surface.h"
#include
+
namespace lime
{
@@ -638,18 +639,23 @@ bool Graphics::Render( const RenderTarget &inTarget, const RenderState &inState
{
if (!mHardwareData)
mHardwareData = new HardwareData();
+ else if (!mHardwareData->isScaleOk(inState))
+ {
+ mHardwareData->clear();
+ mBuiltHardware = 0;
+ }
while(mBuiltHardwaremCalls.size())
+ if (mHardwareData && !mHardwareData->mElements.empty())
{
if (inState.mPhase==rpHitTest)
- return inTarget.mHardware->Hits(inState,mHardwareData->mCalls);
+ return inTarget.mHardware->Hits(inState,*mHardwareData);
else
- inTarget.mHardware->Render(inState,mHardwareData->mCalls);
+ inTarget.mHardware->Render(inState,*mHardwareData);
}
}
else
diff --git a/project/src/common/Hardware.cpp b/project/src/common/Hardware.cpp
index fd0b07dfb..1085c6f38 100644
--- a/project/src/common/Hardware.cpp
+++ b/project/src/common/Hardware.cpp
@@ -11,33 +11,75 @@
namespace lime
{
+
+struct CurveEdge
+{
+ CurveEdge(const UserPoint &inP, float inT) : p(inP), t(inT) { }
+ inline CurveEdge(){}
+
+ UserPoint p;
+ float t;
+};
+typedef QuickVec Curves;
+
+struct Range
+{
+ inline Range() {}
+ inline Range(float inT0, const UserPoint &l0, const UserPoint &r0,
+ float inT1, const UserPoint &l1, const UserPoint &r1) :
+ t0(inT0), t1(inT1),
+ left0(l0), right0(r0),
+ left1(l1), right1(r1) { }
+
+ float t0,t1;
+ UserPoint left0;
+ UserPoint right0;
+ UserPoint left1;
+ UserPoint right1;
+};
+
+
+
+typedef QuickVec Normals;
+
class HardwareBuilder
{
public:
HardwareBuilder(const GraphicsJob &inJob,const GraphicsPath &inPath,HardwareData &ioData,
- HardwareContext &inHardware)
+ HardwareContext &inHardware, const RenderState &inState) : data(ioData)
{
mTexture = 0;
- bool tile_mode = false;
- mElement.mColour = 0xffffffff;
- mSolidMode = false;
- mPerpLen = 0.5;
+
bool tessellate_lines = true;
+ bool tile_mode = false;
+ bool alphaAA = true;
+
+ memset(&mElement,0,sizeof(mElement));
+ mElement.mWidth = -1;
+ mElement.mColour = 0xffffffff;
+ mElement.mVertexOffset = ioData.mArray.size();
+ mElement.mStride = 2*sizeof(float);
+
+ mSolidMode = false;
+ mAlphaAA = false;
+ mPerpLen = 0.5;
+ mScale = data.scaleOf(inState);
+ if (mScale<=0.001)
+ mScale = 0.001;
+ mCurveThresh2 = 0.125/mScale/mScale;
+ mFatLineCullThresh = 5.0/mScale;
if (inJob.mIsTileJob)
{
- mElement.mBitmapRepeat = true;
- mElement.mBitmapSmooth = false;
-
mElement.mPrimType = ptTriangles;
mElement.mScaleMode = ssmNormal;
- mElement.mWidth = -1;
GraphicsBitmapFill *bmp = inJob.mFill->AsBitmapFill();
- mSurface = bmp->bitmapData->IncRef();
- mTexture = mSurface->GetOrCreateTexture(inHardware);
- mElement.mBitmapRepeat = false;
- mElement.mBitmapSmooth = bmp->smooth;
+ mElement.mSurface = bmp->bitmapData->IncRef();
+
+ mTexture = mElement.mSurface->GetOrCreateTexture(inHardware);
+ if (bmp->smooth)
+ mElement.mFlags |= DRAW_BMP_SMOOTH;
tile_mode = true;
}
else if (inJob.mFill)
@@ -45,30 +87,45 @@ public:
mSolidMode = true;
mElement.mPrimType = inJob.mTriangles ? ptTriangles : ptTriangleFan;
mElement.mScaleMode = ssmNormal;
- mElement.mWidth = -1;
if (!SetFill(inJob.mFill,inHardware))
return;
}
else if (tessellate_lines && inJob.mStroke->scaleMode==ssmNormal)
{
- // ptTriangleStrip?
mElement.mPrimType = ptTriangles;
GraphicsStroke *stroke = inJob.mStroke;
+ mElement.mWidth = stroke->thickness;
if (!SetFill(stroke->fill,inHardware))
return;
mPerpLen = stroke->thickness * 0.5;
if (mPerpLen<=0.0)
- mPerpLen = 0.5;
- else if (mPerpLen<0.5)
{
mPerpLen = 0.5;
+ mElement.mWidth = 1.0;
}
mCaps = stroke->caps;
mJoints = stroke->joints;
- if (mJoints==sjMiter)
- mMiterLimit = stroke->miterLimit*mPerpLen;
+ mMiterLimit = stroke->miterLimit*mPerpLen;
+
+ if (mPerpLen<0.5/mScale)
+ {
+ int a = (mElement.mColour>>24)*mPerpLen*mScale/0.5;
+ mElement.mColour = (mElement.mColour & 0x00ffffff) | (a<<24);
+ mPerpLen = 0.5/mScale;
+ mElement.mWidth = 1.0/mScale;
+ }
+
+ if (alphaAA)
+ {
+ mPerpLen += 0.5/mScale;
+ mElement.mWidth += 1.0/mScale;
+ mElement.mFlags |= DRAW_HAS_NORMAL;
+ mElement.mNormalOffset += mElement.mVertexOffset + mElement.mStride;
+ mElement.mStride += sizeof(float)*2.0;
+ mAlphaAA = true;
+ }
}
else
{
@@ -79,38 +136,59 @@ public:
mElement.mWidth = stroke->thickness;
SetFill(stroke->fill,inHardware);
}
- mElement.mFirst = 0;
- mElement.mCount = 0;
-
-
+
+ if (mElement.mSurface)
+ {
+ mElement.mFlags |= DRAW_HAS_TEX;
+ mElement.mTexOffset = mElement.mVertexOffset + mElement.mStride;
+ mElement.mStride += 2*sizeof(float);
+ }
+
if (inJob.mTriangles)
{
- bool has_colour = inJob.mTriangles->mColours.size()>0;
- unsigned int flags = 0;
- if (inJob.mTriangles->mType == vtVertexUVT)
- flags |= HardwareArrays::PERSPECTIVE;
- if (inJob.mTriangles->mBlendMode==bmAdd)
- flags |= HardwareArrays::BM_ADD;
- if (inJob.mTriangles->mBlendMode==bmMultiply)
- flags |= HardwareArrays::BM_MULTIPLY;
- if (inJob.mTriangles->mBlendMode==bmScreen)
- flags |= HardwareArrays::BM_SCREEN;
- if (mSurface && (mSurface->GetAlphaMode () == amPremultiplied))
- flags |= HardwareArrays::AM_PREMULTIPLIED;
- mArrays = &ioData.GetArrays(mSurface,has_colour,flags);
+ if (inJob.mTriangles->mType == vtVertexUVT && mElement.mSurface)
+ {
+ // Add z,w to position coordinates...
+ mElement.mStride += 2*sizeof(float);
+ mElement.mTexOffset += 2*sizeof(float);
+ mElement.mFlags |= DRAW_HAS_PERSPECTIVE;
+ }
+
+ if (inJob.mTriangles->mColours.size())
+ {
+ mElement.mColourOffset = mElement.mVertexOffset + mElement.mStride;
+ mElement.mStride += sizeof(int);
+ mElement.mFlags |= DRAW_HAS_COLOUR;
+ mElement.mColour = 0xffffffff;
+ }
+
+ mElement.mBlendMode =inJob.mTriangles->mBlendMode;
+
AddTriangles(inJob.mTriangles);
if (inJob.mStroke && inJob.mStroke->fill)
{
+ if (mElement.mSurface)
+ mElement.mSurface->DecRef();
+ memset(&mElement,0,sizeof(mElement));
+ mElement.mColour = 0xffffffff;
+ mElement.mVertexOffset = ioData.mArray.size();
+ mElement.mStride = 2*sizeof(float);
+ mElement.mScaleMode = ssmNormal;
+ mElement.mWidth = inJob.mStroke->thickness;
+
mElement.mPrimType = ptLines;
GraphicsStroke *stroke = inJob.mStroke;
if (!SetFill(stroke->fill,inHardware))
return;
- mArrays = &ioData.GetArrays(mSurface,false,mGradFlags);
- mElement.mFirst = 0;
- mElement.mCount = 0;
- mElement.mScaleMode = ssmNormal;
+ if (mElement.mSurface)
+ {
+ mElement.mFlags |= DRAW_HAS_TEX;
+ mElement.mTexOffset = mElement.mVertexOffset + mElement.mStride;
+ mElement.mStride = 2*sizeof(float);
+ }
+
mElement.mWidth = stroke->thickness;
AddTriangleLines(inJob.mTriangles);
}
@@ -118,36 +196,68 @@ public:
else if (tile_mode)
{
bool has_colour = false;
- BlendMode bm = bmNormal;
- GetTileFlags(&inPath.commands[inJob.mCommand0], inJob.mCommandCount, has_colour, bm);
- mArrays = &ioData.GetArrays(mSurface,has_colour,(bm == bmAdd) ? HardwareArrays::BM_ADD : (bm == bmMultiply) ? HardwareArrays::BM_MULTIPLY : (bm == bmScreen) ? HardwareArrays::BM_SCREEN : 0);
- AddTiles(&inPath.commands[inJob.mCommand0], inJob.mCommandCount, &inPath.data[inJob.mData0]);
+ const uint8 *cmd = &inPath.commands[inJob.mCommand0];
+ int cc = inJob.mCommandCount;
+ int tiles = 0;
+
+ for(int i=0;iGetAlphaMode() == amPremultiplied)) ? mGradFlags | HardwareArrays::AM_PREMULTIPLIED : mGradFlags);
AddLineTriangles(&inPath.commands[inJob.mCommand0], inJob.mCommandCount, &inPath.data[inJob.mData0]);
}
else
{
- mArrays = &ioData.GetArrays(mSurface,false,(mSurface && (mSurface->GetAlphaMode() == amPremultiplied)) ? mGradFlags | HardwareArrays::AM_PREMULTIPLIED : mGradFlags);
AddObject(&inPath.commands[inJob.mCommand0], inJob.mCommandCount, &inPath.data[inJob.mData0]);
}
}
-
-
+
+ void ReserveArrays(int inN)
+ {
+ mElement.mCount = inN;
+ data.mArray.resize( mElement.mVertexOffset + mElement.mStride*inN );
+ }
+
+
bool SetFill(IGraphicsFill *inFill,HardwareContext &inHardware)
{
- mSurface = 0;
- mElement.mBitmapRepeat = true;
- mElement.mBitmapSmooth = false;
mGradFlags = 0;
+ if (mElement.mSurface)
+ {
+ mElement.mSurface->DecRef();
+ mElement.mSurface = 0;
+ }
GraphicsSolidFill *solid = inFill->AsSolidFill();
if (solid)
{
- //if (solid -> mRGB.a == 0)
- //return false;
mElement.mColour = solid->mRGB.ToInt();
}
else
@@ -157,37 +267,37 @@ public:
{
mGradReflect = grad->spreadMethod == smReflect;
int w = mGradReflect ? 512 : 256;
- mSurface = new SimpleSurface(w,1,pfARGB);
- mSurface->IncRef();
- grad->FillArray( (ARGB *)mSurface->GetBase(), false);
-
- mElement.mBitmapRepeat = grad->spreadMethod!=smPad;
- mElement.mBitmapSmooth = true;
+ mElement.mSurface = new SimpleSurface(w,1,pfARGB);
+ mElement.mSurface->IncRef();
+ grad->FillArray( (ARGB *)mElement.mSurface->GetBase(), false);
+ if (grad->spreadMethod!=smPad)
+ mElement.mFlags |= DRAW_BMP_REPEAT;
+ mElement.mFlags |= DRAW_BMP_SMOOTH;
+
mTextureMapper = grad->matrix.Inverse();
if (!grad->isLinear)
{
- mGradFlags |= HardwareArrays::RADIAL;
+ mElement.mFlags |= DRAW_RADIAL;
if (grad->focalPointRatio!=0)
{
- int r = fabs(grad->focalPointRatio)*256.0;
- if (r>255) r = 255;
-
- mGradFlags |= (r << 8);
- if (grad->focalPointRatio<0)
- mGradFlags |= HardwareArrays::FOCAL_SIGN;
+ int r = grad->focalPointRatio*10000.0;
+ if (r<-10000) r = -10000;
+ if (r>10000) r = 10000;
+ mElement.mRadialPos = r;
}
}
- //return true;
}
else
{
GraphicsBitmapFill *bmp = inFill->AsBitmapFill();
mTextureMapper = bmp->matrix.Inverse();
- mSurface = bmp->bitmapData->IncRef();
- mTexture = mSurface->GetOrCreateTexture(inHardware);
- mElement.mBitmapRepeat = bmp->repeat;
- mElement.mBitmapSmooth = bmp->smooth;
+ mElement.mSurface = bmp->bitmapData->IncRef();
+ mTexture = mElement.mSurface->GetOrCreateTexture(inHardware);
+ if (bmp->repeat)
+ mElement.mFlags |= DRAW_BMP_REPEAT;
+ if (bmp->smooth)
+ mElement.mFlags |= DRAW_BMP_SMOOTH;
}
}
//return false;
@@ -196,22 +306,22 @@ public:
~HardwareBuilder()
{
- if (mSurface)
- mSurface->DecRef();
+ if (mElement.mSurface)
+ mElement.mSurface->DecRef();
}
void CalcTexCoords()
{
- Vertices &vertices = mArrays->mVertices;
- Vertices &tex = mArrays->mTexCoords;
- int v0 = vertices.size();
- int t0 = tex.size();
- tex.resize(v0);
- bool radial = mGradFlags & HardwareArrays::RADIAL;
- for(int i=t0;ix,vertices->y);
+ Next(vertices);
+
if (mTexture)
{
p = mTexture->PixelToTex(p);
@@ -238,102 +348,107 @@ public:
p.x *= 0.5;
}
}
- tex[i] = p;
+ *tex = p;
+ Next(tex);
}
}
+
+ template
+ void Next(T *&ptr)
+ {
+ ptr = (T *)( (char *)ptr + mElement.mStride );
+ }
void AddTriangles(GraphicsTrianglePath *inPath)
{
- Vertices &vertices = mArrays->mVertices;
- Colours &colours = mArrays->mColours;
- Vertices &tex = mArrays->mTexCoords;
- DrawElements &elements = mArrays->mElements;
- bool persp = inPath->mType == vtVertexUVT;
- mElement.mFirst = vertices.size() / (persp?2:1);
+ int n = inPath->mVertices.size();
+ ReserveArrays(n);
+
+ UserPoint *vertices = (UserPoint *)&data.mArray[ mElement.mVertexOffset ];
+ int *colours = (mElement.mFlags & DRAW_HAS_COLOUR) ? (int *)&data.mArray[ mElement.mColourOffset ] : 0;
+ UserPoint *tex = (mElement.mFlags & DRAW_HAS_TEX) ? (UserPoint *)&data.mArray[ mElement.mTexOffset ] : 0;
+ bool persp = mElement.mFlags & DRAW_HAS_PERSPECTIVE;
+ int stride = mElement.mStride;
+
mElement.mPrimType = ptTriangles;
const float *t = &inPath->mUVT[0];
- for(int v=0;vmVertices.size();v++)
+ for(int v=0;vmVertices[v]);
- if(inPath->mColours.size()>0)
- {
- colours.push_back(inPath->mColours[v]);/*mwb*/
- }
+ *vertices = inPath->mVertices[v];
+ Next(vertices);
+ }
+
+ if(colours)
+ {
+ *colours = inPath->mColours[v];
+ Next(colours);
}
if (inPath->mType != vtVertex)
{
- tex.push_back( mTexture->TexToPaddedTex( UserPoint(t[0],t[1]) ) );
+ *tex = mTexture->TexToPaddedTex( UserPoint(t[0],t[1]) );
+ Next(tex);
+
t+=2;
if (persp)
{
float w= 1.0/ *t++;
- vertices.push_back(inPath->mVertices[v]*w);
- vertices.push_back( UserPoint(0,w) );
+ vertices[0] = inPath->mVertices[v]*w;
+ vertices[1] = UserPoint(0,w);
+ Next(vertices);
}
}
}
- mElement.mCount = (vertices.size() - mElement.mFirst)/(persp ? 2:1);
- elements.push_back(mElement);
+ mElement.mCount = n;
+
+ PushElement();
}
void AddTriangleLines(GraphicsTrianglePath *inPath)
{
- Vertices &vertices = mArrays->mVertices;
- DrawElements &elements = mArrays->mElements;
- mElement.mFirst = vertices.size();
mElement.mPrimType = ptLines;
int tri_count = inPath->mVertices.size()/3;
+ ReserveArrays(tri_count*6);
+
+ UserPoint *vertices = (UserPoint *)&data.mArray[mElement.mVertexOffset];
UserPoint *tri = &inPath->mVertices[0];
for(int v=0;vmVertices;
- Vertices &tex = mArrays->mTexCoords;
- Colours &colours = mArrays->mColours;
- const UserPoint *point = (const UserPoint *)inData;
- mElement.mFirst = vertices.size();
-
- vertices.reserve(vertices.size() + (6 * inCount));
- tex.reserve(tex.size() + (6 * inCount));
- colours.reserve(colours.size() + (6 * inCount));
+ UserPoint *point = (UserPoint *)inData;
for(int i=0;iPixelToTex(tex_pos);
- const UserPoint tp2 = mTexture->PixelToTex(UserPoint(tex_pos.x+size.x,tex_pos.y+size.y));
- tex.push_back( tp1 );
- tex.push_back( mTexture->PixelToTex(UserPoint(tex_pos.x+size.x,tex_pos.y)) );
- tex.push_back( tp2 );
- tex.push_back( tp1 );
- tex.push_back( tp2 );
- tex.push_back( mTexture->PixelToTex(UserPoint(tex_pos.x,tex_pos.y+size.y)) );
+ pos = tex_pos;
+ *tex = ( mTexture->PixelToTex(pos) );
+ Next(tex);
+ *tex = ( mTexture->PixelToTex(UserPoint(pos.x+size.x,pos.y)) );
+ Next(tex);
+ *tex = ( mTexture->PixelToTex(UserPoint(pos.x+size.x,pos.y+size.y)) );
+ Next(tex);
+ *tex = ( mTexture->PixelToTex(pos) );
+ Next(tex);
+ *tex = ( mTexture->PixelToTex(UserPoint(pos.x+size.x,pos.y+size.y)) );
+ Next(tex);
+ *tex = ( mTexture->PixelToTex(UserPoint(pos.x,pos.y+size.y)) );
+ Next(tex);
if (inCommands[i]&pcTile_Col_Bit)
{
- const UserPoint &rg = *point++;
- const UserPoint &ba = *point++;
+ UserPoint rg = *point++;
+ UserPoint ba = *point++;
#ifdef BLACKBERRY
- const uint32 col = ((int)(rg.x*255)) |
- (((int)(rg.y*255))<<8) |
- (((int)(ba.x*255))<<16) |
- (((int)(ba.y*255))<<24);
+ uint32 col = ((int)(rg.x*255)) |
+ (((int)(rg.y*255))<<8) |
+ (((int)(ba.x*255))<<16) |
+ (((int)(ba.y*255))<<24);
#else
- const uint32 col = ((rg.x<0 ? 0 : rg.x>1?255 : (int)(rg.x*255))) |
- ((rg.y<0 ? 0 : rg.y>1?255 : (int)(rg.y*255))<<8) |
- ((ba.x<0 ? 0 : ba.x>1?255 : (int)(ba.x*255))<<16) |
- ((ba.y<0 ? 0 : ba.y>1?255 : (int)(ba.y*255))<<24);
+ uint32 col = ((rg.x<0 ? 0 : rg.x>1?255 : (int)(rg.x*255))) |
+ ((rg.y<0 ? 0 : rg.y>1?255 : (int)(rg.y*255))<<8) |
+ ((ba.x<0 ? 0 : ba.x>1?255 : (int)(ba.x*255))<<16) |
+ ((ba.y<0 ? 0 : ba.y>1?255 : (int)(ba.y*255))<<24);
#endif
- colours.push_back( col );
- colours.push_back( col );
- colours.push_back( col );
- colours.push_back( col );
- colours.push_back( col );
- colours.push_back( col );
+
+ *colours = ( col );
+ Next(colours);
+ *colours = ( col );
+ Next(colours);
+ *colours = ( col );
+ Next(colours);
+ *colours = ( col );
+ Next(colours);
+ *colours = ( col );
+ Next(colours);
+ *colours = ( col );
+ Next(colours);
}
}
}
}
- mElement.mCount = vertices.size() - mElement.mFirst;
+ mElement.mCount = inTiles*6;
if (mElement.mCount>0)
- mArrays->mElements.push_back(mElement);
+ PushElement();
+ }
+
+ void PushElement()
+ {
+ if (mElement.mCount>0)
+ {
+ /*
+ if (data.mElements.size()>0)
+ {
+ DrawElement &e = data.mElements.last();
+ if (e.mFlags==mElement.mFlags &&
+ (e.mPrimType==ptLines || e.mPrimType==ptTriangles || e.mPrimType==ptPoints) &&
+ e.mPrimType==mElement.mPrimType &&
+ e.mBlendMode==mElement.mBlendMode &&
+ e.mRadialPos==mElement.mRadialPos &&
+ e.mSurface==mElement.mSurface &&
+ e.mColour==mElement.mColour &&
+ e.mWidth==mElement.mWidth )
+ {
+ e.mCount += mElement.mCount;
+ return;
+ }
+ }
+ */
+ data.mElements.push_back(mElement);
+ if (mElement.mSurface)
+ mElement.mSurface->IncRef();
+ }
+ }
+
+ void PushVertices(const Vertices &inV)
+ {
+ ReserveArrays(inV.size());
+
+ //printf("PushVertices %d\n", inV.size());
+
+ UserPoint *v = (UserPoint *)&data.mArray[mElement.mVertexOffset];
+ for(int i=0;imVertices;
- mElement.mFirst = vertices.size();
bool isConvex = inSubPolys.size()==1;
if (mSolidMode)
{
@@ -473,16 +657,14 @@ public:
}
- mElement.mCount = inOutline.size();
- vertices.resize(mElement.mFirst + mElement.mCount);
- for(int i=0;imElements.push_back(mElement);
+ mElement.mVertexOffset = data.mArray.size();
+ if (mElement.mSurface)
+ mElement.mTexOffset = mElement.mVertexOffset + 2*sizeof(float);
+
+ PushVertices(inOutline);
if (!isConvex)
- mArrays->mElements.last().mPrimType = ptTriangles;
+ data.mElements.last().mPrimType = ptTriangles;
}
@@ -610,207 +792,285 @@ public:
UserPoint curve;
};
- void AddArc(Vertices &vertices,UserPoint inP, double angle, UserPoint inVx, UserPoint inVy, UserPoint p0, UserPoint p1)
+ void AddArc(Curves &outCurve, UserPoint inP, double angle, UserPoint inVx, UserPoint inVy, float t)
{
- int steps = 1 + angle*8;
+ int steps = 1 + mPerpLen*angle*3;
+ if (steps>60)
+ steps = 60;
double d_theta = angle / (steps+1);
double theta = d_theta;
- for(int i=0;imMiterLimit)
{
UserPoint corner0 = p0+dir1*mMiterLimit;
UserPoint corner1 = p1-dir2*mMiterLimit;
- vertices.push_back(inP);
- vertices.push_back(p0);
- vertices.push_back(corner0);
-
- vertices.push_back(inP);
- vertices.push_back(corner0);
- vertices.push_back(corner1);
-
- vertices.push_back(inP);
- vertices.push_back(corner1);
- vertices.push_back(p1);
+ outCurves.push_back( CurveEdge(corner0, t+0.33) );
+ outCurves.push_back( CurveEdge(corner1, t+0.66) );
}
else
{
- UserPoint corner = p0+dir1*inAlpha;
- vertices.push_back(inP);
- vertices.push_back(p0);
- vertices.push_back(corner);
-
- vertices.push_back(inP);
- vertices.push_back(corner);
- vertices.push_back(p1);
+ UserPoint corner0 = p0+dir1*inAlpha;
+ UserPoint corner1 = p1-dir2*inAlpha;
+ UserPoint diff = corner1-corner0;
+ outCurves.push_back( CurveEdge(corner1, t+0.501) );
}
}
-
- void AddCurveSegment(Vertices &vertices,UserPoint inP0,UserPoint inP1,UserPoint inP2, UserPoint perp0, UserPoint perp1,
- UserPoint p0_left, UserPoint p0_right, UserPoint p1_left, UserPoint p1_right)
+
+
+ void removeLoops(QuickVec &curve,int startPoint,float turningPoint)
{
- double len = (inP0 - inP1).Norm() + (inP2 - inP1).Norm();
-
- int steps = (int)len*0.1;
-
- if (len < 50 && steps < 10) steps = 50;
- else if (steps < 1) steps = 1;
- else if (steps > 100) steps = 100;
-
- double step = 1.0 / (steps);
- double t = 0;
-
- UserPoint v0 = p0_right - p0_left;
- UserPoint v1 = p1_right - p1_left;
-
- UserPoint last_p_left = inP0 - perp0;
- UserPoint last_p_right = inP0 + perp0;
-
- // Clip against end ...
- if ( v0.Cross(last_p_left-p0_left)>0 )
- last_p_left = p0_left;
- if ( v0.Cross(last_p_right-p0_left)>0 )
- last_p_right = p0_right;
- // TODO - against other end?
- for (int s=1; s <= steps; s++)
+ for(int i=startPoint;iturningPoint;
+ for(int j=i+2;j0)
- p_left = p0_left;
- if ( v0.Cross(p_right-p0_left)>0)
- p_right = p0_right;
- }
+ const UserPoint &l0 = curve[j].p;
+ const UserPoint &l1 = curve[j+1].p;
+ if ( (l0.xmaxX && l1.x>maxX) ||
+ (l0.ymaxY && l1.y>maxY) )
+ continue;
- if (v1.Cross(dir) < 0 ) // if pointing in same direction (left-handed)
- {
- if ( v1.Cross(p_left-p1_left)<0)
- p_left = p1_left;
- if ( v1.Cross(p_right-p1_left)<0)
- p_right = p1_right;
- }
+ // Only consider intersection with self or joint for second half of curve
+ if (turningPoint>0 && curve[j].t>turningPoint && cti<(int)curve[j].t-1)
+ break;
- if (p_left==last_p_left)
- {
- if (p_right!=last_p_right)
+ UserPoint dl = l1-l0;
+ // Solve p0.x + a dp.x = l0.x + b dl.x
+ // p0.y + a dp.y = l0.y + b dl.y
+
+ // Solve p0.x*dp.y + a dp.x*dp.y = l0.x*dp.y + b dl.x*dp.y
+ // p0.y*dp.x + a dp.y*dp.x = l0.y*dp.x + b dl.y*dp.x
+ // p0 x dp - l0 x dp = b dl x dp
+ // (p0-l0) x dp = b dl x dp
+ double denom = dl.Cross(dp);
+ if (denom!=0.0)
{
- vertices.push_back(p_left);
- vertices.push_back(last_p_right);
- vertices.push_back(p_right);
+ double b = (p0-l0).Cross(dp)/denom;
+ if (b>=0 && b<=1.0)
+ {
+ double a = (fabs(dp.x) > fabs(dp.y)) ? (l0.x + b*dl.x - p0.x)/dp.x :
+ (l0.y + b*dl.y - p0.y)/dp.y;
+ if (a>=0 && a<=1)
+ {
+ if (a>0 && a<1 && b>0 && b<1)
+ {
+ UserPoint p = p0 + dp*a;
+ // Remove the loop
+ // c[i]
+ // p <- new point between c[i] and c[i+1]
+ // c[i+1]
+ // c[i+2]
+ // ...
+ // c[j]
+ // p <- new point between c[j] and c[j+1]
+ // c[j+1]
+ {
+ // replace c[i+1] with p, and erase upto and including c[j]
+ p1 = p;
+ curve.EraseAt(i+2,j+1);
+ break;
+ }
+ }
+ }
+ }
}
}
- else if (p_right==last_p_right)
+ }
+ }
+
+
+ void AddCurveSegment(Curves &leftCurve, Curves &rightCurve,
+ UserPoint perp0, UserPoint perp1,
+ UserPoint inP0,UserPoint inP1,UserPoint inP2,
+ UserPoint p0_left, UserPoint p0_right,UserPoint p1_left, UserPoint p1_right, float t0)
+ {
+
+ QuickVec stack;
+ Range r0(0,inP0-perp0, inP0+perp0, 1,inP2-perp1, inP2+perp1);
+ stack.push_back(r0);
+
+ while(stack.size())
+ {
+ Range r = stack.qpop();
+ if (r.t1-r.t0 > 0.001 )
{
- if (p_left!=last_p_left)
+ // Calc midpoint...
+ double t = (r.t0+r.t1)*0.5;
+ double t_ = 1.0 - t;
+ UserPoint mid_p = inP0 * (t_ * t_) + inP1 * (2.0 * t * t_) + inP2 * (t * t);
+ UserPoint dir = (inP0 * -t_ + inP1 * (1.0 - 2.0 * t) + inP2 * t);
+ UserPoint mid_l = mid_p - dir.Perp(mPerpLen);
+ UserPoint mid_r = mid_p + dir.Perp(mPerpLen);
+
+ UserPoint average_l = (r.left0+r.left1)*0.5;
+ UserPoint average_r = (r.right0+r.right1)*0.5;
+ if ( mid_l.Dist2(average_l)>mCurveThresh2 || mid_r.Dist2(average_r)>mCurveThresh2)
{
- vertices.push_back(last_p_left);
- vertices.push_back(p_right);
- vertices.push_back(p_left);
+ // Reverse order, LIFO
+ stack.push_back( Range(t,mid_l,mid_r, r.t1,r.left1,r.right1) );
+ r.t1 = t;
+ r.left1 = mid_l;
+ r.right1 = mid_r;
+ stack.push_back(r);
+ continue;
}
+ // Too much curvature?
+ // dir = pert @ mid_t
+ /*
+ t+=0.001;
+ t_ = 1.0 - t;
+ UserPoint p_plus = inP0 * (t_ * t_) + inP1 * (2.0 * t * t_) + inP2 * (t * t);
+ UserPoint perp_plus = (inP0 * -t_ + inP1 * (1.0 - 2.0 * t) + inP2 * t).Perp(mPerpLen);
+
+ if (r.t0==0.0 || (mid_p-p_plus).Dot(mid_l-(p_plus-perp_plus)) > 0)
+ leftCurve.push_back( CurveEdge(r.left0,r.t0+t0) );
+
+ if ( (mid_p-p_plus).Dot(mid_r-(p_plus+perp_plus)) > 0)
+ rightCurve.push_back( CurveEdge(r.right0,r.t0+t0) );
+
+ continue;
+ */
+ }
+ leftCurve.push_back( CurveEdge(r.left0,r.t0+t0) );
+ rightCurve.push_back( CurveEdge(r.right0,r.t0+t0) );
+ }
+ leftCurve.push_back( CurveEdge(inP2-perp1,0.9999+t0) );
+ rightCurve.push_back( CurveEdge(inP2+perp1,0.9999+t0) );
+ }
+
+ void EndCap(Curves &left, Curves &right, UserPoint p0, UserPoint perp, double t)
+ {
+ bool first = t==0;
+
+ UserPoint back(-perp.y, perp.x);
+ if (!first)
+ {
+ back.x*=-1;
+ back.y*=-1;
+ }
+
+ if (mCaps==scSquare)
+ {
+ if (first)
+ {
+ left.push_back(CurveEdge(p0+back,t));
+ right.push_back(CurveEdge(p0+back,t));
+
+ left.push_back(CurveEdge(p0+back-perp,t+0.5));
+ right.push_back(CurveEdge(p0+back+perp,t+0.5));
}
else
{
- vertices.push_back(last_p_left);
- vertices.push_back(last_p_right);
- vertices.push_back(p_left);
+ left.push_back(CurveEdge(p0-perp,t));
+ right.push_back(CurveEdge(p0+perp,t));
- vertices.push_back(p_left);
- vertices.push_back(last_p_right);
- vertices.push_back(p_right);
+ left.push_back(CurveEdge(p0+back-perp,t+0.5));
+ right.push_back(CurveEdge(p0+back+perp,t+0.5));
}
-
- last_p_left = p_left;
- last_p_right = p_right;
- }
- }
-
- void EndCap(Vertices &vertices,UserPoint p0, UserPoint perp)
- {
- UserPoint back(-perp.y, perp.x);
- if (mCaps==scSquare)
- {
- vertices.push_back(p0+perp);
- vertices.push_back(p0+perp + back);
- vertices.push_back(p0-perp);
-
- vertices.push_back(p0+perp + back);
- vertices.push_back(p0-perp + back);
- vertices.push_back(p0-perp);
}
else
{
int n = std::max(2,(int)(mPerpLen * 4));
- double dtheta = M_PI / n;
- double theta = 0.0;
- UserPoint prev(perp);
+ double dtheta = M_PI*0.5 / n;
+
for(int i=1;ip
+
+ */
+
+ float dist = fabs( (p-base).Dot( (p-prev).Perp(1.0) ) );
+ if (!inAllowSmaller && dist &inPath, bool inLoop)
{
- Vertices &vertices = mArrays->mVertices;
- mElement.mFirst = vertices.size();
+ if (inPath.size()<2)
+ return;
+
+ Curves leftCurve;
+ Curves rightCurve;
+
+ float t = 0.0;
+ int prevSegLeft = 0;
+ int prevSegRight = 0;
// Endcap 0 ...
- if (!inLoop && (mCaps==scSquare || mCaps==scRound))
+ if (!inLoop)
{
- UserPoint p0 = inPath[0].p;
- EndCap(vertices, p0, inPath[1].getDir0(p0).Perp(mPerpLen));
+ if (mCaps==scSquare || mCaps==scRound)
+ {
+ UserPoint p0 = inPath[0].p;
+ EndCap(leftCurve, rightCurve, p0, inPath[1].getDir0(p0).Perp(mPerpLen),t);
+ }
}
+ t+=1.0;
+
+ UserPoint p;
+ UserPoint dir1;
- double prev_alpha = 0;
for(int i=1;i next_perp-perp1 = alpha*(dir1+next_dir)
- -> alpha = prep1-next_perp in either x or y direction...
- ---------------
- dir1+next_dir
-
- Make the split such that DpY and down belongs to this segment - first add this DpY triangle, then
- the remainder of the segment happens below the D-Y line.
-
- On one side (right hand, drawn here) the segments will overlap - on the other side, there
- will be a join. Which side this will be depends on the sign of alpha. When reversed, the
- roles of Y and Z will change.
-
- BpY is for this upper segment - but there is an equivalent B'p0Y' for this segment.
- First we add B'p-Y' triangle, and work from B'Y' line
- */
UserPoint perp0(-dir0.y*mPerpLen, dir0.x*mPerpLen);
UserPoint perp1(-dir1.y*mPerpLen, dir1.x*mPerpLen);
UserPoint next_perp(-next_dir.y*mPerpLen, next_dir.x*mPerpLen);
- double denom_x = dir1.x+next_dir.x;
- double denom_y = dir1.y+next_dir.y;
- double alpha=0;
-
- // Choose the better-conditioned axis
- if (fabs(denom_x)>fabs(denom_y))
- alpha = denom_x==0 ? 0 : (perp1.x-next_perp.x)/denom_x;
- else
- alpha = denom_y==0 ? 0 : (perp1.y-next_perp.y)/denom_y;
UserPoint p1_left = p-perp1;
UserPoint p1_right = p+perp1;
- // This could start getting dodgy when the line doubles-back
- double max_alpha = std::max( (p0-p).Norm()*0.5, mPerpLen );
- if (fabs(alpha)>max_alpha)
- {
- // draw overlapped
- }
- else if (alpha>0)
- {
- p1_right -= dir1 * alpha;
- vertices.push_back(p1_left);
- vertices.push_back(p);
- vertices.push_back(p1_right);
- }
- else if (alpha<0)
- {
- p1_left += dir1 * alpha;
- vertices.push_back(p1_left);
- vertices.push_back(p);
- vertices.push_back(p1_right);
- }
-
UserPoint p0_left = p0-perp0;
UserPoint p0_right = p0+perp0;
- if (i==1 && inLoop)
- {
- UserPoint prev_dir = inPath[inPath.size()-1].getDir1(inPath[inPath.size()-2].p).Normalized();
- UserPoint prev_perp(-prev_dir.y*mPerpLen, prev_dir.x*mPerpLen);
- double denom_x = prev_dir.x+dir0.x;
- double denom_y = prev_dir.y+dir0.y;
-
- // Choose the better-conditioned axis
- if (fabs(denom_x)>fabs(denom_y))
- prev_alpha = denom_x==0 ? 0 : (prev_perp.x-perp0.x)/denom_x;
- else
- prev_alpha = denom_y==0 ? 0 : (prev_perp.y-perp0.y)/denom_y;
- }
-
- if (fabs(prev_alpha)>max_alpha)
- {
- // do nothing
- }
- else if (prev_alpha>0)
- {
- p0_right += dir0 * std::min(prev_alpha,max_alpha);
- vertices.push_back(p0_left);
- vertices.push_back(p0);
- vertices.push_back(p0_right);
- }
- else if (prev_alpha<0)
- {
- p0_left -= dir0 * std::max(prev_alpha,-max_alpha);
- vertices.push_back(p0_left);
- vertices.push_back(p0);
- vertices.push_back(p0_right);
- }
-
- if (alpha)
- switch(mPerpLen<1 ? sjBevel : mJoints)
- {
- case sjRound:
- {
- double angle = acos(dir1.Dot(next_dir));
- if (angle<0) angle += M_PI;
- if (alpha>0) // left
- AddArc(vertices, p, angle, -perp1, dir1*mPerpLen, p1_left, p-next_perp );
- else // right
- AddArc(vertices, p, angle, perp1, dir1*mPerpLen, p1_right, p+next_perp );
- }
- break;
-
- case sjMiter:
- if (alpha>0) // left
- AddMiter(vertices, p, p-perp1, p-next_perp, alpha, dir1, next_dir);
- else // Right
- AddMiter(vertices, p, p+perp1, p+next_perp, -alpha, dir1, next_dir);
- break;
-
- case sjBevel:
- if (alpha>0) // left
- {
- vertices.push_back(p1_left);
- vertices.push_back(p);
- vertices.push_back(p-next_perp);
- }
- else
- {
- vertices.push_back(p1_right);
- vertices.push_back(p);
- vertices.push_back(p+next_perp);
- }
- break;
- }
+ int segStartLeft = leftCurve.size();
+ int segStartRight = rightCurve.size();
if (seg.isCurve())
{
- AddCurveSegment(vertices,p0,seg.curve,seg.p, perp0, perp1, p0_left, p0_right, p1_left, p1_right);
+ AddCurveSegment(leftCurve,rightCurve,perp0, perp1,p0,seg.curve,seg.p, p0_left, p0_right, p1_left, p1_right,t);
+ t+=1.0;
}
else
{
- vertices.push_back(p0_left);
- vertices.push_back(p0_right);
- vertices.push_back(p1_right);
+ leftCurve.push_back( CurveEdge(p0_left,t) );
+ leftCurve.push_back( CurveEdge(p1_left,t+0.99) );
- vertices.push_back(p0_left);
- vertices.push_back(p1_right);
- vertices.push_back(p1_left);
+ rightCurve.push_back( CurveEdge(p0_right,t) );
+ rightCurve.push_back( CurveEdge(p1_right,t+0.99) );
+
+ t+=1.0;
}
- // Endcap end ...
- if (!inLoop && (i+1==inPath.size()) && (mCaps==scSquare || mCaps==scRound))
- EndCap(vertices, p, dir1.Perp(-mPerpLen));
+ float segJoinLeft = leftCurve.last().t;
+ float segJoinRight = rightCurve.last().t;
- prev_alpha = alpha;
+ bool reversed = next_dir.Dot(dir1)<0;
+ bool fullReverse = reversed && next_dir.Dot(dir1)<-0.99;
+ if (fullReverse)
+ {
+ leftCurve.push_back( CurveEdge(p1_right,t) );
+ rightCurve.push_back( CurveEdge(p1_left,t) );
+ segStartLeft = prevSegLeft = leftCurve.size();
+ segStartRight = prevSegRight = rightCurve.size();
+ }
+ else if (mPerpLen>1 && (mJoints==sjRound || mJoints==sjMiter) && (reversed || fabs(next_dir.Cross(dir1))>0.25 ) )
+ {
+ /*
+
+ ---
+ ---
+ ---
+ - B- next segment
+ Z \ ...
+ | \ ...
+ D_____\ ...____
+ | p C ---.
+ | .\ | ---
+ | . \ -Y-
+ | . A-- |
+ | . |
+ | . | p = end segment
+ | . |
+ | . |
+ | . |
+
+ A = p + next_perp
+ B = p - next_perp
+
+ C = p + perp1
+ D = p - perp1
+
+ Y = A + alpha*next_dir
+ = C - alpha*dir1
+
+ = p + next_perp + alpha*next_dir
+ = p + perp1 - alpha*dir1
+
+ -> next_perp-perp1 = alpha*(dir1+next_dir)
+ -> alpha = prep1-next_perp in either x or y direction...
+ ---------------
+ dir1+next_dir
+
+ On the overlap side, we will draw a bevel, and let the removeLoops code fix it.
+ On the non-overlay side, we will draw a joint
+ */
+
+
+
+ double denom_x = dir1.x+next_dir.x;
+ double denom_y = dir1.y+next_dir.y;
+ double alpha=0;
+
+ // Choose the better-conditioned axis
+ if (fabs(denom_x)>fabs(denom_y))
+ alpha = denom_x==0 ? 0 : (perp1.x-next_perp.x)/denom_x;
+ else
+ alpha = denom_y==0 ? 0 : (perp1.y-next_perp.y)/denom_y;
+
+ if ( fabs(alpha)>0.01 )
+ {
+ if (mJoints==sjRound)
+ {
+ double angle = acos(dir1.Dot(next_dir));
+ if (angle<0) angle += M_PI;
+ if (alpha>0) // left
+ AddArc(leftCurve, p, angle, -perp1, dir1*mPerpLen, t );
+ else // right
+ AddArc(rightCurve, p, angle, perp1, dir1*mPerpLen, t );
+ }
+ else
+ {
+ if (alpha>0) // left
+ {
+ AddMiter(leftCurve, p, p1_left, p-next_perp, alpha, dir1, next_dir,t);
+ }
+ else // Right
+ {
+ AddMiter(rightCurve, p, p1_right, p+next_perp, -alpha, dir1, next_dir,t);
+ }
+ }
+ }
+ }
+ t+=1.0;
+
+ float turnLeft = seg.isCurve() ? segJoinLeft - 0.66 : 0;
+ float turnRight = seg.isCurve() ? segJoinRight - 0.66 : 0;
+ removeLoops(leftCurve,prevSegLeft,turnLeft);
+ removeLoops(rightCurve,prevSegRight,turnRight);
+
+ prevSegLeft = segStartLeft;
+ prevSegRight = segStartRight;
}
+ // Endcap end ...
+ if (!inLoop && (mCaps==scSquare || mCaps==scRound))
+ {
+ EndCap(leftCurve, rightCurve, p, dir1.Perp(mPerpLen),t);
+ }
- mElement.mCount = vertices.size()-mElement.mFirst;
- if (mSurface)
+ removeLoops(leftCurve,prevSegLeft,0);
+ removeLoops(rightCurve,prevSegRight,0);
+
+
+ if (leftCurve.size()<2 || rightCurve.size()<2)
+ return;
+
+ bool useTriStrip = true;
+ bool keepTriSense = true;
+
+ data.mArray.reserve( mElement.mVertexOffset + (leftCurve.size() + rightCurve.size()) * mElement.mStride * (useTriStrip?2:3) );
+
+ UserPoint *v = (UserPoint *)&data.mArray[mElement.mVertexOffset];
+ UserPoint *normal = (mElement.mFlags & DRAW_HAS_NORMAL) ? (UserPoint *)&data.mArray[mElement.mNormalOffset] : 0;
+
+ UserPoint pLeft = leftCurve[0].p;
+ UserPoint pRight = rightCurve[0].p;
+
+ UserPoint leftNormal(mElement.mWidth*0.5, -mPerpLen);
+ UserPoint rightNormal(mElement.mWidth*0.5, mPerpLen);
+
+
+ if (useTriStrip)
+ {
+ *v = pRight; Next(v);
+ if (normal)
+ { *normal = rightNormal; Next(normal); }
+
+ *v = pLeft; Next(v);
+ if (normal)
+ { *normal = leftNormal; Next(normal); }
+ }
+
+ int added = useTriStrip ? 2 : 0;
+ int left = 1;
+ int right = 1;
+
+
+ enum { PREV_LEFT, PREV_RIGHT };
+ int prevEdge = PREV_LEFT;
+
+
+ while(left=leftCurve.size() || (right=0)
+ {
+ if (!useTriStrip)
+ {
+ *v = pRight; Next(v);
+ if (normal)
+ { *normal = rightNormal; Next(normal); }
+
+ *v = pLeft; Next(v);
+ if (normal)
+ { *normal = leftNormal; Next(normal); }
+ added+=2;
+ }
+ else if (keepTriSense && prevEdge!=PREV_LEFT)
+ {
+ *v = pLeft; Next(v);
+ if (normal)
+ { *normal = leftNormal; Next(normal); }
+ added++;
+ }
+ added++;
+ if (normal)
+ {
+ *normal = rightNormal = CalcNormalInfo(pLeft, pRight, test, 1.0, testT<1 ||testT>=t);
+ Next(normal);
+ }
+ *v = pRight = test;
+ Next(v);
+ prevEdge = PREV_RIGHT;
+ }
+ }
+ else
+ {
+ float testT = rightCurve[left].t;
+ UserPoint test = leftCurve[left++].p;
+ if ( mPerpLen=0)
+ {
+ if (!useTriStrip)
+ {
+ *v = pRight; Next(v);
+ if (normal)
+ { *normal = rightNormal; Next(normal); }
+
+ *v = pLeft; Next(v);
+ if (normal)
+ { *normal = leftNormal; Next(normal); }
+ added+=2;
+ }
+ else if (keepTriSense && prevEdge!=PREV_RIGHT)
+ {
+ *v = pRight; Next(v);
+ if (normal)
+ { *normal = rightNormal; Next(normal); }
+ added++;
+ }
+
+ added++;
+ if (normal)
+ {
+ *normal = leftNormal = CalcNormalInfo(pRight, pLeft, test, -1.0, testT<1 || testT>=t);
+ Next(normal);
+ }
+ *v = pLeft = test;
+ Next(v);
+ prevEdge = PREV_LEFT;
+ }
+ }
+ }
+
+ // Build triangle strip....
+ mElement.mPrimType = useTriStrip ? ptTriangleStrip : ptTriangles;
+ mElement.mCount = added;
+ data.mArray.resize( mElement.mVertexOffset + mElement.mCount*mElement.mStride );
+
+ if (mElement.mSurface)
CalcTexCoords();
- mArrays->mElements.push_back(mElement);
- }
+ PushElement();
+ }
+
+
void AddLineTriangles(const uint8* inCommands, int inCount, const float *inData)
{
UserPoint *point = (UserPoint *)inData;
@@ -1098,21 +1441,34 @@ public:
}
}
- if (strip.size()>0)
+ if (strip.size()>1)
+ {
+ float s = mScale * 0.707;
+ if (data.mMinScale==0 || s>data.mMinScale)
+ data.mMinScale = s;
+
+ s = mScale * 1.41;
+ if (data.mMaxScale==0 || sAsSolidFill() : 0;
if (fill)
@@ -1140,90 +1497,124 @@ void CreatePointJob(const GraphicsJob &inJob,const GraphicsPath &inPath,Hardware
}
elem.mPrimType = ptPoints;
+ elem.mVertexOffset = ioData.mArray.size();
+ elem.mStride = sizeof(float)*2;
+ if (!fill)
+ {
+ elem.mColourOffset = elem.mVertexOffset + elem.mStride;
+ elem.mStride += sizeof(int);
+ elem.mFlags |= DRAW_HAS_COLOUR;
+ elem.mColour = 0xffffffff;
+ }
elem.mCount = inJob.mDataCount / (fill ? 2 : 3);
+ ioData.mArray.resize( elem.mVertexOffset + elem.mStride*elem.mCount );
- HardwareArrays *arrays = &ioData.GetArrays(0,fill==0, /* TODO: bm add ? */ 0);
- Vertices &vertices = arrays->mVertices;
- elem.mFirst = vertices.size();
- vertices.resize( elem.mFirst + elem.mCount );
- memcpy( &vertices[elem.mFirst], &inPath.data[ inJob.mData0 ], elem.mCount*sizeof(UserPoint) );
+ UserPoint *srcV = (UserPoint *)&inPath.data[ inJob.mData0 ];
+ UserPoint *v = (UserPoint *)&ioData.mArray[ elem.mVertexOffset ];
+
+ for(int i=0;imColours;
- colours.resize( elem.mFirst + elem.mCount );
const int * src = (const int *)(&inPath.data[ inJob.mData0 + elem.mCount*2]);
- int * dest = &colours[elem.mFirst];
- int n = elem.mCount;
- for(int i=0;i>16)&0xff) | ((s<<16) & 0xff0000);
+ *dest = (s & 0xff00ff00) | ((s>>16)&0xff) | ((s<<16) & 0xff0000);
+ dest = (int *)( (char *)dest + elem.mStride );
}
}
- arrays->mElements.push_back(elem);
+ ioData.mElements.push_back(elem);
}
void BuildHardwareJob(const GraphicsJob &inJob,const GraphicsPath &inPath,HardwareData &ioData,
- HardwareContext &inHardware)
+ HardwareContext &inHardware, const RenderState &inState)
{
+ ioData.releaseVbo();
+
if (inJob.mIsPointJob)
CreatePointJob(inJob,inPath,ioData,inHardware);
else
{
- HardwareBuilder builder(inJob,inPath,ioData,inHardware);
+ HardwareBuilder builder(inJob,inPath,ioData,inHardware, inState);
}
}
-// --- HardwareArrays ---------------------------------------------------------------------
-
-HardwareArrays::HardwareArrays(Surface *inSurface,unsigned int inFlags)
-{
- mFlags = inFlags;
- mSurface = inSurface;
- if (inSurface)
- inSurface->IncRef();
-}
-
-HardwareArrays::~HardwareArrays()
-{
- if (mSurface)
- mSurface->DecRef();
-}
-
-bool HardwareArrays::ColourMatch(bool inWantColour)
-{
- if (mVertices.empty())
- return true;
- return mColours.empty() != inWantColour;
-}
-
-
-
// --- HardwareData ---------------------------------------------------------------------
+
+HardwareData::HardwareData()
+{
+ mRendersWithoutVbo = 0;
+ mVertexBo = 0;
+ mContextId = 0;
+ mVboOwner = 0;
+ mMinScale = mMaxScale = 0.0;
+}
+
+void HardwareData::releaseVbo()
+{
+ if (mVboOwner)
+ {
+ if (mVertexBo && mContextId==gTextureContextVersion)
+ mVboOwner->DestroyVbo(mVertexBo);
+ mVboOwner->DecRef();
+ mVboOwner=0;
+ }
+ mContextId = 0;
+ mVertexBo = 0;
+ mRendersWithoutVbo = 0;
+}
+
+float HardwareData::scaleOf(const RenderState &inState) const
+{
+ const Matrix &m = *inState.mTransform.mMatrix;
+ return sqrt( 0.5*( m.m00*m.m00 + m.m01*m.m01 + m.m10*m.m10 + m.m11*m.m11 ) );
+}
+
+bool HardwareData::isScaleOk(const RenderState &inState) const
+{
+ if (mMinScale==0 && mMaxScale==0)
+ return true;
+
+ float scale = scaleOf(inState);
+ if (mMinScale>0 && scale0 && scale>mMaxScale)
+ {
+ //printf("%f>%f\n", scale, mMaxScale);
+ return false;
+ }
+ return true;
+}
+
+
+void HardwareData::clear()
+{
+ releaseVbo();
+ mArray.resize(0);
+ mElements.resize(0);
+ mMinScale = mMaxScale = 0.0;
+}
+
HardwareData::~HardwareData()
{
- mCalls.DeleteAll();
+ releaseVbo();
+ for(int i=0;iDecRef();
}
-HardwareArrays &HardwareData::GetArrays(Surface *inSurface,bool inWithColour,unsigned int inFlags)
-{
- if (mCalls.empty() || mCalls.last()->mSurface != inSurface ||
- !mCalls.last()->ColourMatch(inWithColour) ||
- mCalls.last()->mFlags != inFlags )
- {
- HardwareArrays *arrays = new HardwareArrays(inSurface,inFlags);
- mCalls.push_back(arrays);
- }
-
- return *mCalls.last();
-}
-
-
-
// --- Texture -----------------------------
void Texture::Dirty(const Rect &inRect)
{
@@ -1243,7 +1634,48 @@ double sLineScaleH = -1;
double sLineScaleNormal = -1;
-bool HardwareContext::Hits(const RenderState &inState, const HardwareCalls &inCalls )
+inline bool HitTri(const UserPoint &base, const UserPoint &_v0, const UserPoint &_v1, const UserPoint &pos)
+{
+ bool bgx = pos.x>base.x;
+ if ( bgx!=(pos.x>_v0.x) || bgx!=(pos.x>_v1.x) )
+ {
+ bool bgy = pos.y>base.y;
+ if ( bgy!=(pos.y>_v0.y) || bgy!=(pos.y>_v1.y) )
+ {
+ UserPoint v0 = _v0 - base;
+ UserPoint v1 = _v1 - base;
+ UserPoint v2 = pos - base;
+ double dot00 = v0.Dot(v0);
+ double dot01 = v0.Dot(v1);
+ double dot02 = v0.Dot(v2);
+ double dot11 = v1.Dot(v1);
+ double dot12 = v1.Dot(v2);
+
+ // Compute barycentric coordinates
+ double denom = (dot00 * dot11 - dot01 * dot01);
+ if (denom!=0)
+ {
+ denom = 1 / denom;
+ double u = (dot11 * dot02 - dot01 * dot12) * denom;
+ if (u>=0)
+ {
+ double v = (dot00 * dot12 - dot01 * dot02) * denom;
+
+ // Check if point is in triangle
+ if ( (v >= 0) && (u + v < 1) )
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
+
+
+bool HardwareContext::Hits(const RenderState &inState, const HardwareData &inData )
{
if (inState.mClipRect.w!=1 || inState.mClipRect.h!=1)
return false;
@@ -1260,164 +1692,137 @@ bool HardwareContext::Hits(const RenderState &inState, const HardwareCalls &inCa
}
- for(int c=0;cx1) prev |= 0x02;
- if (p0.yy1) prev |= 0x08;
- if (prev==0 && pos.Dist2(p0)<=w2)
+ int prev = 0;
+ if (p0.xx1) prev |= 0x02;
+ if (p0.yy1) prev |= 0x08;
+ if (prev==0 && pos.Dist2(p0)<=w2)
+ return true;
+ for(int i=1;ix1) flags |= 0x02;
+ if (p.yy1) flags |= 0x08;
+ if (flags==0 && pos.Dist2(p)<=w2)
return true;
- for(int i=1;ix1) flags |= 0x02;
- if (p.yy1) flags |= 0x08;
- if (flags==0 && pos.Dist2(p)<=w2)
- return true;
- if ( !(flags & prev) )
+ // Line *may* pass though the point...
+ UserPoint vec = p-p0;
+ double len = sqrt(vec.x*vec.x + vec.y*vec.y);
+ if (len>0)
{
- // Line *may* pass though the point...
- UserPoint vec = p-p0;
- double len = sqrt(vec.x*vec.x + vec.y*vec.y);
- if (len>0)
+ double a = vec.Dot(pos-p0)/len;
+ if (a>0 && a<1)
{
- double a = vec.Dot(pos-p0)/len;
- if (a>0 && a<1)
- {
- if ( (p0 + vec*a).Dist2(pos) < w2 )
- return true;
- }
+ if ( (p0 + vec*a).Dist2(pos) < w2 )
+ return true;
}
}
- prev = flags;
- p0 = p;
}
+ prev = flags;
+ p0 = p;
}
- else if (draw.mPrimType == ptTriangleFan)
+ }
+ else if (draw.mPrimType == ptTriangleFan)
+ {
+ if (draw.mCount<3)
+ continue;
+ UserPoint p0 = V(0);
+ int count_left = 0;
+ for(int i=1;i<=draw.mCount;i++)
{
- if (draw.mCount<3)
- continue;
- UserPoint *v = &vert[ draw.mFirst ];
- UserPoint p0 = *v;
- int count_left = 0;
- for(int i=1;i<=draw.mCount;i++)
+ UserPoint p = V(i%draw.mCount);
+ if ( (p.ybase.x;
- if ( bgx!=(pos.x>v[0].x) || bgx!=(pos.x>v[1].x) )
- {
- bool bgy = pos.y>base.y;
- if ( bgy!=(pos.y>v[0].y) || bgy!=(pos.y>v[1].y) )
- {
- UserPoint v0 = v[0] - base;
- UserPoint v1 = v[1] - base;
- UserPoint v2 = pos - base;
- double dot00 = v0.Dot(v0);
- double dot01 = v0.Dot(v1);
- double dot02 = v0.Dot(v2);
- double dot11 = v1.Dot(v1);
- double dot12 = v1.Dot(v2);
-
- // Compute barycentric coordinates
- double denom = (dot00 * dot11 - dot01 * dot01);
- if (denom!=0)
- {
- denom = 1 / denom;
- double u = (dot11 * dot02 - dot01 * dot12) * denom;
- if (u>=0)
- {
- double v = (dot00 * dot12 - dot01 * dot02) * denom;
-
- // Check if point is in triangle
- if ( (v >= 0) && (u + v < 1) )
- return true;
- }
- }
- }
- }
- v+=2;
- }
+ if (HitTri(V(i-2), V(i-2),V(i), pos ))
+ return true;
}
}
}
diff --git a/project/src/common/Tessellate.cpp b/project/src/common/Tessellate.cpp
index c18bdcf24..37bb71e6f 100644
--- a/project/src/common/Tessellate.cpp
+++ b/project/src/common/Tessellate.cpp
@@ -1,5 +1,6 @@
#include
#include
+#include
namespace lime
{
diff --git a/project/src/common/TextField.cpp b/project/src/common/TextField.cpp
index 433a32aad..f356d49b1 100644
--- a/project/src/common/TextField.cpp
+++ b/project/src/common/TextField.cpp
@@ -1430,6 +1430,8 @@ void TextField::Render( const RenderTarget &inTarget, const RenderState &inState
int line = 0;
int last_line = mLines.size()-1;
+ Surface *hardwareSurface = 0;
+ uint32 hardwareTint = 0;
for(int g=0;g=mSelectMin && cidBeginBitmapRender(tile.mSurface,tint);
+ if (hardwareSurface!=tile.mSurface || hardwareTint!=tint)
+ {
+ if (hardwareSurface)
+ hardware->EndBitmapRender();
+
+ hardwareSurface = tile.mSurface;
+ hardwareTint = tint;
+ hardware->BeginBitmapRender(tile.mSurface,tint);
+ }
hardware->RenderBitmap(tile.mRect, (int)p.x, (int)p.y);
}
else
@@ -1475,7 +1483,7 @@ void TextField::Render( const RenderTarget &inTarget, const RenderState &inState
}
- if (hardware)
+ if (hardwareSurface)
hardware->EndBitmapRender();
}
diff --git a/project/src/common/Tilesheet.cpp b/project/src/common/Tilesheet.cpp
index 3d811d458..02d476065 100644
--- a/project/src/common/Tilesheet.cpp
+++ b/project/src/common/Tilesheet.cpp
@@ -12,7 +12,7 @@ Tilesheet::Tilesheet(int inWidth,int inHeight,PixelFormat inFormat, bool inInitR
mCurrentY = 0;
mMaxHeight = 0;
mSheet = new SimpleSurface(inWidth,inHeight,inFormat);
-
+ mSheet->IncRef();
}
Tilesheet::Tilesheet(Surface *inSurface,bool inInitRef) : Object(inInitRef)
diff --git a/project/src/platform/ios/UIStageView.mm b/project/src/platform/ios/UIStageView.mm
index 95a31a219..f661435de 100644
--- a/project/src/platform/ios/UIStageView.mm
+++ b/project/src/platform/ios/UIStageView.mm
@@ -142,7 +142,6 @@ public:
int Width() const { return mWidth; }
int Height() const { return mHeight; }
PixelFormat Format() const { return pfXRGB; }
- AlphaMode GetAlphaMode() const { return amStraight; }
const uint8 *GetBase() const { return (const uint8 *)mBuffer; }
int GetStride() const { return mWidth*4; }
void Clear(uint32 inColour,const lime::Rect *inRect)
diff --git a/project/src/renderer/common/HardwareSurface.cpp b/project/src/renderer/common/HardwareSurface.cpp
index cdb9c5476..0d1aeb8da 100644
--- a/project/src/renderer/common/HardwareSurface.cpp
+++ b/project/src/renderer/common/HardwareSurface.cpp
@@ -6,7 +6,6 @@ namespace lime {
HardwareSurface::HardwareSurface (HardwareContext *inContext) {
- mAlphaMode = amUnknown;
mHardware = inContext;
mHardware->IncRef ();
@@ -24,7 +23,6 @@ namespace lime {
// This is not really a clone...
Surface *copy = new HardwareSurface (mHardware);
- copy->setAlphaMode (mAlphaMode);
copy->IncRef ();
return copy;
diff --git a/project/src/renderer/common/SimpleSurface.cpp b/project/src/renderer/common/SimpleSurface.cpp
index 58015172e..c8a94748a 100644
--- a/project/src/renderer/common/SimpleSurface.cpp
+++ b/project/src/renderer/common/SimpleSurface.cpp
@@ -12,7 +12,6 @@ namespace lime {
mTexture = 0;
mPixelFormat = inPixelFormat;
mGPUPixelFormat = inPixelFormat;
- mAlphaMode = amUnknown;
if (inGPUFormat == -1) {
@@ -653,8 +652,6 @@ namespace lime {
if (!mBase)
return;
- if (mAlphaMode == amIgnore || mAlphaMode == amPremultiplied)
- return;
Rect r = Rect (0, 0, mWidth, mHeight);
mVersion++;
if (mTexture)
@@ -686,8 +683,6 @@ namespace lime {
}
- mAlphaMode = amPremultiplied;
-
}
@@ -1011,8 +1006,6 @@ namespace lime {
if (!mBase)
return;
- if (mAlphaMode == amIgnore || mAlphaMode == amStraight)
- return;
Rect r = Rect (0, 0, mWidth, mHeight);
mVersion++;
if (mTexture)
@@ -1044,8 +1037,6 @@ namespace lime {
}
- mAlphaMode = amStraight;
-
}
diff --git a/project/src/renderer/opengl/OpenGL2Context.cpp b/project/src/renderer/opengl/OpenGL2Context.cpp
deleted file mode 100644
index ffa66c615..000000000
--- a/project/src/renderer/opengl/OpenGL2Context.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-#include "renderer/opengl/OpenGL2Context.h"
-
-
-namespace lime {
-
-
- OpenGL2Context::OpenGL2Context (WinDC inDC, GLCtx inOGLCtx) : OpenGLContext (inDC, inOGLCtx) {
-
- mIsRadial = false;
-
- for (int i = 0; i < gpuSIZE; i++)
- mProg[i] = 0;
-
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- mBitmapTrans[i][j] = mTrans[i][j] = (i == j);
- //mBitmapTrans[2][2] = 0.0;
-
- }
-
-
- OpenGL2Context::~OpenGL2Context () {
-
- for (int i = 0; i < gpuSIZE; i++)
- delete mProg[i];
-
- }
-
-
- void OpenGL2Context::CombineModelView (const Matrix &inModelView) {
-
- mTrans[0][0] = inModelView.m00 * mScaleX;
- mTrans[0][1] = inModelView.m01 * mScaleX;
- mTrans[0][2] = 0;
- mTrans[0][3] = inModelView.mtx * mScaleX + mOffsetX;
-
- mTrans[1][0] = inModelView.m10 * mScaleY;
- mTrans[1][1] = inModelView.m11 * mScaleY;
- mTrans[1][2] = 0;
- mTrans[1][3] = inModelView.mty * mScaleY + mOffsetY;
-
- }
-
-
- void OpenGL2Context::FinishBitmapRender () {
-
- // TODO: Need replacement call for GLES2
- //#ifndef LIME_FORCE_GLES2
- //glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- //#endif
-
- }
-
-
- void OpenGL2Context::FinishDrawing () {
-
- if (mCurrentProg)
- mCurrentProg->finishDrawing ();
-
- }
-
-
- void OpenGL2Context::OnBeginRender () {}
-
-
- void OpenGL2Context::PopBitmapMatrix () {}
-
-
- void OpenGL2Context::PrepareBitmapRender () {
-
- GPUProgID id = mBitmapSurface->BytesPP () == 1 ? gpuBitmapAlpha : gpuBitmap;
- if (!mProg[id])
- mProg[id] = GPUProg::create (id, mAlphaMode);
- mCurrentProg = mProg[id];
- if (!mCurrentProg)
- return;
-
- mCurrentProg->bind ();
- mCurrentProg->setTint (mTint);
- mBitmapSurface->Bind (*this, 0);
- mCurrentProg->setTransform (mBitmapTrans);
- // TODO: Need replacement call for GLES2
- //#ifndef LIME_FORCE_GLES2
- //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- //#endif
-
- }
-
-
- bool OpenGL2Context::PrepareDrawing () {
-
- GPUProgID id = gpuNone;
-
- if (mTexCoords) {
-
- if (mIsRadial) {
-
- if (mRadialFocus != 0) {
-
- id = gpuRadialFocusGradient;
-
- } else {
-
- id = gpuRadialGradient;
-
- }
-
- } else if (mColourTransform && !mColourTransform->IsIdentity ()) {
-
- id = gpuTextureTransform;
-
- } else if (mColourArray) {
-
- id = gpuTextureColourArray;
-
- } else {
-
- id = gpuTexture;
-
- }
-
- } else {
-
- if (mColourArray) {
-
- if (mColourTransform && !mColourTransform->IsIdentity ()) {
-
- id = gpuColourTransform;
-
- } else {
-
- id = gpuColour;
-
- }
-
- } else {
-
- id = gpuSolid;
-
- }
-
- }
-
- if (id == gpuNone)
- return false;
-
- if (!mProg[id])
- mProg[id] = GPUProg::create (id, mAlphaMode);
-
- if (!mProg[id])
- return false;
-
- GPUProg *prog = mProg[id];
- mCurrentProg = prog;
- prog->bind ();
-
- prog->setPositionData (mPosition, mPositionPerspective);
- prog->setTransform (mTrans);
-
- if (mTexCoords) {
-
- prog->setTexCoordData (mTexCoords);
- mTextureSurface->Bind (*this, 0);
-
- }
-
- if (mColourArray)
- prog->setColourData (mColourArray);
-
- if (mColourTransform)
- prog->setColourTransform (mColourTransform);
-
- if (id == gpuRadialFocusGradient)
- prog->setGradientFocus (mRadialFocus);
-
- return true;
-
- }
-
-
- void OpenGL2Context::PushBitmapMatrix () {}
-
-
- void OpenGL2Context::SetBitmapData (const float *inPos, const float *inTex) {
-
- mCurrentProg->setPositionData (inPos, false);
- mCurrentProg->setTexCoordData (inTex);
-
- }
-
-
- void OpenGL2Context::SetColourArray (const int *inData) {
-
- mColourArray = inData;
-
- }
-
-
- void OpenGL2Context::SetModulatingTransform (const ColorTransform *inTransform) {
-
- mColourTransform = inTransform;
-
- }
-
-
- void OpenGL2Context::setOrtho (float x0, float x1, float y0, float y1) {
-
- mScaleX = 2.0 / (x1 - x0);
- mScaleY = 2.0 / (y1 - y0);
- mOffsetX = (x0 + x1) / (x0 - x1);
- mOffsetY = (y0 + y1) / (y0 - y1);
- mModelView = Matrix ();
-
- mBitmapTrans[0][0] = mScaleX;
- mBitmapTrans[0][3] = mOffsetX;
- mBitmapTrans[1][1] = mScaleY;
- mBitmapTrans[1][3] = mOffsetY;
-
- CombineModelView (mModelView);
-
- }
-
-
- void OpenGL2Context::SetPositionData (const float *inData,bool inPerspective) {
-
- mPosition = inData;
- mPositionPerspective = inPerspective;
-
- }
-
-
- void OpenGL2Context::SetRadialGradient (bool inIsRadial, float inFocus) {
-
- mIsRadial = inIsRadial;
- mRadialFocus = inFocus;
-
- }
-
-
- void OpenGL2Context::SetSolidColour (unsigned int col) {
-
- if (mCurrentProg)
- mCurrentProg->setTint (col);
-
- }
-
-
- void OpenGL2Context::SetTexture (Surface *inSurface, const float *inTexCoords) {
-
- mTextureSurface = inSurface;
- mTexCoords = inTexCoords;
-
- }
-
-
-}
diff --git a/project/src/renderer/opengl/OpenGLContext.cpp b/project/src/renderer/opengl/OpenGLContext.cpp
index 9869968c0..94377c8af 100644
--- a/project/src/renderer/opengl/OpenGLContext.cpp
+++ b/project/src/renderer/opengl/OpenGLContext.cpp
@@ -2,7 +2,6 @@
int sgDrawCount = 0;
-int sgBufferCount = 0;
int sgDrawBitmap = 0;
@@ -17,22 +16,11 @@ namespace lime {
mWidth = 0;
mHeight = 0;
mLineWidth = -1;
- mPointsToo = true;
- mBitmapSurface = 0;
mBitmapTexture = 0;
- mUsingBitmapMatrix = false;
mLineScaleNormal = -1;
mLineScaleV = -1;
mLineScaleH = -1;
- mPointSmooth = true;
- mColourArrayEnabled = false;
mThreadId = GetThreadId ();
- mAlphaMode = amUnknown;
-
- const char *str = (const char *)glGetString (GL_VENDOR);
-
- if (str && !strncmp (str, "Intel", 5))
- mPointSmooth = false;
#if defined(LIME_GLES)
mQuality = sqLow;
@@ -40,31 +28,77 @@ namespace lime {
mQuality = sqBest;
#endif
+ for (int i = 0; i < PROG_COUNT; i++) {
+
+ mProg[i] = 0;
+
+ }
+
+ for (int i = 0; i < 4; i++) {
+
+ for (int j = 0; j < 4; j++) {
+
+ mBitmapTrans[i][j] = mTrans[i][j] = (i == j);
+
+ }
+
+ }
+
+ mBitmapBuffer.mElements.resize (1);
+ DrawElement &e = mBitmapBuffer.mElements[0];
+ memset (&e, 0, sizeof (DrawElement));
+ e.mCount = 0;
+ e.mFlags = DRAW_HAS_TEX;
+ e.mPrimType = ptTriangles;
+ e.mVertexOffset = 0;
+ e.mColour = 0xff000000;
+ e.mTexOffset = sizeof (float) * 2;
+ e.mStride = sizeof (float) * 4;
+
}
- OpenGLContext::~OpenGLContext () {}
+ OpenGLContext::~OpenGLContext () {
+
+ for (int i = 0; i < PROG_COUNT; i++) {
+
+ delete mProg[i];
+
+ }
+
+ }
void OpenGLContext::BeginBitmapRender (Surface *inSurface, uint32 inTint, bool inRepeat, bool inSmooth) {
- if (!mUsingBitmapMatrix) {
+ mBitmapBuffer.mArray.resize (0);
+ mBitmapBuffer.mRendersWithoutVbo = -999;
+ DrawElement &e = mBitmapBuffer.mElements[0];
+ e.mCount = 0;
+
+ e.mColour = inTint;
+ if (e.mSurface) {
- mUsingBitmapMatrix = true;
- PushBitmapMatrix ();
+ e.mSurface->DecRef ();
+ }
+
+ e.mSurface = inSurface;
+ e.mSurface->IncRef ();
+ e.mFlags = (e.mFlags & ~(DRAW_BMP_REPEAT|DRAW_BMP_SMOOTH));
+
+ if (inRepeat) {
+
+ e.mFlags |= DRAW_BMP_REPEAT;
}
- if (mBitmapSurface == inSurface && mTint == inTint)
- return;
+ if (inSmooth) {
+
+ e.mFlags |= DRAW_BMP_SMOOTH;
+
+ }
- mTint = inTint;
- mBitmapSurface = inSurface;
- inSurface->Bind (*this, 0);
mBitmapTexture = inSurface->GetOrCreateTexture (*this);
- mBitmapTexture->BindFlags (inRepeat, inSmooth);
-
- PrepareBitmapRender ();
}
@@ -88,39 +122,28 @@ namespace lime {
}
+ if (mZombieVbos.size ()) {
+
+ glDeleteTextures (mZombieVbos.size (), &mZombieVbos[0]);
+ mZombieVbos.resize (0);
+
+ }
+
// Force dirty
mViewport.w = -1;
SetViewport (inRect);
- //#ifndef LIME_FORCE_GLES2
glEnable (GL_BLEND);
- //#endif
-
- if (mAlphaMode == amPremultiplied)
- glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- else
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifdef WEBOS
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
#endif
- #ifndef LIME_FORCE_GLES2
- if (mQuality >= sqHigh && mPointSmooth)
- glEnable (GL_POINT_SMOOTH);
-
- if (mQuality >= sqBest)
- glEnable (GL_LINE_SMOOTH);
- #endif
-
mLineWidth = 99999;
// printf("DrawArrays: %d, DrawBitmaps:%d Buffers:%d\n", sgDrawCount, sgDrawBitmap, sgBufferCount );
sgDrawCount = 0;
sgDrawBitmap = 0;
- sgBufferCount = 0;
-
- OnBeginRender ();
}
@@ -130,38 +153,25 @@ namespace lime {
void OpenGLContext::Clear (uint32 inColour, const Rect *inRect) {
Rect r = inRect ? *inRect : Rect (mWidth, mHeight);
+
glViewport (r.x, mHeight - r.y1 (), r.w, r.h);
+ float alpha = ((inColour >> 24) & 0xFF) / 255.0;
+ float red = ((inColour >> 16) & 0xFF) / 255.0;
+ float green = ((inColour >> 8) & 0xFF) / 255.0;
+ float blue = (inColour & 0xFF) / 255.0;
+ red *= alpha;
+ green *= alpha;
+ blue *= alpha;
+
if (r == Rect (mWidth, mHeight)) {
- glClearColor ((GLclampf)(((inColour >> 16) & 0xff) / 255.0), (GLclampf)(((inColour >> 8) & 0xff) / 255.0), (GLclampf)(((inColour) & 0xff) / 255.0), (GLclampf)1.0);
+ glClearColor (red, green, blue, alpha );
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} else {
- #ifndef LIME_FORCE_GLES2
-
- // TODO: Clear with a rect
- // TODO: Need replacement call for GLES2
- glColor4f ((GLclampf)(((inColour >> 16) & 0xff) / 255.0), (GLclampf)(((inColour >> 8) & 0xff) / 255.0), (GLclampf)(((inColour) & 0xff) / 255.0), (GLclampf)1.0);
-
- glMatrixMode (GL_MODELVIEW);
- glPushMatrix ();
- glLoadIdentity ();
- glMatrixMode (GL_PROJECTION);
- glPushMatrix ();
- glLoadIdentity ();
-
- glDisable (GL_TEXTURE_2D);
- static GLfloat rect[4][2] = { { -2, -2 }, { 2, -2 }, { 2, 2 }, { -2, 2 } };
- glVertexPointer (2, GL_FLOAT, 0, rect[0]);
- glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
-
- glPopMatrix ();
- glMatrixMode (GL_MODELVIEW);
- glPopMatrix ();
-
- #endif
+ //printf(" - partial clear\n");
}
@@ -176,20 +186,15 @@ namespace lime {
void OpenGLContext::CombineModelView (const Matrix &inModelView) {
- #ifndef LIME_FORCE_GLES2
+ mTrans[0][0] = inModelView.m00 * mScaleX;
+ mTrans[0][1] = inModelView.m01 * mScaleX;
+ mTrans[0][2] = 0;
+ mTrans[0][3] = inModelView.mtx * mScaleX + mOffsetX;
- // Do not combine ModelView and Projection in fixed-function
- float matrix[] = {
-
- mModelView.m00, mModelView.m10, 0, 0,
- mModelView.m01, mModelView.m11, 0, 0,
- 0, 0, 1, 0,
- mModelView.mtx, mModelView.mty, 0, 1
-
- };
-
- glLoadMatrixf (matrix);
- #endif
+ mTrans[1][0] = inModelView.m10 * mScaleY;
+ mTrans[1][1] = inModelView.m11 * mScaleY;
+ mTrans[1][2] = 0;
+ mTrans[1][3] = inModelView.mty * mScaleY + mOffsetY;
}
@@ -217,35 +222,50 @@ namespace lime {
}
}
-
-
- void OpenGLContext::EndBitmapRender () {
+
+
+ void OpenGLContext::DestroyVbo (unsigned int inVbo) {
- if (mUsingBitmapMatrix) {
+ if (!IsMainThread ()) {
- mUsingBitmapMatrix = false;
- PopBitmapMatrix ();
+ mZombieVbos.push_back (inVbo);
+
+ } else {
+
+ glDeleteBuffers (1, &inVbo);
}
- mBitmapTexture = 0;
- mBitmapSurface = 0;
- FinishBitmapRender ();
-
}
- void OpenGLContext::EndRender () {}
-
-
- void OpenGLContext::FinishBitmapRender () {
+ void OpenGLContext::EndBitmapRender () {
+
+ DrawElement &e = mBitmapBuffer.mElements[0];
+
+ if (e.mCount) {
+
+ RenderData (mBitmapBuffer, 0, mBitmapTrans);
+ e.mCount = 0;
+
+ }
+
+ if (e.mSurface) {
+
+ e.mSurface->DecRef ();
+ e.mSurface = 0;
+
+ }
+
+ mBitmapBuffer.mArray.resize (0);
+ mBitmapTexture = 0;
+
+ }
+
+
+ void OpenGLContext::EndRender () {
+
- #ifndef LIME_FORCE_GLES2
- glDisable (GL_TEXTURE_2D);
- #ifdef LIME_DITHER
- glEnable (GL_DITHER);
- #endif
- #endif
}
@@ -263,77 +283,16 @@ namespace lime {
}
- void OpenGLContext::FinishDrawing () {
+ void OpenGLContext::Render (const RenderState &inState, const HardwareData &inData) {
- SetColourArray (0);
+ if (!inData.mArray.size ()) {
+
+ return;
+
+ }
- }
-
-
- void OpenGLContext::OnBeginRender () {
-
- #ifndef LIME_FORCE_GLES2
- glEnableClientState (GL_VERTEX_ARRAY);
- #endif
-
- }
-
-
- void OpenGLContext::PopBitmapMatrix () {
-
- #ifndef LIME_FORCE_GLES2
- glPopMatrix ();
- #endif
-
- }
-
-
- void OpenGLContext::PrepareBitmapRender () {
-
- #ifndef LIME_FORCE_GLES2
- float a = (float)((mTint >> 24) & 0xFF) * one_on_255;
- float c0 = (float)((mTint >> 16) & 0xFF) * one_on_255;
- float c1 = (float)((mTint >> 8) & 0xFF) * one_on_255;
- float c2 = (float)(mTint & 0xFF) * one_on_255;
- if (mAlphaMode == amPremultiplied)
- glColor4f (c0 * a, c1 * a, c2 * a, a);
- else
- glColor4f (c0, c1, c2, a);
- glEnable (GL_TEXTURE_2D);
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- #ifdef LIME_DITHER
- if (!inSmooth)
- glDisable (GL_DITHER);
- #endif
- #endif
-
- }
-
-
- bool OpenGLContext::PrepareDrawing () {
-
- return true;
-
- }
-
-
- void OpenGLContext::PushBitmapMatrix () {
-
- #ifndef LIME_FORCE_GLES2
- glPushMatrix ();
- glLoadIdentity ();
- #endif
-
- }
-
-
- void OpenGLContext::Render (const RenderState &inState, const HardwareCalls &inCalls) {
-
- //#ifndef LIME_FORCE_GLES2
- glEnable (GL_BLEND);
- //#endif
SetViewport (inState.mClipRect);
-
+
if (mModelView != *inState.mTransform.mMatrix) {
mModelView = *inState.mTransform.mMatrix;
@@ -344,416 +303,362 @@ namespace lime {
}
- uint32 last_col = 0;
+ const ColorTransform *ctrans = inState.mColourTransform;
- for (int c = 0; c < inCalls.size (); c++) {
+ if (ctrans && ctrans->IsIdentity ()) {
- HardwareArrays &arrays = *inCalls[c];
- DrawElements &elements = arrays.mElements;
- if (elements.empty ())
- continue;
-
- Vertices &vert = arrays.mVertices;
- Vertices &tex_coords = arrays.mTexCoords;
- bool persp = arrays.mFlags & HardwareArrays::PERSPECTIVE;
-
- if (arrays.mFlags & HardwareArrays::BM_ADD) {
-
- glBlendFunc (GL_SRC_ALPHA, GL_ONE);
-
- } else if (arrays.mFlags & HardwareArrays::BM_MULTIPLY) {
-
- glBlendFunc (GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
-
- } else if (arrays.mFlags & HardwareArrays::BM_SCREEN) {
-
- glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR);
-
- } else if (arrays.mFlags & HardwareArrays::AM_PREMULTIPLIED) {
-
- //printf("Premultiplied\n");
- mAlphaMode = amPremultiplied;
- glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
- } else {
-
- //printf("Straight\n");
- mAlphaMode = amStraight;
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- }
-
- #ifdef LIME_USE_VBO
- if (!arrays.mVertexBO) {
-
- glGenBuffers (1, &arrays.mVertexBO);
- glBindBuffer (GL_ARRAY_BUFFER, arrays.mVertexBO);
- glBufferData (GL_ARRAY_BUFFER, sizeof(float) * (persp ? 4 : 2) * vert.size (), &vert[0].x, GL_STATIC_DRAW);
-
- } else {
-
- glBindBuffer (GL_ARRAY_BUFFER, arrays.mVertexBO);
-
- }
-
- glVertexPointer (persp ? 4 : 2, GL_FLOAT, 0, 0);
- glBindBuffer (GL_ARRAY_BUFFER, 0);
- #else
- SetPositionData (&vert[0].x, persp);
- #endif
-
- Texture *boundTexture = 0;
- bool tex = arrays.mSurface && tex_coords.size ();
- if (tex) {
-
- boundTexture = arrays.mSurface->GetOrCreateTexture (*this);
- SetTexture (arrays.mSurface, &tex_coords[0].x);
- last_col = -1;
- SetModulatingTransform (inState.mColourTransform);
-
- if (arrays.mFlags & HardwareArrays::RADIAL) {
-
- float focus = ((arrays.mFlags & HardwareArrays::FOCAL_MASK) >> 8) / 256.0;
- if (arrays.mFlags & HardwareArrays::FOCAL_SIGN)
- focus = -focus;
- SetRadialGradient (true, focus);
-
- } else {
-
- SetRadialGradient (0, 0);
-
- }
-
- } else {
-
- boundTexture = 0;
- SetTexture (0, 0);
- SetModulatingTransform (0);
-
- }
-
- if (arrays.mColours.size () == vert.size ()) {
-
- SetColourArray (&arrays.mColours[0]);
- SetModulatingTransform (inState.mColourTransform);
-
- } else {
-
- SetColourArray (0);
-
- }
-
- int n = elements.size ();
- if (!PrepareDrawing ())
- n = 0;
-
- sgBufferCount++;
- for (int e = 0; e < n; e++) {
-
- DrawElement draw = elements[e];
-
- if (boundTexture) {
-
- boundTexture->BindFlags (draw.mBitmapRepeat, draw.mBitmapSmooth);
- #ifndef LIME_FORCE_GLES2
- #ifdef LIME_DITHER
- if (!inSmooth)
- glDisable (GL_DITHER);
- #endif
- #endif
-
- } else {
-
- int col = inState.mColourTransform->Transform (draw.mColour);
- if (c == 0 || last_col != col) {
-
- last_col = col;
- SetSolidColour (col);
-
- }
-
- }
-
- if ((draw.mPrimType == ptLineStrip || draw.mPrimType == ptPoints || draw.mPrimType == ptLines) && draw.mCount > 1) {
-
- if (draw.mWidth < 0) {
-
- SetLineWidth (1.0);
-
- } else if (draw.mWidth == 0) {
-
- SetLineWidth (0.0);
-
- } else {
-
- switch (draw.mScaleMode) {
-
- case ssmNone:
- SetLineWidth (draw.mWidth);
- break;
-
- case ssmNormal:
- case ssmOpenGL:
- if (mLineScaleNormal < 0)
- mLineScaleNormal = sqrt (0.5 * ((mModelView.m00 * mModelView.m00) + (mModelView.m01 * mModelView.m01) + (mModelView.m10 * mModelView.m10) + (mModelView.m11 * mModelView.m11)));
- SetLineWidth (draw.mWidth * mLineScaleNormal);
- break;
-
- case ssmVertical:
- if (mLineScaleV < 0)
- mLineScaleV = sqrt ((mModelView.m00 * mModelView.m00) + (mModelView.m01 * mModelView.m01));
- SetLineWidth (draw.mWidth * mLineScaleV);
- break;
-
- case ssmHorizontal:
- if (mLineScaleH <0)
- mLineScaleH = sqrt ((mModelView.m10 * mModelView.m10) + (mModelView.m11 * mModelView.m11));
- SetLineWidth (draw.mWidth * mLineScaleH);
- break;
-
- }
-
- }
-
- if (mPointsToo && mLineWidth > 1.5 && draw.mPrimType != ptLines)
- glDrawArrays (GL_POINTS, draw.mFirst, draw.mCount);
-
- }
-
- //printf("glDrawArrays %d : %d x %d\n", draw.mPrimType, draw.mFirst, draw.mCount );
-
- sgDrawCount++;
- glDrawArrays (sgOpenglType[draw.mPrimType], draw.mFirst, draw.mCount);
-
- //#ifndef LIME_FORCE_GLES2
- #ifdef LIME_DITHER
- if (boundTexture && !draw.mBitmapSmooth)
- glEnable (GL_DITHER);
- #endif
- //#endif
-
- }
-
- FinishDrawing ();
+ ctrans = 0;
}
+ RenderData (inData, ctrans, mTrans);
+
}
void OpenGLContext::RenderBitmap (const Rect &inSrc, int inX, int inY) {
- UserPoint vertex[4];
+ DrawElement &e = mBitmapBuffer.mElements[0];
+ mBitmapBuffer.mArray.resize ((e.mCount + 6) * e.mStride);
+ UserPoint *p = (UserPoint *)&mBitmapBuffer.mArray[e.mCount * e.mStride];
+ e.mCount += 6;
+
+ UserPoint corners[4];
UserPoint tex[4];
for (int i = 0; i < 4; i++) {
- UserPoint t (inSrc.x + ((i & 1) ? inSrc.w : 0), inSrc.y + ((i > 1) ? inSrc.h : 0));
- tex[i] = mBitmapTexture->PixelToTex (t);
- vertex[i] = UserPoint (inX + ((i & 1) ? inSrc.w : 0), inY + ((i > 1) ? inSrc.h : 0));
+ corners[i] = UserPoint (inX + ((i & 1) ? inSrc.w : 0), inY + ((i > 1) ? inSrc.h : 0));
+ tex[i] = mBitmapTexture->PixelToTex (UserPoint (inSrc.x + ((i & 1) ? inSrc.w : 0), inSrc.y + ((i > 1) ? inSrc.h : 0)));
}
- SetBitmapData (&vertex[0].x, &tex[0].x);
+ *p++ = corners[0];
+ *p++ = tex[0];
+ *p++ = corners[1];
+ *p++ = tex[1];
+ *p++ = corners[2];
+ *p++ = tex[2];
- glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
- sgDrawBitmap++;
+ *p++ = corners[1];
+ *p++ = tex[1];
+ *p++ = corners[2];
+ *p++ = tex[2];
+ *p++ = corners[3];
+ *p++ = tex[3];
}
- void OpenGLContext::SetBitmapData (const float *inPos, const float *inTex) {
+ void OpenGLContext::RenderData (const HardwareData &inData, const ColorTransform *ctrans, const Trans4x4 &inTrans) {
- #ifndef LIME_FORCE_GLES2
- glVertexPointer (2, GL_FLOAT, 0, inPos);
- glTexCoordPointer (2, GL_FLOAT, 0, inTex);
- #endif
+ const uint8 *data = 0;
- }
-
-
- void OpenGLContext::SetColourArray (const int *inData) {
-
- #ifndef LIME_FORCE_GLES2
- if (inData) {
+ if (inData.mVertexBo) {
- mColourArrayEnabled = true;
- glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (4, GL_UNSIGNED_BYTE, 0, inData);
+ glBindBuffer (GL_ARRAY_BUFFER, inData.mVertexBo);
- } else if (mColourArrayEnabled) {
+ } else {
- mColourArrayEnabled = false;
- glDisableClientState (GL_COLOR_ARRAY);
+ data = &inData.mArray[0];
+ inData.mRendersWithoutVbo++;
+
+ if (inData.mRendersWithoutVbo > 4) {
+
+ glGenBuffers (1, &inData.mVertexBo);
+ inData.mVboOwner = this;
+ IncRef ();
+ glBindBuffer (GL_ARRAY_BUFFER, inData.mVertexBo);
+ // printf ("VBO DATA %d\n", inData.mArray.size ());
+ glBufferData (GL_ARRAY_BUFFER, inData.mArray.size (), data, GL_STATIC_DRAW);
+ data = 0;
+
+ }
}
- #endif
- }
-
-
- void OpenGLContext::SetLineWidth (double inWidth) {
-
- if (inWidth != mLineWidth) {
+ GPUProg *lastProg = 0;
+
+ for (int e = 0; e < inData.mElements.size (); e++) {
- double w = inWidth;
- #ifndef LIME_FORCE_GLES2
- if (mQuality >= sqBest) {
+ const DrawElement &element = inData.mElements[e];
+ int n = element.mCount;
+
+ if (!n) {
- if (w > 1) {
+ continue;
+
+ }
+
+ switch (element.mBlendMode) {
+
+ case bmAdd:
- glDisable (GL_LINE_SMOOTH);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE);
+ break;
+
+ case bmMultiply:
+
+ glBlendFunc (GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
+ break;
+
+ case bmScreen:
+
+ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR);
+ break;
+
+ default:
+
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ break;
+
+ }
+
+ int progId = 0;
+
+ if ((element.mFlags & DRAW_HAS_TEX) && element.mSurface) {
+
+ progId |= PROG_TEXTURE;
+ if (element.mSurface->BytesPP () == 1) {
+
+ progId |= PROG_ALPHA_TEXTURE;
+
+ }
+
+ }
+
+ if (element.mFlags & DRAW_HAS_COLOUR) {
+
+ progId |= PROG_COLOUR_PER_VERTEX;
+
+ }
+
+ if (element.mFlags & DRAW_HAS_NORMAL) {
+
+ progId |= PROG_NORMAL_DATA;
+
+ }
+
+ if (element.mFlags & DRAW_RADIAL) {
+
+ progId |= PROG_RADIAL;
+ if (element.mRadialPos != 0) {
+
+ progId |= PROG_RADIAL_FOCUS;
+
+ }
+
+ }
+
+ if (ctrans || element.mColour != 0xFFFFFFFF) {
+
+ progId |= PROG_TINT;
+ if (ctrans && ctrans->HasOffset ())
+ progId |= PROG_COLOUR_OFFSET;
+
+ }
+
+ bool persp = element.mFlags & DRAW_HAS_PERSPECTIVE;
+ GPUProg *prog = mProg[progId];
+
+ if (!prog) {
+
+ mProg[progId] = prog = GPUProg::create (progId);
+
+ }
+
+ if (!prog) {
+
+ continue;
+
+ }
+
+ if (prog != lastProg) {
+
+ if (lastProg) {
+
+ lastProg->disableSlots ();
+
+ }
+
+ prog->bind ();
+ prog->setTransform (inTrans);
+ lastProg = prog;
+
+ }
+
+ int stride = element.mStride;
+ if (prog->vertexSlot >= 0) {
+
+ glVertexAttribPointer (prog->vertexSlot, persp ? 4 : 2 , GL_FLOAT, GL_FALSE, stride, data + element.mVertexOffset);
+ glEnableVertexAttribArray (prog->vertexSlot);
+
+ }
+
+ if (prog->textureSlot >= 0) {
+
+ glVertexAttribPointer (prog->textureSlot, 2 , GL_FLOAT, GL_FALSE, stride, data + element.mTexOffset);
+ glEnableVertexAttribArray (prog->textureSlot);
+
+ if (element.mSurface) {
+
+ Texture *boundTexture = element.mSurface->GetOrCreateTexture (*this);
+ element.mSurface->Bind (*this, 0);
+ boundTexture->BindFlags (element.mFlags & DRAW_BMP_REPEAT, element.mFlags & DRAW_BMP_SMOOTH);
+
+ }
+
+ }
+
+ if (prog->colourSlot >= 0) {
+
+ glVertexAttribPointer (prog->colourSlot, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, data + element.mColourOffset);
+ glEnableVertexAttribArray (prog->colourSlot);
+
+ }
+
+ if (prog->normalSlot >= 0) {
+
+ glVertexAttribPointer (prog->normalSlot, 2, GL_FLOAT, GL_FALSE, stride, data + element.mNormalOffset);
+ glEnableVertexAttribArray (prog->normalSlot);
+
+ }
+
+ if (element.mFlags & DRAW_RADIAL) {
+
+ prog->setGradientFocus (element.mRadialPos * one_on_256);
+
+ }
+
+ if (progId & (PROG_TINT | PROG_COLOUR_OFFSET)) {
+
+ prog->setColourTransform (ctrans, element.mColour);
+
+ }
+
+ if ((element.mPrimType == ptLineStrip || element.mPrimType == ptPoints || element.mPrimType == ptLines) && element.mCount > 1) {
+
+ if (element.mWidth < 0) {
+
+ SetLineWidth (1.0);
+
+ } else if (element.mWidth == 0) {
+
+ SetLineWidth (0.0);
} else {
- w = 1;
- if (inWidth == 0) {
+ switch (element.mScaleMode) {
- glDisable (GL_LINE_SMOOTH);
+ case ssmNone: SetLineWidth (element.mWidth); break;
+
+ case ssmNormal:
+ case ssmOpenGL:
+
+ if (mLineScaleNormal < 0) {
+
+ mLineScaleNormal = sqrt (0.5 * ((mModelView.m00 * mModelView.m00) + (mModelView.m01 * mModelView.m01) + (mModelView.m10 * mModelView.m10) + (mModelView.m11 * mModelView.m11)));
+
+ }
+
+ SetLineWidth (element.mWidth * mLineScaleNormal);
+ break;
- } else {
+ case ssmVertical:
+
+ if (mLineScaleV < 0) {
+
+ mLineScaleV = sqrt ((mModelView.m00 * mModelView.m00) + (mModelView.m01 * mModelView.m01));
+
+ }
+
+ SetLineWidth (element.mWidth * mLineScaleV);
+ break;
- glEnable (GL_LINE_SMOOTH);
+ case ssmHorizontal:
+
+ if (mLineScaleH<0) {
+
+ mLineScaleH = sqrt ((mModelView.m10 * mModelView.m10) + (mModelView.m11 * mModelView.m11));
+
+ }
+
+ SetLineWidth (element.mWidth * mLineScaleH);
+ break;
}
}
}
- #endif
+
+ //printf("glDrawArrays %d : %d x %d\n", element.mPrimType, element.mFirst, element.mCount );
+ sgDrawCount++;
+ glDrawArrays (sgOpenglType[element.mPrimType], 0, element.mCount);
+
+ }
+
+ if (lastProg) {
+
+ lastProg->disableSlots ();
+
+ }
+
+ if (inData.mVertexBo) {
+
+ glBindBuffer (GL_ARRAY_BUFFER, 0);
+
+ }
+
+ }
+
+
+ inline void OpenGLContext::SetLineWidth (double inWidth) {
+
+ if (inWidth != mLineWidth) {
+
+ // TODO mQuality -> tessellate_lines/tessellate_lines_aa
mLineWidth = inWidth;
- glLineWidth (w);
-
- // TODO: Need replacement call for GLES2?
- #ifndef LIME_FORCE_GLES2
- if (mPointsToo)
- glPointSize (inWidth);
- #endif
+ glLineWidth (inWidth);
}
}
- void OpenGLContext::SetModulatingTransform (const ColorTransform *inTransform) {
-
- #ifndef LIME_FORCE_GLES2
- if (inTransform) {
- if (mAlphaMode == amPremultiplied)
- glColor4f (inTransform->redMultiplier * inTransform->alphaMultiplier, inTransform->greenMultiplier * inTransform->alphaMultiplier, inTransform->blueMultiplier * inTransform->alphaMultiplier, inTransform->alphaMultiplier);
- else
- glColor4f (inTransform->redMultiplier, inTransform->greenMultiplier, inTransform->blueMultiplier, inTransform->alphaMultiplier);
- }
- #endif
-
- }
-
-
- void OpenGLContext::setOrtho (float x0,float x1, float y0, float y1) {
-
- #ifndef LIME_FORCE_GLES2
-
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
-
- #if defined (LIME_GLES)
- glOrthof (x0, x1, y0, y1, -1, 1);
- #else
- glOrtho (x0, x1, y0, y1, -1, 1);
- #endif
-
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
-
- #endif
+ void OpenGLContext::setOrtho (float x0, float x1, float y0, float y1) {
+ mScaleX = 2.0 / (x1 - x0);
+ mScaleY = 2.0 / (y1 - y0);
+ mOffsetX = (x0 + x1) / (x0 - x1);
+ mOffsetY = (y0 + y1) / (y0 - y1);
mModelView = Matrix ();
- }
-
-
- void OpenGLContext::SetPositionData (const float *inData, bool inPerspective) {
+ mBitmapTrans[0][0] = mScaleX;
+ mBitmapTrans[0][3] = mOffsetX;
+ mBitmapTrans[1][1] = mScaleY;
+ mBitmapTrans[1][3] = mOffsetY;
- #ifndef LIME_FORCE_GLES2
- glVertexPointer (inPerspective ? 4 : 2, GL_FLOAT, 0, inData);
- #endif
+ CombineModelView (mModelView);
- }
+ }
void OpenGLContext::SetQuality (StageQuality inQ) {
- #ifndef LIME_FORCE_GLES2
- //inQ = sqMedium;
if (inQ != mQuality) {
mQuality = inQ;
- if (mQuality >= sqHigh) {
-
- if (mPointSmooth)
- glEnable (GL_POINT_SMOOTH);
-
- } else {
-
- glDisable (GL_POINT_SMOOTH);
-
- }
-
- if (mQuality >= sqBest)
- glEnable (GL_LINE_SMOOTH);
- else
- glDisable (GL_LINE_SMOOTH);
mLineWidth = 99999;
}
- #endif
-
- }
-
-
- void OpenGLContext::SetRadialGradient (bool inIsRadial, float inFocus) {};
-
-
- void OpenGLContext::SetSolidColour (unsigned int col) {
-
- #ifndef LIME_FORCE_GLES2
- float a = (float)((col >> 24) & 0xFF) * one_on_255;
- float c0 = (float)((col >> 16) & 0xFF) * one_on_255;
- float c1 = (float)((col >> 8) & 0xFF) * one_on_255;
- float c2 = (float)(col & 0xFF) * one_on_255;
- if (mAlphaMode == amPremultiplied)
- glColor4f (c0 * a, c1 * a,c2 * a, a);
- else
- glColor4f (c0, c1, c2, a);
- #endif
-
- }
-
-
- void OpenGLContext::SetTexture (Surface *inSurface, const float *inTexCoords) {
-
- #ifndef LIME_FORCE_GLES2
- if (!inSurface) {
-
- glDisable (GL_TEXTURE_2D);
- glDisableClientState (GL_TEXTURE_COORD_ARRAY);
-
- } else {
-
- glEnable (GL_TEXTURE_2D);
- inSurface->Bind (*this, 0);
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (2, GL_FLOAT, 0, inTexCoords);
-
- }
- #endif
}
void OpenGLContext::SetViewport (const Rect &inRect) {
-
+
if (inRect != mViewport) {
setOrtho (inRect.x, inRect.x1 (), inRect.y1 (), inRect.y);
@@ -763,18 +668,17 @@ namespace lime {
}
}
-
-
+
+
void OpenGLContext::SetWindowSize (int inWidth, int inHeight) {
mWidth = inWidth;
mHeight = inHeight;
-
#ifdef ANDROID
- //__android_log_print(ANDROID_LOG_ERROR, "lime", "SetWindowSize %d %d", inWidth, inHeight);
+ //__android_log_print(ANDROID_LOG_ERROR, "Lime", "SetWindowSize %d %d", inWidth, inHeight);
#endif
}
-
+
}
diff --git a/project/src/renderer/opengl/OpenGLInit.cpp b/project/src/renderer/opengl/OpenGLInit.cpp
index 299427247..a5aa1cc50 100644
--- a/project/src/renderer/opengl/OpenGLInit.cpp
+++ b/project/src/renderer/opengl/OpenGLInit.cpp
@@ -7,7 +7,6 @@
#endif
#include "renderer/opengl/OpenGLContext.h"
-#include "renderer/opengl/OpenGL2Context.h"
#include "renderer/opengl/OpenGLTexture.h"
#ifdef TIZEN
@@ -126,15 +125,15 @@ namespace lime {
#endif
#endif
- if (shaders && HasShaderSupport ()) {
+ //if (shaders && HasShaderSupport ()) {
//#ifdef TIZEN
//AppLog ("Using OGL2\n");
//#endif
//printf("Using OGL2\n");
- ctx = new OpenGL2Context ((WinDC)inWindow, (GLCtx)inGLCtx);
+ //ctx = new OpenGL2Context ((WinDC)inWindow, (GLCtx)inGLCtx);
- } else {
+ //} else {
//#ifdef TIZEN
//AppLog ("Using OGL2\n");
@@ -142,7 +141,11 @@ namespace lime {
//printf("Using OGL1\n");
ctx = new OpenGLContext ((WinDC)inWindow, (GLCtx)inGLCtx);
- }
+ //} else {
+
+ // return 0;
+
+ //}
InitExtensions ();
return ctx;
diff --git a/project/src/renderer/opengl/OpenGLProgram.cpp b/project/src/renderer/opengl/OpenGLProgram.cpp
index f25908eef..137828482 100644
--- a/project/src/renderer/opengl/OpenGLProgram.cpp
+++ b/project/src/renderer/opengl/OpenGLProgram.cpp
@@ -1,5 +1,4 @@
#include "renderer/opengl/OGL.h"
-#ifdef ALLOW_OGL2
#include "renderer/opengl/OpenGLProgram.h"
@@ -11,16 +10,24 @@ namespace lime {
const float one_on_255 = 1.0 / 255.0;
- OpenGLProgram::OpenGLProgram (const char *inVertProg, const char *inFragProg, AlphaMode inAlphaMode) {
+ OpenGLProgram::OpenGLProgram (const std::string &inVertProg, const std::string &inFragProg) {
mVertProg = inVertProg;
mFragProg = inFragProg;
- mAlphaMode = inAlphaMode;
mVertId = 0;
mFragId = 0;
- mTexCoordSlot = -1;
- mTextureSlot = -1;
+
+ mImageSlot = -1;
mColourTransform = 0;
+
+ vertexSlot = -1;
+ textureSlot = -1;
+ normalSlot = -1;
+ colourSlot = -1;
+
+ //printf("%s", inVertProg.c_str());
+ //printf("%s", inFragProg.c_str());
+
recreate ();
}
@@ -48,16 +55,6 @@ namespace lime {
const char *source = inShader;
GLuint shader = glCreateShader (inType);
- #ifdef LIME_GLES
- std::string sourceBuf;
- if (inType == GL_FRAGMENT_SHADER) {
-
- sourceBuf = std::string ("precision mediump float;\n") + inShader;
- source = sourceBuf.c_str ();
-
- }
- #endif
-
glShaderSource (shader, 1, &source, 0);
glCompileShader (shader);
@@ -91,23 +88,38 @@ namespace lime {
}
- void OpenGLProgram::finishDrawing () {
+ void OpenGLProgram::disableSlots () {
- if (mColourArraySlot >= 0)
- glDisableVertexAttribArray (mColourArraySlot);
+ if (vertexSlot >= 0) {
+
+ glDisableVertexAttribArray (vertexSlot);
+
+ }
- if (mTexCoordSlot >= 0)
- glDisableVertexAttribArray (mTexCoordSlot);
+ if (normalSlot >= 0) {
+
+ glDisableVertexAttribArray (normalSlot);
+
+ }
- if (mVertexSlot >= 0)
- glDisableVertexAttribArray (mVertexSlot);
+ if (colourSlot >= 0) {
+
+ glDisableVertexAttribArray (colourSlot);
+
+ }
+
+ if (textureSlot >= 0) {
+
+ glDisableVertexAttribArray (textureSlot);
+
+ }
}
int OpenGLProgram::getTextureSlot () {
- return mTextureSlot;
+ return mImageSlot;
}
@@ -117,10 +129,10 @@ namespace lime {
mContextVersion = gTextureContextVersion;
mProgramId = 0;
- mVertId = createShader (GL_VERTEX_SHADER, mVertProg);
+ mVertId = createShader (GL_VERTEX_SHADER, mVertProg.c_str ());
if (!mVertId)
return;
- mFragId = createShader (GL_FRAGMENT_SHADER, mFragProg);
+ mFragId = createShader (GL_FRAGMENT_SHADER, mFragProg.c_str ());
if (!mFragId)
return;
@@ -154,8 +166,8 @@ namespace lime {
char *log = new char[logLen];
glGetProgramInfoLog (mProgramId, logLen, &logLen, log);
ELOG ("----");
- ELOG ("VERT: %s", mVertProg);
- ELOG ("FRAG: %s", mFragProg);
+ ELOG ("VERT: %s", mVertProg.c_str ());
+ ELOG ("FRAG: %s", mFragProg.c_str ());
ELOG ("ERROR:\n%s\n", log);
delete [] log;
@@ -168,57 +180,58 @@ namespace lime {
}
- mVertexSlot = glGetAttribLocation (mProgramId, "aVertex");
- mTexCoordSlot = glGetAttribLocation (mProgramId, "aTexCoord");
+ vertexSlot = glGetAttribLocation(mProgramId, "aVertex");
+ textureSlot = glGetAttribLocation(mProgramId, "aTexCoord");
+ colourSlot = glGetAttribLocation(mProgramId, "aColourArray");
+ normalSlot = glGetAttribLocation(mProgramId, "aNormal");
+
mTransformSlot = glGetUniformLocation (mProgramId, "uTransform");
- mTintSlot = glGetUniformLocation (mProgramId, "uTint");
- mColourArraySlot = glGetAttribLocation (mProgramId, "aColourArray");
- mTextureSlot = glGetUniformLocation (mProgramId, "uImage0");
+ mImageSlot = glGetUniformLocation(mProgramId, "uImage0");
mColourOffsetSlot = glGetUniformLocation (mProgramId, "uColourOffset");
mColourScaleSlot = glGetUniformLocation (mProgramId, "uColourScale");
mFXSlot = glGetUniformLocation (mProgramId, "mFX");
mASlot = glGetUniformLocation (mProgramId, "mA");
mOn2ASlot = glGetUniformLocation (mProgramId, "mOn2A");
+ glUseProgram (mProgramId);
+
+ if (mImageSlot >= 0) {
+
+ glUniform1i (mImageSlot, 0);
+
+ }
+
}
- void OpenGLProgram::setColourData (const int *inData) {
+ void OpenGLProgram::setColourTransform (const ColorTransform *inTransform, uint32 inColor) {
- if (inData && mColourArraySlot >= 0) {
+ float rf, gf, bf, af;
+
+ if (inColor == 0xFFFFFFFF) {
- glVertexAttribPointer (mColourArraySlot, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, inData);
- glEnableVertexAttribArray (mColourArraySlot);
+ rf = gf = bf = af = 1.0;
- } else if (mColourArraySlot >= 0) {
+ } else {
- glDisableVertexAttribArray (mColourArraySlot);
+ rf = ((inColor >> 16) & 0xFF) * one_on_255;
+ gf = ((inColor >> 8) & 0xFF) * one_on_255;
+ bf = (inColor & 0xFF) * one_on_255;
+ af = ((inColor >> 24) & 0xFF) * one_on_255;
}
- }
-
-
- void OpenGLProgram::setColourTransform (const ColorTransform *inTransform) {
-
- mColourTransform = inTransform;
if (inTransform && !inTransform->IsIdentity ()) {
if (mColourOffsetSlot >= 0) {
- if (mAlphaMode == amPremultiplied)
- glUniform4f (mColourOffsetSlot, inTransform->redOffset * one_on_255 * inTransform->alphaMultiplier, inTransform->greenOffset * one_on_255 * inTransform->alphaMultiplier, inTransform->blueOffset * one_on_255 * inTransform->alphaMultiplier, inTransform->alphaOffset * one_on_255);
- else
- glUniform4f (mColourOffsetSlot, inTransform->redOffset * one_on_255, inTransform->greenOffset * one_on_255, inTransform->blueOffset * one_on_255, inTransform->alphaOffset * one_on_255);
+ glUniform4f (mColourOffsetSlot, inTransform->redOffset * one_on_255, inTransform->greenOffset * one_on_255, inTransform->blueOffset * one_on_255, inTransform->alphaOffset * one_on_255);
}
if (mColourScaleSlot >= 0) {
- if (mAlphaMode == amPremultiplied)
- glUniform4f (mColourScaleSlot, inTransform->redMultiplier * inTransform->alphaMultiplier, inTransform->greenMultiplier * inTransform->alphaMultiplier, inTransform->blueMultiplier * inTransform->alphaMultiplier, inTransform->alphaMultiplier);
- else
- glUniform4f (mColourScaleSlot, inTransform->redMultiplier, inTransform->greenMultiplier, inTransform->blueMultiplier, inTransform->alphaMultiplier);
+ glUniform4f (mColourScaleSlot, inTransform->redMultiplier * rf, inTransform->greenMultiplier * gf, inTransform->blueMultiplier * bf, inTransform->alphaMultiplier * af);
}
@@ -227,7 +240,7 @@ namespace lime {
if (mColourOffsetSlot >= 0)
glUniform4f (mColourOffsetSlot, 0, 0, 0, 0);
if (mColourScaleSlot >= 0)
- glUniform4f (mColourScaleSlot, 1, 1, 1, 1);
+ glUniform4f (mColourScaleSlot, rf, gf, bf, af);
}
@@ -257,45 +270,6 @@ namespace lime {
}
- void OpenGLProgram::setPositionData (const float *inData, bool inIsPerspective) {
-
- glVertexAttribPointer (mVertexSlot, inIsPerspective ? 4 : 2, GL_FLOAT, GL_FALSE, 0, inData);
- glEnableVertexAttribArray (mVertexSlot);
-
- }
-
-
- void OpenGLProgram::setTexCoordData (const float *inData) {
-
- if (inData) {
-
- glVertexAttribPointer (mTexCoordSlot, 2, GL_FLOAT, GL_FALSE, 0, inData);
- glEnableVertexAttribArray (mTexCoordSlot);
- glUniform1i (mTextureSlot, 0);
-
- }
-
- }
-
-
- void OpenGLProgram::setTint (unsigned int inColour) {
-
- if (mTintSlot >= 0) {
-
- float a = ((inColour >> 24) & 0xff) * one_on_255;
- float c0 = ((inColour >> 16) & 0xff) * one_on_255;
- float c1 = ((inColour >> 8) & 0xff) * one_on_255;
- float c2 = (inColour & 0xff) * one_on_255;
- if (mAlphaMode == amPremultiplied)
- glUniform4f (mTintSlot, c0 * a, c1 * a, c2 * a, a);
- else
- glUniform4f (mTintSlot, c0, c1, c2, a);
-
- }
-
- }
-
-
void OpenGLProgram::setTransform (const Trans4x4 &inTrans) {
glUniformMatrix4fv (mTransformSlot, 1, 0, inTrans[0]);
@@ -304,6 +278,3 @@ namespace lime {
}
-
-
-#endif
diff --git a/project/src/renderer/opengl/OpenGLShaders.cpp b/project/src/renderer/opengl/OpenGLShaders.cpp
index b6146a85d..3ce6a6faa 100644
--- a/project/src/renderer/opengl/OpenGLShaders.cpp
+++ b/project/src/renderer/opengl/OpenGLShaders.cpp
@@ -5,232 +5,179 @@
namespace lime {
- const char *gSolidVert =
- "uniform mat4 uTransform;\n"
- "attribute vec4 aVertex;\n"
- "void main(void)\n"
- "{\n"
- " gl_Position = aVertex * uTransform;\n"
- "}";
-
-
- const char *gColourVert =
- "uniform mat4 uTransform;\n"
- "attribute vec4 aVertex;\n"
- "attribute vec4 aColourArray;\n"
- "varying vec4 vColourArray;\n"
- "void main(void)\n"
- "{\n"
- " vColourArray = aColourArray;\n"
- " gl_Position = aVertex * uTransform;\n"
- "}";
-
-
- const char *gTextureVert =
- "uniform mat4 uTransform;\n"
- "attribute vec4 aVertex;\n"
- "attribute vec2 aTexCoord;\n"
- "varying vec2 vTexCoord;\n"
- "void main(void)\n"
- "{\n"
- " vTexCoord = aTexCoord;\n"
- " gl_Position = aVertex * uTransform;\n"
- "}";
-
-
- const char *gTextureColourVert =
- "uniform mat4 uTransform;\n"
- "attribute vec4 aColourArray;\n"
- "attribute vec4 aVertex;\n"
- "attribute vec2 aTexCoord;\n"
- "varying vec2 vTexCoord;\n"
- "varying vec4 vColourArray;\n"
- "void main(void)\n"
- "{\n"
- " vColourArray = aColourArray;\n"
- " vTexCoord = aTexCoord;\n"
- " gl_Position = aVertex * uTransform;\n"
- "}";
-
-
- const char *gSolidFrag =
- "uniform vec4 uTint;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = uTint;\n"
- "}\n";
-
-
- const char *gColourFrag =
- "varying vec4 vColourArray;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = vColourArray;\n"
- "}\n";
-
-
- const char *gColourTransFrag =
- "varying vec4 vColourArray;\n"
- "uniform vec4 uColourScale;\n"
- "uniform vec4 uColourOffset;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = vColourArray*uColourScale+uColourOffset;\n"
- "}\n";
-
-
- const char *gBitmapAlphaFrag =
- "varying vec2 vTexCoord;\n"
- "uniform sampler2D uImage0;\n"
- "uniform vec4 uTint;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor.rgb = uTint.rgb;\n"
- " gl_FragColor.a = texture2D(uImage0,vTexCoord).a*uTint.a;\n"
- "}\n";
-
-
- const char *gBitmapAlphaPremultFrag =
- "varying vec2 vTexCoord;\n"
- "uniform sampler2D uImage0;\n"
- "uniform vec4 uTint;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor.rgb = uTint.rgb*texture2D(uImage0,vTexCoord).a;\n"
- " gl_FragColor.a = texture2D(uImage0,vTexCoord).a*uTint.a;\n"
- "}\n";
-
-
- const char *gBitmapFrag =
- "varying vec2 vTexCoord;\n"
- "uniform sampler2D uImage0;\n"
- "uniform vec4 uTint;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = texture2D(uImage0,vTexCoord)*uTint;\n"
- "}\n";
-
-
- const char *gTextureFrag =
- "varying vec2 vTexCoord;\n"
- "uniform sampler2D uImage0;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = texture2D(uImage0,vTexCoord);\n"
- "}\n";
-
-
- const char *gRadialTextureFrag =
- "varying vec2 vTexCoord;\n"
- "uniform sampler2D uImage0;\n"
- "void main(void)\n"
- "{\n"
- " float rad = sqrt(vTexCoord.x*vTexCoord.x + vTexCoord.y*vTexCoord.y);\n"
- " gl_FragColor = texture2D(uImage0,vec2(rad,0));\n"
- "}\n";
-
-
- const char *gRadialFocusTextureFrag =
- "varying vec2 vTexCoord;\n"
- "uniform sampler2D uImage0;\n"
- "uniform float mA;\n"
- "uniform float mFX;\n"
- "uniform float mOn2A;\n"
- "void main(void)\n"
- "{\n"
- " float GX = vTexCoord.x - mFX;\n"
- " float C = GX*GX + vTexCoord.y*vTexCoord.y;\n"
- " float B = 2.0*GX * mFX;\n"
- " float det =B*B - mA*C;\n"
- " float rad;\n"
- " if (det<0.0)\n"
- " rad = -B * mOn2A;\n"
- " else\n"
- " rad = (-B - sqrt(det)) * mOn2A;"
- " gl_FragColor = texture2D(uImage0,vec2(rad,0));\n"
- "}\n";
-
-
- const char *gTextureColourFrag =
- "uniform sampler2D uImage0;\n"
- "varying vec2 vTexCoord;\n"
- "varying vec4 vColourArray;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = texture2D(uImage0,vTexCoord) * vColourArray;\n"
- "}\n";
-
-
- const char *gTextureColourPremultFrag =
- "uniform sampler2D uImage0;\n"
- "varying vec2 vTexCoord;\n"
- "varying vec4 vColourArray;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor.rgb = texture2D(uImage0,vTexCoord).rgb * vColourArray.rgb * vColourArray.a;\n"
- " gl_FragColor.a = texture2D(uImage0,vTexCoord).a * vColourArray.a;\n"
- "}\n";
-
-
- const char *gTextureTransFrag =
- "varying vec2 vTexCoord;\n"
- "uniform sampler2D uImage0;\n"
- "uniform vec4 uColourScale;\n"
- "uniform vec4 uColourOffset;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = texture2D(uImage0,vTexCoord) * uColourScale + uColourOffset;\n"
- "}\n";
-
-
- GPUProg *GPUProg::create (GPUProgID inID, AlphaMode inAlphaMode) {
+ GPUProg *GPUProg::create (unsigned int inID) {
- #ifdef ALLOW_OGL2
- switch (inID) {
-
- case gpuSolid:
- return new OpenGLProgram (gSolidVert, gSolidFrag, inAlphaMode);
-
- case gpuColourTransform:
- return new OpenGLProgram (gColourVert, gColourTransFrag, inAlphaMode);
-
- case gpuColour:
- return new OpenGLProgram (gColourVert, gColourFrag, inAlphaMode);
-
- case gpuRadialGradient:
- return new OpenGLProgram (gTextureVert, gRadialTextureFrag, inAlphaMode);
-
- case gpuRadialFocusGradient:
- return new OpenGLProgram (gTextureVert, gRadialFocusTextureFrag, inAlphaMode);
-
- case gpuTexture:
- return new OpenGLProgram (gTextureVert, gTextureFrag, inAlphaMode);
-
- case gpuTextureColourArray:
- if (inAlphaMode == amPremultiplied)
- return new OpenGLProgram (gTextureColourVert, gTextureColourPremultFrag, inAlphaMode);
- else
- return new OpenGLProgram (gTextureColourVert, gTextureColourFrag, inAlphaMode);
-
- case gpuTextureTransform:
- return new OpenGLProgram (gTextureVert, gTextureTransFrag, inAlphaMode);
-
- case gpuBitmap:
- return new OpenGLProgram (gTextureVert, gBitmapFrag, inAlphaMode);
-
- case gpuBitmapAlpha:
- if (inAlphaMode == amPremultiplied)
- return new OpenGLProgram (gTextureVert, gBitmapAlphaPremultFrag, inAlphaMode);
- else
- return new OpenGLProgram (gTextureVert, gBitmapAlphaFrag, inAlphaMode);
-
- default:
- break;
-
- }
+ std::string vertexVars =
+ "uniform mat4 uTransform;\n"
+ "attribute vec4 aVertex;\n";
+
+ std::string vertexProg =
+ " gl_Position = aVertex * uTransform;\n";
+
+ std::string pixelVars = "";
+ std::string pixelProlog = "";
+
+ #ifdef LIME_GLES
+ pixelVars = std::string ("precision mediump float;\n");
#endif
- return 0;
+ std::string fragColour = "";
+
+ if (inID & PROG_TINT) {
+
+ pixelVars += "uniform vec4 uColourScale;\n";
+ fragColour = "uColourScale";
+
+ }
+
+ if (inID & PROG_COLOUR_OFFSET) {
+
+ pixelVars += "uniform vec4 uColourOffset;\n";
+
+ }
+
+ if (inID & PROG_COLOUR_PER_VERTEX) {
+
+ vertexVars +=
+ "attribute vec4 aColourArray;\n"
+ "varying vec4 vColourArray;\n";
+
+ vertexProg =
+ " vColourArray = aColourArray;\n" + vertexProg;
+
+ pixelVars +=
+ "varying vec4 vColourArray;\n";
+
+ if (fragColour != "") {
+
+ fragColour += "*";
+
+ }
+
+ fragColour += "vColourArray";
+
+ }
+
+ if (inID & PROG_TEXTURE) {
+
+ vertexVars +=
+ "attribute vec2 aTexCoord;\n"
+ "varying vec2 vTexCoord;\n";
+
+ vertexProg =
+ " vTexCoord = aTexCoord;\n" + vertexProg;
+
+ pixelVars +=
+ "uniform sampler2D uImage0;\n"
+ "varying vec2 vTexCoord;\n";
+
+ if (!(inID & PROG_RADIAL)) {
+
+ if (fragColour != "") {
+
+ fragColour += "*";
+
+ }
+
+ if (inID & PROG_ALPHA_TEXTURE) {
+
+ fragColour += "vec4(1,1,1,texture2D(uImage0,vTexCoord).a)";
+
+ } else {
+
+ fragColour += "texture2D(uImage0,vTexCoord)";
+
+ }
+
+ }
+
+ }
+
+ if (inID & PROG_RADIAL) {
+
+ if (inID & PROG_RADIAL_FOCUS) {
+
+ pixelVars +=
+ "uniform float mA;\n"
+ "uniform float mFX;\n"
+ "uniform float mOn2A;\n";
+
+ pixelProlog =
+ " float GX = vTexCoord.x - mFX;\n"
+ " float C = GX*GX + vTexCoord.y*vTexCoord.y;\n"
+ " float B = 2.0*GX * mFX;\n"
+ " float det =B*B - mA*C;\n"
+ " float rad;\n"
+ " if (det<0.0)\n"
+ " rad = -B * mOn2A;\n"
+ " else\n"
+ " rad = (-B - sqrt(det)) * mOn2A;\n";
+
+ } else {
+
+ pixelProlog =
+ " float rad = sqrt(vTexCoord.x*vTexCoord.x + vTexCoord.y*vTexCoord.y);\n";
+
+ }
+
+ if (fragColour != "") {
+
+ fragColour += "*";
+
+ }
+
+ fragColour += "texture2D(uImage0,vec2(rad,0))";
+
+ }
+
+ if (inID & PROG_NORMAL_DATA) {
+
+ vertexVars +=
+ "attribute vec2 aNormal;\n"
+ "varying vec2 vNormal;\n";
+
+ vertexProg =
+ " vNormal = aNormal;\n" + vertexProg;
+
+ pixelVars +=
+ "varying vec2 vNormal;\n";
+
+ }
+
+ std::string vertexShader =
+ vertexVars +
+ "void main()\n"
+ "{\n" +
+ vertexProg +
+ "}\n";
+
+ if (fragColour == "") {
+
+ fragColour = "vec4(1,1,1,1)";
+
+ }
+
+ if (inID & PROG_COLOUR_OFFSET) {
+
+ fragColour = fragColour + "+ uColourOffset";
+
+ }
+
+ if (inID & PROG_NORMAL_DATA) {
+
+ fragColour = "(" + fragColour + ") * vec4(1,1,1, min(vNormal.x-abs(vNormal.y),1.0) )";
+
+ }
+
+ std::string pixelShader =
+ pixelVars +
+ "void main()\n"
+ "{\n" +
+ pixelProlog +
+ " gl_FragColor = " + fragColour + ";\n" +
+ "}\n";
+
+ return new OpenGLProgram (vertexShader, pixelShader);
}