فهرست منبع

SDL/OGL platform improvements

Brian Fiete 2 سال پیش
والد
کامیت
258a6653f9

+ 39 - 39
BeefySysLib/BeefySysLib.cpp

@@ -32,12 +32,12 @@ static int BfAllocHook(int nAllocType, void *pvData,
 	size_t nSize, int nBlockUse, long lRequest,
 	const unsigned char * szFileName, int nLine)
 {
-	if (gLastReqId == lRequest)	
-		return TRUE;	
+	if (gLastReqId == lRequest)
+		return TRUE;
 
-	gLastReqId = lRequest;	
+	gLastReqId = lRequest;
 	if (szFileName == NULL)
-		return TRUE;	
+		return TRUE;
 
 	/*char str[1024];
 	sprintf(str, "Alloc: %d File: %s Line: %d\n", lRequest, szFileName, nLine);
@@ -56,7 +56,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 	//_CrtSetAllocHook(BfAllocHook);
 #endif
 
-    switch (fdwReason) 
+    switch (fdwReason)
 	{
     case DLL_PROCESS_ATTACH:
 		gDLLInstance = hinstDLL;
@@ -92,7 +92,7 @@ BF_EXPORT void BF_CALLTYPE BFApp_Create()
 BF_EXPORT void BF_CALLTYPE BFApp_Delete()
 {
 	delete gBFApp;
-	gBFApp = NULL;	
+	gBFApp = NULL;
 	FTFontManager::ClearCache();
 
 	//OutputDebugStrF("Deleting App\n");
@@ -105,16 +105,16 @@ BF_EXPORT void BF_CALLTYPE BFApp_Delete()
 //{
 //	FT_Library  library;   /* handle to library     */
 //	FT_Face     face;      /* handle to face object */
-//	
-//	auto error = FT_Init_FreeType(&library);	
+//
+//	auto error = FT_Init_FreeType(&library);
 //	error = FT_New_Face(library, "/temp/SourceCodePro-Regular.ttf", 0, &face);
 //	if (error == FT_Err_Unknown_File_Format)
 //	{
-//		
+//
 //	}
 //	else if (error)
 //	{
-//		
+//
 //	}
 //
 //	error = FT_Set_Char_Size(
@@ -127,7 +127,7 @@ BF_EXPORT void BF_CALLTYPE BFApp_Delete()
 //	String str = ".cHasDebugFlags";
 //
 //	PNGData image;
-//	image.CreateNew(256, 256);	
+//	image.CreateNew(256, 256);
 //	for (int i = 0; i < 256 * 256; i++)
 //		image.mBits[i] = 0xFF000000;
 //
@@ -201,12 +201,12 @@ BF_EXPORT void BF_CALLTYPE BFApp_SetRefreshRate(int rate)
 }
 
 BF_EXPORT const char* BF_CALLTYPE BFApp_GetInstallDir()
-{	
+{
 	return gBFApp->mInstallDir.c_str();
 }
 
 BF_EXPORT const char* BF_CALLTYPE BFApp_GetDataDir()
-{	
+{
 	return gBFApp->mDataDir.c_str();
 }
 
@@ -261,7 +261,7 @@ BF_EXPORT void BF_CALLTYPE BFApp_RehupMouse()
 }
 
 BF_EXPORT const char* BF_CALLTYPE BFApp_EnumerateInputDevices()
-{	
+{
 	String& outString = *gBeefySys_TLStrReturn.Get();
 	outString = gBFApp->EnumerateInputDevices();
 	return outString.c_str();
@@ -284,7 +284,7 @@ BF_EXPORT intptr BF_CALLTYPE BFApp_GetCriticalThreadId(int idx)
 
 ///
 
-BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_MovedFunc movedFunc, BFWindow_CloseQueryFunc closeQueryFunc, BFWindow_ClosedFunc closedFunc, 
+BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_MovedFunc movedFunc, BFWindow_CloseQueryFunc closeQueryFunc, BFWindow_ClosedFunc closedFunc,
 	BFWindow_GotFocusFunc gotFocusFunc, BFWindow_LostFocusFunc lostFocusFunc,
 	BFWindow_KeyCharFunc keyCharFunc, BFWindow_KeyDownFunc keyDownFunc, BFWindow_KeyUpFunc keyUpFunc, BFWindow_HitTestFunc hitTestFunc,
 	BFWindow_MouseMove mouseMoveFunc, BFWindow_MouseProxyMove mouseProxyMoveFunc,
@@ -293,7 +293,7 @@ BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_Move
 {
 	window->mMovedFunc = movedFunc;
 	window->mCloseQueryFunc = closeQueryFunc;
-	window->mClosedFunc = closedFunc;	
+	window->mClosedFunc = closedFunc;
 	window->mGotFocusFunc = gotFocusFunc;
 	window->mLostFocusFunc = lostFocusFunc;
 	window->mKeyCharFunc = keyCharFunc;
@@ -420,8 +420,8 @@ BF_EXPORT TextureSegment* BF_CALLTYPE Gfx_CreateRenderTarget(int width, int heig
 {
 	Texture* texture = gBFApp->mRenderDevice->CreateRenderTarget(width, height, destAlpha != 0);
 
-	TextureSegment* aTextureSegment = new TextureSegment();		
-	aTextureSegment->InitFromTexture(texture);	
+	TextureSegment* aTextureSegment = new TextureSegment();
+	aTextureSegment->InitFromTexture(texture);
 	return aTextureSegment;
 }
 
@@ -438,10 +438,10 @@ BF_EXPORT TextureSegment* BF_CALLTYPE Gfx_LoadTexture(const char* fileName, int
 {
 	Texture* texture = gBFApp->mRenderDevice->LoadTexture(fileName, flags);
 	if (texture == NULL)
-		return NULL;	
+		return NULL;
 
-	TextureSegment* aTextureSegment = new TextureSegment();		
-	aTextureSegment->InitFromTexture(texture);	
+	TextureSegment* aTextureSegment = new TextureSegment();
+	aTextureSegment->InitFromTexture(texture);
 	return aTextureSegment;
 }
 
@@ -512,12 +512,12 @@ BF_EXPORT void BF_CALLTYPE Gfx_SetDrawSize(TextureSegment* textureSegment, int w
 }
 
 BF_EXPORT void BF_CALLTYPE Gfx_DrawTextureSegment(TextureSegment* textureSegment, float a, float b, float c, float d, float tx, float ty, float z, uint32 color, int pixelSnapping)
-{	
+{
 	DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
 	drawLayer->SetTexture(0, textureSegment->mTexture);
 	DefaultVertex3D* v = (DefaultVertex3D*)drawLayer->AllocStrip(4);
 
-	if ((pixelSnapping == 1) || 
+	if ((pixelSnapping == 1) ||
 		((pixelSnapping == 2) && (a == 1.0f) && (b == 0) && (c == 0) && (d == 1.0f)))
 	{
 		tx = (float) (int) (tx + 100000) - 100000;
@@ -527,13 +527,13 @@ BF_EXPORT void BF_CALLTYPE Gfx_DrawTextureSegment(TextureSegment* textureSegment
 	a *= textureSegment->mScaleX;
 	b *= textureSegment->mScaleX;
 	c *= textureSegment->mScaleY;
-	d *= textureSegment->mScaleY;	
+	d *= textureSegment->mScaleY;
 
 	v[0].Set(tx, ty, z, textureSegment->mU1, textureSegment->mV1, color);
 	v[1].Set(tx + a, ty + b, z, textureSegment->mU2, textureSegment->mV1, color);
-	v[2].Set(tx + c, ty + d, z, textureSegment->mU1, textureSegment->mV2, color);	
+	v[2].Set(tx + c, ty + d, z, textureSegment->mU1, textureSegment->mV2, color);
 	v[3].Set(tx + (a + c), ty + (b + d), z, textureSegment->mU2, textureSegment->mV2, color);
-    
+
     gPixelsDrawn += (int)((a + b) * (c + d));
 }
 
@@ -542,7 +542,7 @@ static DefaultVertex3D* gCurAllocVertices = NULL;
 
 BF_EXPORT void BF_CALLTYPE Gfx_AllocTris(TextureSegment* textureSegment, int vtxCount)
 {
-	gCurTextureSegment = textureSegment;	
+	gCurTextureSegment = textureSegment;
 	DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
 	drawLayer->SetTexture(0, textureSegment->mTexture);
 	gCurAllocVertices = (DefaultVertex3D*)gBFApp->mRenderDevice->mCurDrawLayer->AllocTris(vtxCount);
@@ -550,8 +550,8 @@ BF_EXPORT void BF_CALLTYPE Gfx_AllocTris(TextureSegment* textureSegment, int vtx
 
 BF_EXPORT void BF_CALLTYPE Gfx_SetDrawVertex(int idx, float x, float y, float z, float u, float v, uint32 color)
 {
-	gCurAllocVertices[idx].Set(x, y, z, 
-		gCurTextureSegment->mU1 + u * (gCurTextureSegment->mU2 - gCurTextureSegment->mU1), 
+	gCurAllocVertices[idx].Set(x, y, z,
+		gCurTextureSegment->mU1 + u * (gCurTextureSegment->mU2 - gCurTextureSegment->mU1),
 		gCurTextureSegment->mV1 + v * (gCurTextureSegment->mV2 - gCurTextureSegment->mV1), color);
 }
 
@@ -565,7 +565,7 @@ BF_EXPORT void BF_CALLTYPE Gfx_DrawQuads(TextureSegment* textureSegment, Default
 	/*for (int vtxIdx = 0; vtxIdx < vtxCount; vtxIdx += 4)
 	{
 		Vertex3D* v = gBFApp->mRenderDevice->mCurDrawLayer->AllocStrip(textureSegment->mTexture, drawType != 0, 4);
-		
+
 		v[0] = vertices[vtxIdx];
 		v[1] = vertices[vtxIdx + 1];
 		v[2] = vertices[vtxIdx + 2];
@@ -573,7 +573,7 @@ BF_EXPORT void BF_CALLTYPE Gfx_DrawQuads(TextureSegment* textureSegment, Default
 	}
 
 	return;*/
-	
+
 	DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
 	drawLayer->SetTexture(0, textureSegment->mTexture);
 
@@ -631,24 +631,24 @@ BF_EXPORT void BF_CALLTYPE Gfx_DrawIndexedVertices(int vertexSize, void* vtxData
 	for (int idxIdx = 0; idxIdx < idxCount; idxIdx++)
 		*(drawBatchIdxPtr++) = *(idxPtr++) + idxOfs;
 
-	memcpy(drawBatchVtxPtr, vtxData, vertexSize * vtxCount);	
+	memcpy(drawBatchVtxPtr, vtxData, vertexSize * vtxCount);
 }
 
 BF_EXPORT void BF_CALLTYPE Gfx_DrawIndexedVertices2D(int vertexSize, void* vtxData, int vtxCount, uint16* idxData, int idxCount, float a, float b, float c, float d, float tx, float ty, float z)
 {
 	DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
-	
+
 	uint16 idxOfs;
 	void* drawBatchVtxPtr;
 	uint16* drawBatchIdxPtr;
 	gBFApp->mRenderDevice->mCurDrawLayer->AllocIndexed(vtxCount, idxCount, (void**)&drawBatchVtxPtr, &drawBatchIdxPtr, &idxOfs);
-	BF_ASSERT(gBFApp->mRenderDevice->mCurDrawLayer->mCurDrawBatch->mVtxSize == vertexSize);	
+	BF_ASSERT(gBFApp->mRenderDevice->mCurDrawLayer->mCurDrawBatch->mVtxSize == vertexSize);
 
 	uint16* idxPtr = idxData;
-	for (int idxIdx = 0; idxIdx < idxCount; idxIdx++)	
+	for (int idxIdx = 0; idxIdx < idxCount; idxIdx++)
 		*(drawBatchIdxPtr++) = *(idxPtr++) + idxOfs;
 
-	//memcpy(drawBatchIdxPtr, idxData, sizeof(uint16) * idxCount);	
+	//memcpy(drawBatchIdxPtr, idxData, sizeof(uint16) * idxCount);
 	//memcpy(drawBatchVtxPtr, vtxData, vertexSize * vtxCount);
 
 	void* vtxPtr = vtxData;
@@ -713,12 +713,12 @@ BF_EXPORT void BF_CALLTYPE RenderState_SetWireframe(RenderState* renderState, bo
 }
 
 BF_EXPORT void BF_CALLTYPE RenderState_SetClip(RenderState* renderState, float x, float y, float width, float height)
-{	
+{
 	BF_ASSERT((width >= 0) && (height >= 0));
 	renderState->mClipRect.mX = x;
 	renderState->mClipRect.mY = y;
 	renderState->mClipRect.mWidth = width;
-	renderState->mClipRect.mHeight = height;	
+	renderState->mClipRect.mHeight = height;
 	if (!renderState->mClipped)
 		renderState->SetClipped(true);
 }
@@ -762,7 +762,7 @@ BF_EXPORT Shader* BF_CALLTYPE Gfx_LoadShader(const char* fileName, VertexDefinit
 BF_EXPORT void BF_CALLTYPE Gfx_SetRenderState(RenderState* renderState)
 {
 	BF_ASSERT(renderState->mShader != NULL);
-	gBFApp->mRenderDevice->SetRenderState(renderState);	
+	gBFApp->mRenderDevice->SetRenderState(renderState);
 }
 
 BF_EXPORT void BF_CALLTYPE Gfx_Shader_Delete(Shader* shader)

+ 41 - 42
BeefySysLib/gfx/DrawLayer.cpp

@@ -11,15 +11,15 @@ USING_NS_BF;
 static int sCurBatchId = 0;
 
 DrawBatch::DrawBatch()
-{		
+{
 	mId = ++sCurBatchId;
 	mVtxIdx = 0;
-	mIdxIdx = 0;	
+	mIdxIdx = 0;
 	mAllocatedVertices = 0;
-	mAllocatedIndices = 0;	
+	mAllocatedIndices = 0;
 	mIsIndexBufferHead = false;
 	mIsVertexBufferHead = false;
-	mVertices = NULL;		
+	mVertices = NULL;
 	mIndices = NULL;
 	mRenderState = NULL;
 	mDrawLayer = NULL;
@@ -41,7 +41,7 @@ void DrawBatch::Clear()
 }
 
 void DrawBatch::Free()
-{	
+{
 	RenderDevice* renderDevice = mDrawLayer->mRenderDevice;
 
 	if (mIsVertexBufferHead)
@@ -60,8 +60,8 @@ void DrawBatch::Free()
 
 DrawBatch* DrawBatch::AllocateChainedBatch(int minVtxCount, int minIdxCount)
 {
-	mDrawLayer->CloseDrawBatch();	
-	return mDrawLayer->AllocateBatch(minVtxCount, minIdxCount);		
+	mDrawLayer->CloseDrawBatch();
+	return mDrawLayer->AllocateBatch(minVtxCount, minIdxCount);
 }
 
 void* DrawBatch::AllocTris(int vtxCount)
@@ -75,14 +75,14 @@ void* DrawBatch::AllocTris(int vtxCount)
 			DrawBatch* nextBatch = AllocateChainedBatch(0, 0);
 			return nextBatch->AllocTris(vtxCount);
 		}
-		
-		mRenderState = gBFApp->mRenderDevice->mCurRenderState;		
+
+		mRenderState = gBFApp->mRenderDevice->mCurRenderState;
 	}
 
 	uint16* idxPtr = mIndices + mIdxIdx;
 	void* vtxPtr = (uint8*)mVertices + (mVtxIdx * mVtxSize);
-	
-	for (int idxNum = 0; idxNum < idxCount; idxNum++)	
+
+	for (int idxNum = 0; idxNum < idxCount; idxNum++)
 	{
 		*idxPtr++ = mVtxIdx++;
 		mIdxIdx++;
@@ -96,17 +96,17 @@ void* DrawBatch::AllocStrip(int vtxCount)
 	int idxCount = (vtxCount - 2) * 3;
 
 	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx >= mAllocatedIndices))
-	{			
+	{
 		if (mVtxIdx > 0)
-		{			
-			DrawBatch* nextBatch = AllocateChainedBatch(0, 0);			
+		{
+			DrawBatch* nextBatch = AllocateChainedBatch(0, 0);
 			return nextBatch->AllocStrip(vtxCount);
 		}
-					
-		mRenderState = gBFApp->mRenderDevice->mCurRenderState;		
+
+		mRenderState = gBFApp->mRenderDevice->mCurRenderState;
 	}
 
-	uint16* idxPtr = mIndices + mIdxIdx;	
+	uint16* idxPtr = mIndices + mIdxIdx;
 
 	void* vtxPtr = (uint8*)mVertices + (mVtxIdx * mVtxSize);
 
@@ -120,21 +120,21 @@ void* DrawBatch::AllocStrip(int vtxCount)
 		mVtxIdx++;
 		mIdxIdx += 3;
 	}
-	
+
 	return vtxPtr;
 }
 
 void DrawBatch::AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut)
-{	
+{
 	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx > mAllocatedIndices))
-	{			
+	{
 		if (mVtxIdx > 0)
-		{			
-			DrawBatch* nextBatch = AllocateChainedBatch(vtxCount, idxCount);			
+		{
+			DrawBatch* nextBatch = AllocateChainedBatch(vtxCount, idxCount);
 			return nextBatch->AllocIndexed(vtxCount, idxCount, verticesOut, indicesOut, idxOfsOut);
 		}
-				
-		mRenderState = gBFApp->mRenderDevice->mCurRenderState;		
+
+		mRenderState = gBFApp->mRenderDevice->mCurRenderState;
 	}
 
 	*verticesOut = (uint8*)mVertices + (mVtxIdx * mVtxSize);
@@ -148,8 +148,8 @@ void DrawBatch::AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uin
 //
 
 DrawLayer::DrawLayer()
-{	
-	mRenderWindow = NULL;	
+{
+	mRenderWindow = NULL;
 	mRenderDevice = NULL;
 	mIdxBuffer = NULL;
 	mVtxBuffer = NULL;
@@ -164,7 +164,6 @@ DrawLayer::DrawLayer()
 
 DrawLayer::~DrawLayer()
 {
-	NOP;
 }
 
 void DrawLayer::CloseDrawBatch()
@@ -178,9 +177,9 @@ void DrawLayer::CloseDrawBatch()
 }
 
 void DrawLayer::QueueRenderCmd(RenderCmd* renderCmd)
-{	
+{
 	CloseDrawBatch();
-	mRenderCmdList.PushBack(renderCmd);	
+	mRenderCmdList.PushBack(renderCmd);
 	renderCmd->CommandQueued(this);
 }
 
@@ -196,7 +195,7 @@ DrawBatch* DrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
 		minIdxCount = 512;
 		minVtxCount = minIdxCount;
 	}
-	
+
 	BF_ASSERT(minIdxCount * sizeof(uint16) <= DRAWBUFFER_IDXBUFFER_SIZE);
 	BF_ASSERT(minVtxCount * vtxSize <= DRAWBUFFER_VTXBUFFER_SIZE);
 
@@ -212,7 +211,7 @@ DrawBatch* DrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
 		drawBatch = pool.back();
 		pool.pop_back();
 	}
-	drawBatch->mDrawLayer = this;	
+	drawBatch->mDrawLayer = this;
 
 	int needIdxBytes = minIdxCount * sizeof(uint16);
 	int needVtxBytes = minVtxCount * vtxSize;
@@ -225,7 +224,7 @@ DrawBatch* DrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
 		drawBatch->mIsVertexBufferHead = false;
 	}
 	else
-	{		
+	{
 		mVtxBuffer = mRenderDevice->mPooledVertexBuffers.AllocMemoryBlock();
 		mVtxByteIdx = 0;
 		drawBatch->mVertices = (Vertex3D*)mVtxBuffer;
@@ -235,12 +234,12 @@ DrawBatch* DrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
 
 	if (needIdxBytes < DRAWBUFFER_IDXBUFFER_SIZE - mIdxByteIdx)
 	{
-		drawBatch->mIndices = (uint16*)((uint8*)mIdxBuffer + mIdxByteIdx);		
+		drawBatch->mIndices = (uint16*)((uint8*)mIdxBuffer + mIdxByteIdx);
 		drawBatch->mAllocatedIndices = (DRAWBUFFER_IDXBUFFER_SIZE - mIdxByteIdx) / sizeof(uint16);
 		drawBatch->mIsIndexBufferHead = false;
 	}
 	else
-	{		
+	{
 		mIdxBuffer = mRenderDevice->mPooledIndexBuffers.AllocMemoryBlock();
 		mIdxByteIdx = 0;
 		drawBatch->mIndices = (uint16*)mIdxBuffer;
@@ -250,7 +249,7 @@ DrawBatch* DrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
 
 	drawBatch->mAllocatedIndices = std::min(drawBatch->mAllocatedVertices, drawBatch->mAllocatedIndices);
 	drawBatch->mVtxSize = vtxSize;
-	
+
 	mRenderCmdList.PushBack(drawBatch);
 	mCurDrawBatch = drawBatch;
 
@@ -266,7 +265,7 @@ void DrawLayer::Draw()
 	{
 		curRenderCmd->Render(mRenderDevice, mRenderWindow);
 		curRenderCmd = curRenderCmd->mNext;
-	}	
+	}
 }
 
 void DrawLayer::Flush()
@@ -283,13 +282,13 @@ void DrawLayer::Clear()
 	RenderCmd* curBatch = mRenderCmdList.mHead;
 	while (curBatch != NULL)
 	{
-		RenderCmd* nextBatch = curBatch->mNext;		
+		RenderCmd* nextBatch = curBatch->mNext;
 		curBatch->Free();
 		curBatch = nextBatch;
 	}
-			
+
 	/*if ((mIdxBuffer == NULL) || (mCurDrawBatch != NULL))
-		mIdxBuffer = mRenderDevice->mPooledIndexBuffers.AllocMemoryBlock();	
+		mIdxBuffer = mRenderDevice->mPooledIndexBuffers.AllocMemoryBlock();
 	if ((mVtxBuffer == NULL) || (mCurDrawBatch != NULL))
 		mVtxBuffer = mRenderDevice->mPooledVertexBuffers.AllocMemoryBlock();
 	if ((mRenderCmdBuffer == NULL) || (mRenderCmdByteIdx != 0))
@@ -357,7 +356,7 @@ BF_EXPORT void BF_CALLTYPE DrawLayer_Delete(DrawLayer* drawLayer)
 {
 	if (drawLayer->mRenderWindow != NULL)
 	{
-		drawLayer->mRenderWindow->mDrawLayerList.Remove(drawLayer);		
+		drawLayer->mRenderWindow->mDrawLayerList.Remove(drawLayer);
 	}
 
 	delete drawLayer;
@@ -382,13 +381,13 @@ BF_EXPORT void BF_CALLTYPE DrawLayer_Activate(DrawLayer* drawLayer)
 }
 
 BF_EXPORT void BF_CALLTYPE DrawLayer_DrawToRenderTarget(DrawLayer* drawLayer, TextureSegment* textureSegment)
-{	
+{
 	RenderDevice* renderDevice = gBFApp->mRenderDevice;
 
 	BP_ZONE("DrawLayer_DrawToRenderTarget DrawPart");
 	RenderTarget* prevTarget = renderDevice->mCurRenderTarget;
 	renderDevice->PhysSetRenderState(renderDevice->mDefaultRenderState);
-	renderDevice->PhysSetRenderTarget(textureSegment->mTexture);	
+	renderDevice->PhysSetRenderTarget(textureSegment->mTexture);
 	drawLayer->Draw();
 	drawLayer->Clear();
 	renderDevice->mCurRenderTarget = prevTarget;

+ 12 - 12
BeefySysLib/gfx/DrawLayer.h

@@ -22,7 +22,7 @@ class RenderState;
 class DrawBatch : public RenderCmd
 {
 public:
-	DrawLayer*				mDrawLayer;	
+	DrawLayer*				mDrawLayer;
 	int						mId;
 
 	bool					mIsVertexBufferHead;
@@ -32,11 +32,11 @@ public:
 	int						mVtxSize;
 	int						mVtxIdx;
 	int						mAllocatedVertices;
-	
+
 	uint16*					mIndices;
 	int						mIdxIdx;
 	int						mAllocatedIndices;
-		
+
 	Texture*				mCurTextures[MAX_TEXTURES];
 
 public:
@@ -46,10 +46,10 @@ public:
 	virtual void			Free() override;
 
 	void					Clear();
-	DrawBatch*				AllocateChainedBatch(int minVtxCount, int minIdxCount);		
+	DrawBatch*				AllocateChainedBatch(int minVtxCount, int minIdxCount);
 	virtual void*			AllocTris(int vtxCount);
 	virtual void*			AllocStrip(int vtxCount);
-	virtual void			AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut);	
+	virtual void			AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut);
 };
 
 #define DRAWBUFFER_CMDBUFFER_SIZE 64*1024
@@ -58,26 +58,26 @@ public:
 
 class DrawLayer
 {
-public:			
+public:
 	SLIList<RenderCmd*>		mRenderCmdList;
 	DrawBatch*				mCurDrawBatch;
 
-	RenderWindow*			mRenderWindow;	
+	RenderWindow*			mRenderWindow;
 	RenderDevice*			mRenderDevice;
 
 	void*					mIdxBuffer;
 	void*					mVtxBuffer;
 	void*					mRenderCmdBuffer;
 	int						mIdxByteIdx;
-	int						mVtxByteIdx;	
+	int						mVtxByteIdx;
 	int						mRenderCmdByteIdx;
 
 	Texture*				mCurTextures[MAX_TEXTURES];
-	
+
 public:
 	template <typename T>
 	T*						AllocRenderCmd(int extraBytes = 0)
-	{ 
+	{
 		if (mRenderCmdByteIdx + sizeof(T) + extraBytes >= DRAWBUFFER_CMDBUFFER_SIZE)
 		{
 			mRenderCmdBuffer = mRenderDevice->mPooledRenderCmdBuffers.AllocMemoryBlock();
@@ -93,9 +93,9 @@ public:
 		return cmd;
 	}
 
-public:		
+public:
 	void					CloseDrawBatch();
-	virtual DrawBatch*		CreateDrawBatch() = 0;	
+	virtual DrawBatch*		CreateDrawBatch() = 0;
 	virtual DrawBatch*		AllocateBatch(int minVtxCount, int minIdxCount);
 	void					QueueRenderCmd(RenderCmd* renderCmd);
 	virtual RenderCmd*		CreateSetTextureCmd(int textureIdx, Texture* texture) = 0;

+ 41 - 36
BeefySysLib/gfx/FTFont.cpp

@@ -56,7 +56,7 @@ void FTFont::Dispose(bool cacheRetain)
 				}
 			}
 		}
-		mFaceSize = NULL;		
+		mFaceSize = NULL;
 	}
 }
 
@@ -78,14 +78,14 @@ FTFontManager::FTFontManager()
 	{
 		uint8 whiteVal = (uint8)(pow(i / 255.0f, 0.75) * 255.0f);
 		uint8 blackVal = (uint8)(pow(i / 255.0f, 0.9) * 255.0f);
-		
+
 		mWhiteTab[i] = whiteVal;
 		mBlackTab[i] = blackVal;
 	}
 }
 
 FTFontManager::~FTFontManager()
-{	
+{
 	for (auto page : mPages)
 		delete page;
 	mPages.Clear();
@@ -110,7 +110,7 @@ void FTFontManager::DoClearCache()
 		}
 		else
 			++itr;
-	}	
+	}
 }
 
 void FTFontManager::ClearCache()
@@ -133,11 +133,11 @@ bool FTFont::Load(const StringImpl& fileName, float pointSize)
 {
 	if (gFTLibrary == NULL)
 		FT_Init_FreeType(&gFTLibrary);
-	
+
 	FTFontManager::Face* face = NULL;
 
 	FTFontManager::Face** facePtr = NULL;
-	if (gFTFontManager.mFaces.TryAdd(fileName, NULL, &facePtr))	
+	if (gFTFontManager.mFaces.TryAdd(fileName, NULL, &facePtr))
 	{
 		face = new FTFontManager::Face();
 		*facePtr = face;
@@ -153,7 +153,7 @@ bool FTFont::Load(const StringImpl& fileName, float pointSize)
 			faceIdx = atoi(useFileName.c_str() + atPos + 1);
 			useFileName.RemoveToEnd(atPos);
 		}
-		auto error = FT_New_Face(gFTLibrary, useFileName.c_str(), faceIdx, &ftFace);		
+		auto error = FT_New_Face(gFTLibrary, useFileName.c_str(), faceIdx, &ftFace);
 		face->mFTFace = ftFace;
 	}
 	else
@@ -164,7 +164,7 @@ bool FTFont::Load(const StringImpl& fileName, float pointSize)
 		return false;
 
 	mFace = face;
-		
+
 	FTFontManager::FaceSize** faceSizePtr = NULL;
 	if (face->mFaceSizes.TryAdd(pointSize, NULL, &faceSizePtr))
 	{
@@ -177,17 +177,17 @@ bool FTFont::Load(const StringImpl& fileName, float pointSize)
 		FT_New_Size(mFace->mFTFace, &ftSize);
 		FT_Activate_Size(ftSize);
 		auto error = FT_Set_Char_Size(mFace->mFTFace, 0, (int)(pointSize * 64), 72, 72);
-				
+
 		mFaceSize->mFace = mFace;
 		mFaceSize->mFTSize = ftSize;
-		mFaceSize->mPointSize = pointSize;		
+		mFaceSize->mPointSize = pointSize;
 	}
 	else
 	{
 		mFaceSize = *faceSizePtr;
 	}
 	mFaceSize->mRefCount++;
-		
+
 	mHeight = mFaceSize->mFTSize->metrics.height / 64;
 	mAscent = mFaceSize->mFTSize->metrics.ascender / 64;
 	mDescent = mFaceSize->mFTSize->metrics.descender / 64;
@@ -199,7 +199,7 @@ bool FTFont::Load(const StringImpl& fileName, float pointSize)
 TextureSegment* BF_CALLTYPE Gfx_CreateTextureSegment(TextureSegment* textureSegment, int srcX, int srcY, int srcWidth, int srcHeight);
 
 FTFontManager::Glyph* FTFont::AllocGlyph(int charCode, bool allowDefault)
-{	
+{
 	FT_Activate_Size(mFaceSize->mFTSize);
 
 	int glyph_index = FT_Get_Char_Index(mFace->mFTFace, charCode);
@@ -209,20 +209,20 @@ FTFontManager::Glyph* FTFont::AllocGlyph(int charCode, bool allowDefault)
 	auto error = FT_Load_Glyph(mFace->mFTFace, glyph_index, FT_LOAD_NO_BITMAP);
 	if (error != FT_Err_Ok)
 		return NULL;
-	
+
 	error = FT_Render_Glyph(mFace->mFTFace->glyph, FT_RENDER_MODE_NORMAL);
 	if (error != FT_Err_Ok)
 		return NULL;
-		
+
 	auto& bitmap = mFace->mFTFace->glyph->bitmap;
-	
+
 	if ((bitmap.rows > FT_PAGE_HEIGHT) || (bitmap.width > FT_PAGE_WIDTH))
 	{
 		return NULL;
 	}
-	
+
 	FTFontManager::Page* page = NULL;
-						
+
 	if (!gFTFontManager.mPages.empty())
 	{
 		page = gFTFontManager.mPages.back();
@@ -231,14 +231,14 @@ FTFontManager::Glyph* FTFont::AllocGlyph(int charCode, bool allowDefault)
 			// Move down to next row
 			page->mCurX = 0;
 			page->mCurY += page->mMaxRowHeight;
-			page->mMaxRowHeight = 0;						
+			page->mMaxRowHeight = 0;
 		}
 
 		if (page->mCurY + (int)bitmap.rows > page->mTexture->mHeight)
 		{
 			// Doesn't fit
 			page = NULL;
-		}					
+		}
 	}
 
 	if (page == NULL)
@@ -261,28 +261,32 @@ FTFontManager::Glyph* FTFont::AllocGlyph(int charCode, bool allowDefault)
 	glyph->mX = page->mCurX;
 	glyph->mY = page->mCurY;
 	glyph->mWidth = bitmap.width;
-	glyph->mHeight = bitmap.rows;		
+	glyph->mHeight = bitmap.rows;
 
 	if (page->mTexture == NULL)
 	{
-		ImageData img;
-		img.CreateNew(FT_PAGE_WIDTH, FT_PAGE_HEIGHT);
+		ImageData* img = new ImageData();
+		img->CreateNew(FT_PAGE_WIDTH, FT_PAGE_HEIGHT);
+		auto* bits = img->mBits;
 		for (int i = 0; i < FT_PAGE_HEIGHT * FT_PAGE_WIDTH; i++)
 		{
 			if (i % 3 == 0)
-				img.mBits[i] = 0xFFFF0000;
+				bits[i] = 0xFFFF0000;
 			else if (i % 3 == 1)
-				img.mBits[i] = 0xFF00FF00;
+				bits[i] = 0xFF00FF00;
 			else
-				img.mBits[i] = 0xFF0000FF;
+				bits[i] = 0xFF0000FF;
 		}
-		page->mTexture = gBFApp->mRenderDevice->LoadTexture(&img, TextureFlag_NoPremult);		
+		page->mTexture = gBFApp->mRenderDevice->LoadTexture(img, TextureFlag_NoPremult);
+		img->Deref();
 	}
 
 	if (bitmap.width > 0)
 	{
-		ImageData img;
-		img.CreateNew(bitmap.width, bitmap.rows);
+		ImageData* img = new ImageData();
+		img->CreateNew(bitmap.width, bitmap.rows);
+		auto* bits = img->mBits;
+		int width = img->mWidth;
 		for (int y = 0; y < (int)bitmap.rows; y++)
 		{
 			for (int x = 0; x < (int)bitmap.width; x++)
@@ -292,17 +296,18 @@ FTFontManager::Glyph* FTFont::AllocGlyph(int charCode, bool allowDefault)
 				uint8 whiteVal = gFTFontManager.mWhiteTab[val];
 				uint8 blackVal = gFTFontManager.mBlackTab[val];
 
-				img.mBits[y * img.mWidth + x] = ((int32)whiteVal << 24) |
+				bits[y * width + x] = ((int32)whiteVal << 24) |
 					((int32)blackVal) | ((int32)0xFF << 8) | ((int32)0xFF << 16);
 			}
 		}
-		page->mTexture->Blt(&img, page->mCurX, page->mCurY);
+		page->mTexture->Blt(img, page->mCurX, page->mCurY);
+		img->Deref();
 	}
 
 	page->mCurX += bitmap.width;
 	page->mMaxRowHeight = std::max(page->mMaxRowHeight, (int)bitmap.rows);
 
-	auto texture = page->mTexture;	
+	auto texture = page->mTexture;
 	texture->AddRef();
 
 	TextureSegment* textureSegment = new TextureSegment();
@@ -330,7 +335,7 @@ int FTFont::GetKerning(int charA, int charB)
 
 void FTFont::Release(bool cacheRetain)
 {
-	Dispose(cacheRetain);	
+	Dispose(cacheRetain);
 	delete this;
 }
 
@@ -338,7 +343,7 @@ void FTFont::Release(bool cacheRetain)
 //////////////////////////////////////////////////////////////////////////
 
 BF_EXPORT FTFont* BF_CALLTYPE FTFont_Load(const char* fileName, float pointSize)
-{	
+{
 	auto ftFont = new FTFont();
 	if (!ftFont->Load(fileName, pointSize))
 	{
@@ -351,11 +356,11 @@ BF_EXPORT FTFont* BF_CALLTYPE FTFont_Load(const char* fileName, float pointSize)
 
 BF_EXPORT void BF_CALLTYPE FTFont_ClearCache()
 {
-	FTFontManager::ClearCache();		
+	FTFontManager::ClearCache();
 }
 
 BF_EXPORT void BF_CALLTYPE FTFont_Delete(FTFont* ftFont, bool cacheRetain)
-{	
+{
 	ftFont->Release(cacheRetain);
 }
 
@@ -366,6 +371,6 @@ BF_EXPORT FTFontManager::Glyph* BF_CALLTYPE FTFont_AllocGlyph(FTFont* ftFont, in
 
 BF_EXPORT int BF_CALLTYPE FTFont_GetKerning(FTFont* ftFont, int charCodeA, int charCodeB)
 {
-	auto kerning = ftFont->GetKerning(charCodeA, charCodeB);	
+	auto kerning = ftFont->GetKerning(charCodeA, charCodeB);
 	return kerning;
 }

+ 14 - 14
BeefySysLib/gfx/RenderDevice.cpp

@@ -20,7 +20,7 @@ RenderState::RenderState()
 	mCullMode = CullMode_None;
 	mDepthFunc = DepthFunc_Always;
 	mTopology = Topology3D_TriangleList;
-	mShader = NULL;	
+	mShader = NULL;
 	mClipped = false;
 	mTexWrap = false;
 	mWireframe = false;
@@ -32,18 +32,18 @@ RenderTarget::RenderTarget()
 	mHeight = 0;
 	mHasBeenDrawnTo = false;
 	mHasBeenTargeted = false;
-	mResizeNum = 0;		
+	mResizeNum = 0;
 }
 
 RenderWindow::RenderWindow()
 {
-	mCurDrawLayer = NULL;	
+	mCurDrawLayer = NULL;
 	mRenderDevice = NULL;
 	mWindow = NULL;
 }
 
 RenderWindow::~RenderWindow()
-{	
+{
 	for (auto drawLayer : mDrawLayerList)
 		delete drawLayer;
 }
@@ -54,14 +54,14 @@ RenderDevice::RenderDevice() :
 	mPooledIndexBuffers(DRAWBUFFER_IDXBUFFER_SIZE),
 	mPooledVertexBuffers(DRAWBUFFER_VTXBUFFER_SIZE),
 	mPooledRenderCmdBuffers(DRAWBUFFER_CMDBUFFER_SIZE)
-{	
-	mCurRenderState = NULL;	
+{
+	mCurRenderState = NULL;
 	mDefaultRenderState = NULL;
 	mPhysRenderState = mDefaultRenderState;
 	mResizeCount = 0;
-	mCurRenderTarget = NULL;		
+	mCurRenderTarget = NULL;
 	mCurDrawLayer = NULL;
-	mPhysRenderWindow = NULL;	
+	mPhysRenderWindow = NULL;
 	mApp = NULL;
 }
 
@@ -107,7 +107,7 @@ Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
 	int dotPos = (int)fileName.LastIndexOf('.');
 	String ext;
 	if (dotPos != -1)
-		ext = fileName.Substring(dotPos);		
+		ext = fileName.Substring(dotPos);
 
 	ImageData* imageData = NULL;
 	bool handled = false;
@@ -121,7 +121,7 @@ Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
 		handled = true;
 	}
 	else if (ext == ".tga")
-		imageData = new TGAData();	
+		imageData = new TGAData();
 	else if (ext == ".png")
 		imageData = new PNGData();
 	else if (ext == ".jpg")
@@ -133,10 +133,10 @@ Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
 		BF_FATAL("Unknown texture format");
 		return NULL; // Unknown format
 	}
-		
+
 	if (!handled)
 	{
-		imageData->mWantsAlphaPremultiplied = (flags & TextureFlag_NoPremult) == 0;		
+		imageData->mWantsAlphaPremultiplied = (flags & TextureFlag_NoPremult) == 0;
 		if (fileName.StartsWith("@"))
 		{
 			int colon = (int)fileName.IndexOf(':');
@@ -163,8 +163,8 @@ Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
 	Texture* aTexture = NULL;
 	if (!failed)
 		aTexture = LoadTexture(imageData, flags);
-	
-	delete imageData;
+
+	imageData->Deref();
 	return aTexture;
 }
 

+ 19 - 6
BeefySysLib/img/ImageData.cpp

@@ -19,15 +19,28 @@ ImageData::ImageData()
 	mWantsAlphaPremultiplied = true;
 	mAlphaPremultiplied = false;
 	mIsAdditive = false;
-	mSrcDataLen = 0;		
+	mSrcDataLen = 0;
+	mRefCount = 1;
 }
 
 ImageData::~ImageData()
-{	
+{
+	BF_ASSERT(mRefCount <= 1); // Allow direct delete if we only have one reference
 	delete [] mBits;
 	delete [] mSrcData;
 }
 
+void ImageData::AddRef()
+{
+	mRefCount++;
+}
+
+void ImageData::Deref()
+{
+	if (--mRefCount == 0)
+		delete this;
+}
+
 void ImageData::SwapRAndB()
 {
 	int aSize = mWidth*mHeight;
@@ -101,15 +114,15 @@ ImageData* ImageData::Duplicate()
 }
 
 bool ImageData::LoadFromMemory(void* ptr, int size)
-{		
+{
 	SetSrcData((uint8*)ptr, size);
-	bool result = ReadData();	
-	mSrcData = NULL;	
+	bool result = ReadData();
+	mSrcData = NULL;
 	return result;
 }
 
 bool ImageData::LoadFromFile(const StringImpl& path)
-{	
+{
 	int size = 0;
 	uint8* aData = LoadBinaryData(path, &size);
 	if (aData == NULL)

+ 9 - 6
BeefySysLib/img/ImageData.h

@@ -15,6 +15,7 @@ enum
 class ImageData
 {
 public:
+	int						mRefCount;
 	int						mX;
 	int						mY;
 	int						mWidth;
@@ -26,23 +27,25 @@ public:
 	uint8*					mSrcData;
 	int						mSrcDataLen;
 	bool					mKeepSrcDataValid;
-	bool					mOwnsSrcData;	
+	bool					mOwnsSrcData;
 
 	bool					mWantsAlphaPremultiplied;
 	bool					mAlphaPremultiplied;
-	bool					mIsAdditive;		
-	
-public:	
+	bool					mIsAdditive;
+
+public:
 	ImageData();
 	virtual ~ImageData();
-	
+
+	void					AddRef();
+	void					Deref();
 	void					SwapRAndB();
 	void					CreateNew(int x, int y, int width, int height, bool clear = true);
 	void					CreateNew(int width, int height, bool clear = true);
 	void					CopyFrom(ImageData* img, int x, int y);
 	void					Fill(uint32 color);
 	virtual ImageData*		Duplicate();
-	void					SetSrcData(uint8* data, int dataLen);	
+	void					SetSrcData(uint8* data, int dataLen);
 	virtual bool			LoadFromMemory(void* ptr, int size);
 	virtual bool			LoadFromFile(const StringImpl& path);
 	virtual	bool			ReadData() { return false; }

+ 342 - 557
BeefySysLib/platform/sdl/GLRenderDevice.cpp

@@ -3,12 +3,14 @@
 #include "BFWindow.h"
 #include "img/ImageData.h"
 #include "util/PerfTimer.h"
-#include "SDL_video.h"
+#include <SDL2/SDL_video.h>
 
 USING_NS_BF;
 
 #define NOT_IMPL throw "Not implemented"
 
+#pragma comment(lib, "SDL2.lib")
+
 #ifdef _WIN32
 #ifdef BF_PLATFORM_OPENGL_ES2
 #pragma comment(lib, "libEGL.lib")
@@ -34,6 +36,12 @@ USING_NS_BF;
 #define APIENTRYP BF_CALLTYPE *
 #endif
 
+typedef void (APIENTRYP GL_DEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam);
+
+static void (APIENTRYP bf_glDebugMessageCallback)(GL_DEBUGPROC callback, const void* userParam);
+static void (APIENTRYP bf_glActiveTexture)(GLenum texture);
+static void (APIENTRYP bf_glGenVertexArrays)(GLsizei n, GLuint* buffers);
+static void (APIENTRYP bf_glBindVertexArray)(GLenum target);
 static void (APIENTRYP bf_glGenBuffers)(GLsizei n, GLuint *buffers);
 static void (APIENTRYP bf_glBindBuffer)(GLenum target, GLuint buffer);
 static void (APIENTRYP bf_glBufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
@@ -103,7 +111,7 @@ static int GetPowerOfTwo(int input)
 {
 	int value = 1;
 	while (value < input)
-		value <<= 1;	
+		value <<= 1;
 	return value;
 }
 
@@ -111,13 +119,13 @@ static int GetPowerOfTwo(int input)
 #define GLCHECK(check) if ((check) != 0) BF_FATAL("GL call failed")
 
 static void CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, float matrix[4][4])
-{	
-	memset(matrix, 0, sizeof(float) * 4 * 4);	
-	
+{
+	memset(matrix, 0, sizeof(float) * 4 * 4);
+
 	float invRL = 1.0f / (right - left);
 	float invTB = 1.0f / (top - bottom);
 	float invFN = 1.0f / (zFar - zNear);
-	
+
 	matrix[0][0] = 2.0f * invRL;
 	matrix[1][1] = 2.0f * invTB;
 	matrix[2][2] = -2.0f * invFN;
@@ -134,7 +142,7 @@ GLShaderParam::GLShaderParam()
 }
 
 GLShaderParam::~GLShaderParam()
-{	
+{
 }
 
 void GLShaderParam::SetTexture(Texture* texture)
@@ -147,44 +155,26 @@ void GLShaderParam::SetTexture(Texture* texture)
 void GLShaderParam::SetFloat4(float x, float y, float z, float w)
 {
 	NOT_IMPL;
-	//float v[4] = {x, y, z, w};	
+	//float v[4] = {x, y, z, w};
 	//GLCHECK(mGLVariable->AsVector()->SetFloatVector(v));
 }
 
 ///
 
 GLShader::GLShader()
-{		
+{
 }
 
 GLShader::~GLShader()
 {
-	GLShaderParamMap::iterator itr = mParamsMap.begin();
-	while (itr != mParamsMap.end())
+	for (auto paramKV : mParamsMap)
 	{
-		delete itr->second;
-		++itr;
+		delete paramKV.mValue;
 	}
-
-	//if (mGLEffect != NULL)
-		//mGLEffect->Release();	
 }
 
-ShaderParam* GLShader::GetShaderParam(const std::wstring& name)
+ShaderParam* GLShader::GetShaderParam(const StringImpl& name)
 {
-	/*GLShaderParamMap::iterator itr = mParamsMap.find(name);
-	if (itr != mParamsMap.end())
-		return itr->second;
-
-	IGL10EffectVariable* d3DVariable = mGLEffect->GetVariableByName(ToString(name).c_str());
-	if (d3DVariable == NULL)
-		return NULL;
-
-	GLShaderParam* shaderParam = new GLShaderParam();
-	shaderParam->mGLVariable = d3DVariable;
-	mParamsMap[name] = shaderParam;
-
-	return shaderParam;*/
 	NOT_IMPL;
 	return NULL;
 }
@@ -193,56 +183,48 @@ ShaderParam* GLShader::GetShaderParam(const std::wstring& name)
 
 GLTexture::GLTexture()
 {
-	mGLTexture = NULL;
-	//mGLRenderTargetView = NULL;	
+	mGLTexture = 0;
+	mGLTexture2 = 0;
+	//mGLRenderTargetView = NULL;
 	mRenderDevice = NULL;
+	mImageData = NULL;
 }
 
 GLTexture::~GLTexture()
 {
+	if (mImageData != NULL)
+		mImageData->Deref();
 	//if (mGLTexture != NULL)
 		//mGLTexture->Release();
 }
 
 void GLTexture::PhysSetAsTarget()
-{	
+{
 	NOT_IMPL;
-	//{
-	//	GL10_VIEWPORT viewPort;
-	//	viewPort.Width = mWidth;
-	//	viewPort.Height = mHeight;
-	//	viewPort.MinDepth = 0.0f;
-	//	viewPort.MaxDepth = 1.0f;
-	//	viewPort.TopLeftX = 0;
-	//	viewPort.TopLeftY = 0;
-
-	//	mRenderDevice->mGLDevice->RSSetViewports(1, &viewPort);
-	//	mRenderDevice->mGLDevice->OMSetRenderTargets(1, &mGLRenderTargetView, NULL);		
-	//}
-
-	//if (!mHasBeenDrawnTo)
-	//{
-	//	//mRenderDevice->mGLDevice->ClearRenderTargetView(mGLRenderTargetView, D3GLVECTOR4(1, 0.5, 0.5, 1));				
-	//	mHasBeenDrawnTo = true;
-	//}
 }
 
-///
+void GLTexture::Blt(ImageData* imageData, int x, int y)
+{
+	if (mImageData != NULL)
+	{
+		for (int row = 0; row < imageData->mHeight; row++)
+		{
+			memcpy(mImageData->mBits + (y + row) * mImageData->mWidth + x,
+				imageData->mBits + row * imageData->mWidth, imageData->mWidth * 4);
+		}
+	}
+	else
+	{
+		glBindTexture(GL_TEXTURE_2D, mGLTexture);
+		glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, imageData->mWidth, imageData->mHeight, GL_RGBA, GL_UNSIGNED_BYTE, imageData->mBits);
+	}
+}
 
-GLDrawBatch::GLDrawBatch(int minVtxSize, int minIdxSize) : DrawBatch()
-{	
-	mAllocatedVertices = 16*1024;
-	// Alloc more indices than vertices. Worst case is really long tri strip.
-	mAllocatedIndices = mAllocatedVertices * 3;
+///
 
-	if (minVtxSize > mAllocatedVertices)
-		mAllocatedVertices = GetPowerOfTwo(minVtxSize);
-	if (minIdxSize > mAllocatedIndices)
-		mAllocatedIndices = GetPowerOfTwo(minIdxSize);
+GLDrawBatch::GLDrawBatch() : DrawBatch()
+{
 
-	mVertices = new Vertex3D[mAllocatedVertices];	
-	mIndices = new uint16[mAllocatedIndices];
-    mNext = NULL;
 }
 
 GLDrawBatch::~GLDrawBatch()
@@ -252,86 +234,53 @@ GLDrawBatch::~GLDrawBatch()
 	//mGLBuffer->Release();
 }
 
-void GLDrawBatch::Lock()
-{		
-	//mGLBuffer->Map(GL10_MAP_WRITE_DISCARD, 0, (void**) &mVertices);
-}
-
 extern int gBFDrawBatchCount;
 
-void GLDrawBatch::Draw()
+struct GLVertex3D
+{
+	float x, y, z;
+	float u, v;
+	uint32 color;
+};
+
+void GLDrawBatch::Render(RenderDevice* renderDevice, RenderWindow* renderWindow)
 {
 	if (mIdxIdx == 0)
 		return;
 
     gBFDrawBatchCount++;
-    
-	GLRenderDevice* glRenderDevice = (GLRenderDevice*) gBFApp->mRenderDevice;
-	if (glRenderDevice->mPhysRenderWindow != mDrawLayer->mRenderWindow)
-		glRenderDevice->PhysSetRenderWindow(mDrawLayer->mRenderWindow);
-	
-	//// Flip BGRA to RGBA
-	//for (int i = 0; i < mIdx; i++)
-	//{
-	//	uint32 aColor = mVertices[i].color;
-	//	aColor = 
-	//		(aColor & 0xFF00FF00) |
-	//		((aColor & 0x00FF0000) >> 16) |
-	//		((aColor & 0x000000FF) << 16);
-	//	mVertices[i].color = aColor;
-	//}
-
-	//mGLBuffer->Unmap();
-	
-	
-	//GLShader* curShader = (GLShader*) aRenderDevice->mCurShader;
-	GLShader* curShader = (GLShader*) mCurShader;
-		
-	//if (curShader->mTextureParam != NULL)
-		//curShader->mTextureParam->SetTexture(mCurTexture);
-
-#ifdef BF_PLATFORM_OPENGL_ES2
-	//bf_glClientActiveTexture(GL_TEXTURE0);
-    glActiveTexture(GL_TEXTURE0);
-	glBindTexture(GL_TEXTURE_2D, ((GLTexture*)mCurTexture)->mGLTexture);
-	glUniform1i(curShader->mAttribTex0, 0);
-    
-	//bf_glClientActiveTexture(GL_TEXTURE1);
-    glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, ((GLTexture*)mCurTexture)->mGLTexture2);
-	glUniform1i(curShader->mAttribTex1, 1);
-	//glEnable(GL_TEXTURE_2D);
-#else
-	glBindTexture(GL_TEXTURE_2D, ((GLTexture*)mCurTexture)->mGLTexture);
-#endif
 
-    
-	//if (mIsAdditive != glRenderDevice->mCurAdditive)
-		//glRenderDevice->PhysSetAdditive(mIsAdditive);
-
-	//TODO: Just do 'apply', we don't have to do full PhysSetShaderPass
-	if (curShader != glRenderDevice->mPhysShader)
-		glRenderDevice->PhysSetShader(mCurShader);		
+	GLRenderDevice* glRenderDevice = (GLRenderDevice*) gBFApp->mRenderDevice;
+	GLShader* curShader = (GLShader*)mRenderState->mShader;
 
-	// Set vertex buffer
-	
-	if (glRenderDevice->mGLVertexBuffer == 0)
+	if (glRenderDevice->mGLVAO == 0)
 	{
-		bf_glGenBuffers(1, &glRenderDevice->mGLVertexBuffer);		
+		bf_glGenVertexArrays(1, &glRenderDevice->mGLVAO);
+		bf_glBindVertexArray(glRenderDevice->mGLVAO);
+
+		bf_glGenBuffers(1, &glRenderDevice->mGLVertexBuffer);
 		bf_glGenBuffers(1, &glRenderDevice->mGLIndexBuffer);
-	}	
+	}
+
+	auto glVertices = (GLVertex3D*)mVertices;
 
 	bf_glBindBuffer(GL_ARRAY_BUFFER, glRenderDevice->mGLVertexBuffer);
-	bf_glBufferData(GL_ARRAY_BUFFER, mVtxIdx * sizeof(Vertex3D), mVertices, GL_STREAM_DRAW);
-	
-	bf_glVertexAttribPointer(curShader->mAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void*)offsetof(Vertex3D, x));	
-	bf_glVertexAttribPointer(curShader->mAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void*)offsetof(Vertex3D, u));	
-	bf_glVertexAttribPointer(curShader->mAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D), (void*)offsetof(Vertex3D, color));
+	bf_glBufferData(GL_ARRAY_BUFFER, mVtxIdx * sizeof(GLVertex3D), mVertices, GL_STREAM_DRAW);
+
+	bf_glEnableVertexAttribArray(curShader->mAttribPosition);
+	bf_glVertexAttribPointer(curShader->mAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLVertex3D), (void*)offsetof(GLVertex3D, x));
+	bf_glEnableVertexAttribArray(curShader->mAttribTexCoord0);
+	bf_glVertexAttribPointer(curShader->mAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex3D), (void*)offsetof(GLVertex3D, u));
+	bf_glEnableVertexAttribArray(curShader->mAttribColor);
+	bf_glVertexAttribPointer(curShader->mAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GLVertex3D), (void*)offsetof(GLVertex3D, color));
+
+	if (mRenderState != renderDevice->mPhysRenderState)
+		renderDevice->PhysSetRenderState(mRenderState);
 
 	bf_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glRenderDevice->mGLIndexBuffer);
 	bf_glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIdxIdx * sizeof(int16), mIndices, GL_STREAM_DRAW);
 	bf_glDrawElements(GL_TRIANGLES, mIdxIdx, GL_UNSIGNED_SHORT, NULL);
-    
+
     bf_glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW);
     bf_glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW);
 }
@@ -349,56 +298,21 @@ DrawBatch* GLDrawLayer::CreateDrawBatch()
 	return new GLDrawBatch();
 }
 
-DrawBatch* GLDrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
-{
-	AutoPerf autoPerf("GLDrawLayer::AllocateBatch");
-
-	//GLDrawBatchVector* pool = &((GLRenderDevice*) gBFApp->mRenderDevice)->mDrawBatchPool;
 
-    GLRenderDevice* glRenderDevice = (GLRenderDevice*)gBFApp->mRenderDevice;
-    
-	GLDrawBatch* newBatch = NULL;
-	
-    //TODO: Search
-    GLDrawBatch** prevRefPtr = &glRenderDevice->mFreeBatchHead;
-    GLDrawBatch* checkBatch = glRenderDevice->mFreeBatchHead;
-    
-    while (checkBatch != NULL)
-    {
-        if ((checkBatch->mAllocatedVertices >= minVtxCount) &&
-			(checkBatch->mAllocatedIndices >= minIdxCount))
-		{
-			newBatch = checkBatch;
-			*prevRefPtr = (GLDrawBatch*)checkBatch->mNext;
-            checkBatch->mNext = NULL;
-			break;
-		}
-        
-        checkBatch = (GLDrawBatch*)checkBatch->mNext;
-        prevRefPtr = (GLDrawBatch**)&checkBatch->mNext;
-    }
-    
-	/*for (int i = pool->size() -1; i >= 0; i--)
-	{
-		GLDrawBatch* checkBatch = (*pool)[i];
-		
-		if ((checkBatch->mAllocatedVertices >= minVtxCount) &&
-			(checkBatch->mAllocatedIndices >= minIdxCount))
-		{
-			newBatch = checkBatch;
-			pool->erase(pool->begin() + i);
-			break;
-		}
-	}*/
+RenderCmd* GLDrawLayer::CreateSetTextureCmd(int textureIdx, Texture* texture)
+{
+	GLSetTextureCmd* setTextureCmd = AllocRenderCmd<GLSetTextureCmd>();
+	setTextureCmd->mTextureIdx = textureIdx;
+	setTextureCmd->mTexture = texture;
+	return setTextureCmd;
+}
 
-	if (newBatch == NULL)
-		newBatch = new GLDrawBatch(minVtxCount, minIdxCount);	
-	
-	newBatch->mDrawLayer = this;
-	return newBatch;
+void GLDrawLayer::SetShaderConstantData(int usageIdx, int slotIdx, void* constData, int size)
+{
 }
 
-void GLDrawLayer::FreeBatch(DrawBatch* drawBatch)
+
+/*void GLDrawLayer::FreeBatch(DrawBatch* drawBatch)
 {
 	//delete drawBatch;
 
@@ -410,46 +324,46 @@ void GLDrawLayer::FreeBatch(DrawBatch* drawBatch)
     GLRenderDevice* glRenderDevice = (GLRenderDevice*)gBFApp->mRenderDevice;
     drawBatch->mNext = glRenderDevice->mFreeBatchHead;
     glRenderDevice->mFreeBatchHead = batch;
-}
-
-void GLRenderDevice::PhysSetShader(Shader* shader)
-{	
-	GLRenderDevice* aRenderDevice = (GLRenderDevice*) gBFApp->mRenderDevice;
-	
-	//TODO: Cache more
-
-	GLShader* glShader = (GLShader*)shader;
-
-	GLfloat matrix[4][4];
-	CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix);
-	GLint matrixLoc = bf_glGetUniformLocation(glShader->mGLProgram, "screenMatrix");	
-	//BF_ASSERT(matrixLoc >= 0);	
-	if (matrixLoc >= 0)
-        bf_glUniformMatrix4fv(matrixLoc, 1, false, (float*)matrix);
-
-	/*mPhysShaderPass = shaderPass;
-	GLShaderPass* dXShaderPass = (GLShaderPass*) mPhysShaderPass;
-	mGLDevice->IASetInputLayout(dXShaderPass->mGLLayout);
-	
-	if (mCurShader->mLastResizeCount != mCurRenderTarget->mResizeNum)
-	{
-		ShaderParam* shaderParam = mCurShader->GetShaderParam(L"WindowSize");
-		if (shaderParam != NULL)
-		{
-			shaderParam->SetFloat2((float) mCurRenderTarget->mWidth, (float) mCurRenderTarget->mHeight);
-		}
-
-		mCurShader->mLastResizeCount = mCurRenderTarget->mResizeNum;
-	}
-
-	GLCHECK(dXShaderPass->mGLEffectPass->Apply(0));*/
-
-	/*GLfloat matrix[4][4];
-	CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix);
-	GLint uniformLocation = bf_glGetUniformLocation(((GLShader*)shaderPass->mTechnique->mShader)->mGLProgram, "screenMatrix");
-	if (uniformLocation != -1)
-		bf_glUniformMatrix4fv(uniformLocation, 1, false, (GLfloat*)matrix);*/
-}
+}*/
+
+//void GLRenderDevice::PhysSetShader(Shader* shader)
+//{
+//	GLRenderDevice* aRenderDevice = (GLRenderDevice*) gBFApp->mRenderDevice;
+//
+//	//TODO: Cache more
+//
+//	GLShader* glShader = (GLShader*)shader;
+//
+//	GLfloat matrix[4][4];
+//	CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix);
+//	GLint matrixLoc = bf_glGetUniformLocation(glShader->mGLProgram, "screenMatrix");
+//	//BF_ASSERT(matrixLoc >= 0);
+//	if (matrixLoc >= 0)
+//        bf_glUniformMatrix4fv(matrixLoc, 1, false, (float*)matrix);
+//
+//	/*mPhysShaderPass = shaderPass;
+//	GLShaderPass* dXShaderPass = (GLShaderPass*) mPhysShaderPass;
+//	mGLDevice->IASetInputLayout(dXShaderPass->mGLLayout);
+//
+//	if (mCurShader->mLastResizeCount != mCurRenderTarget->mResizeNum)
+//	{
+//		ShaderParam* shaderParam = mCurShader->GetShaderParam(L"WindowSize");
+//		if (shaderParam != NULL)
+//		{
+//			shaderParam->SetFloat2((float) mCurRenderTarget->mWidth, (float) mCurRenderTarget->mHeight);
+//		}
+//
+//		mCurShader->mLastResizeCount = mCurRenderTarget->mResizeNum;
+//	}
+//
+//	GLCHECK(dXShaderPass->mGLEffectPass->Apply(0));*/
+//
+//	/*GLfloat matrix[4][4];
+//	CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix);
+//	GLint uniformLocation = bf_glGetUniformLocation(((GLShader*)shaderPass->mTechnique->mShader)->mGLProgram, "screenMatrix");
+//	if (uniformLocation != -1)
+//		bf_glUniformMatrix4fv(uniformLocation, 1, false, (GLfloat*)matrix);*/
+//}
 
 void GLRenderDevice::PhysSetRenderWindow(RenderWindow* renderWindow)
 {
@@ -461,9 +375,9 @@ void GLRenderDevice::PhysSetRenderWindow(RenderWindow* renderWindow)
 void GLRenderDevice::PhysSetRenderTarget(Texture* renderTarget)
 {
 	mCurRenderTarget = renderTarget;
-	renderTarget->PhysSetAsTarget();	
+	renderTarget->PhysSetAsTarget();
 }
-  
+
 ///
 
 template <typename T>
@@ -472,12 +386,21 @@ static void BFGetGLProc(T& proc, const char* name)
 	proc = (T)SDL_GL_GetProcAddress(name);
 }
 
-#define BF_GET_GLPROC(name) BFGetGLProc(bf_##name, #name) 
+#define BF_GET_GLPROC(name) BFGetGLProc(bf_##name, #name)
+
+void GL_DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
+{
+	NOP;
+}
 
 GLRenderWindow::GLRenderWindow(GLRenderDevice* renderDevice, SDL_Window* sdlWindow)
-{	
+{
 	if (bf_glGenBuffers == NULL)
 	{
+		BF_GET_GLPROC(glDebugMessageCallback);
+		BF_GET_GLPROC(glActiveTexture);
+		BF_GET_GLPROC(glGenVertexArrays);
+		BF_GET_GLPROC(glBindVertexArray);
 		BF_GET_GLPROC(glGenBuffers);
 		BF_GET_GLPROC(glBindBuffer);
 		BF_GET_GLPROC(glBufferData);
@@ -530,105 +453,36 @@ GLRenderWindow::GLRenderWindow(GLRenderDevice* renderDevice, SDL_Window* sdlWind
 		BF_GET_GLPROC(glUniform1f);
 		BF_GET_GLPROC(glUniform2f);
 		BF_GET_GLPROC(glUniform3f);
-		BF_GET_GLPROC(glUniform4f);	
+		BF_GET_GLPROC(glUniform4f);
 		BF_GET_GLPROC(glUniformMatrix4fv);
 		BF_GET_GLPROC(glGetObjectParameterivARB);
 		BF_GET_GLPROC(glCompressedTexImage2D);
 		BF_GET_GLPROC(glClientActiveTexture);
-	
+
 #if !defined BF_PLATFORM_OPENGL_ES2
         BF_GET_GLPROC(glGetVertexAttribdv);
 #endif
     }
 
 	mSDLWindow = sdlWindow;
-	mRenderDevice = renderDevice;	
+	mRenderDevice = renderDevice;
 	Resized();
-	
-	//mGLSwapChain = NULL;
-	//mGLBackBuffer = NULL;
-	//mGLRenderTargetView = NULL;	
-
-	//mRenderDevice = renderDevice;
-	//mHWnd = hWnd;
-
-	//HRESULT hr = S_OK;	
-
-	//Resized();
-
-	//GLGI_SWAP_CHAIN_DESC swapChainDesc;
-	//ZeroMemory( &swapChainDesc, sizeof(swapChainDesc) );
-	//swapChainDesc.BufferCount = 1;
-	//swapChainDesc.BufferDesc.Width = mWidth;
-	//swapChainDesc.BufferDesc.Height = mHeight;
-	//swapChainDesc.BufferDesc.Format = GLGI_FORMAT_R8G8B8A8_UNORM;
-	//swapChainDesc.BufferUsage = GLGI_USAGE_RENDER_TARGET_OUTPUT;
-	//swapChainDesc.OutputWindow = mHWnd;
-	//swapChainDesc.SampleDesc.Count = 1;
-	//swapChainDesc.SampleDesc.Quality = 0;
-	//swapChainDesc.Windowed = TRUE;
-
-	////swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
-	////swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
-	////swapChainDesc.Flags = GLGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
-
- //   IGLGIDevice* pGLGIDevice = NULL;
- //   mRenderDevice->mGLDevice->QueryInterface(__uuidof(IGLGIDevice), (void**) &pGLGIDevice );
-
- //   GLCHECK(mRenderDevice->mGLGIFactory->CreateSwapChain(pGLGIDevice, &swapChainDesc, &mGLSwapChain));
- //   pGLGIDevice->Release();
- //   pGLGIDevice = NULL;
-	//
-	//GLCHECK(mGLSwapChain->GetBuffer(0, __uuidof(IGL10Texture2D), (LPVOID*)&mGLBackBuffer));	
-	//GLCHECK(mRenderDevice->mGLDevice->CreateRenderTargetView(mGLBackBuffer, NULL, &mGLRenderTargetView));		
+
+	//bf_glDebugMessageCallback(GL_DebugCallback, NULL);
 }
 
 GLRenderWindow::~GLRenderWindow()
-{	
-	/*if (mGLRenderTargetView != NULL)
-		mGLRenderTargetView->Release();
-		if (mGLBackBuffer != NULL)
-		mGLBackBuffer->Release();
-		if (mGLSwapChain != NULL)
-		mGLSwapChain->Release();	*/
+{
+
 }
 
 void GLRenderWindow::PhysSetAsTarget()
 {
 	GLfloat matrix[4][4];
 	CreateOrthographicOffCenter(0.0f, (float)mWidth, (float)mHeight, 0.0f, -100.0f, 100.0f, matrix);
-    
     glViewport(0, 0, (GLsizei)mWidth, (GLsizei)mHeight);
-    
-    //TODO: Set matrix variable
-	//glMatrixMode(GL_MODELVIEW);
-	//glLoadMatrixf((const GLfloat*)matrix);
 
-	
-
-    
-	//NOT_IMPL;
-	////if (mRenderDevice->mCurRenderTarget != this)
-	//{
-	//	GL10_VIEWPORT viewPort;
-	//	viewPort.Width = mWidth;
-	//	viewPort.Height = mHeight;
-	//	viewPort.MinDepth = 0.0f;
-	//	viewPort.MaxDepth = 1.0f;
-	//	viewPort.TopLeftX = 0;
-	//	viewPort.TopLeftY = 0;
-	//	
-	//	mRenderDevice->mGLDevice->OMSetRenderTargets(1, &mGLRenderTargetView, NULL);		
-	//	mRenderDevice->mGLDevice->RSSetViewports(1, &viewPort);
-	//}
-
-	//if (!mHasBeenDrawnTo)
-	//{		
-	//	//mRenderDevice->mGLDevice->ClearRenderTargetView(mGLRenderTargetView, D3GLVECTOR4(rand() / (float) RAND_MAX, 0, 1, 0));				
-	//	mRenderDevice->mGLDevice->ClearRenderTargetView(mGLRenderTargetView, D3GLVECTOR4(0, 0, 0, 0));				
-	//}
-
-	//mHasBeenDrawnTo = true;
+	mHasBeenDrawnTo = true;
 }
 
 void GLRenderWindow::SetAsTarget()
@@ -638,7 +492,7 @@ void GLRenderWindow::SetAsTarget()
 		//mRenderDevice->mCurDrawLayer->Flush();
 
 	mHasBeenTargeted = true;
-	mRenderDevice->mCurRenderTarget = this;	
+	mRenderDevice->mCurRenderTarget = this;
 }
 
 void GLRenderWindow::Resized()
@@ -654,20 +508,20 @@ void GLRenderWindow::Resized()
 		mGLRenderTargetView->Release();
 		mGLBackBuffer->Release();
 		GLCHECK(mGLSwapChain->ResizeBuffers(1, mWidth, mHeight, GLGI_FORMAT_R8G8B8A8_UNORM, 0));
-		
-		GLCHECK(mGLSwapChain->GetBuffer(0, __uuidof(IGL10Texture2D), (LPVOID*)&mGLBackBuffer));	
-		GLCHECK(mRenderDevice->mGLDevice->CreateRenderTargetView(mGLBackBuffer, NULL, &mGLRenderTargetView));		
+
+		GLCHECK(mGLSwapChain->GetBuffer(0, __uuidof(IGL10Texture2D), (LPVOID*)&mGLBackBuffer));
+		GLCHECK(mRenderDevice->mGLDevice->CreateRenderTargetView(mGLBackBuffer, NULL, &mGLRenderTargetView));
 	}*/
 }
 
 void GLRenderWindow::Present()
-{		
-	SDL_GL_SwapWindow(mSDLWindow);	
-	//GLCHECK(mGLSwapChain->Present((mWindow->mFlags & BFWINDOW_VSYNC) ? 1 : 0, 0));	
+{
+	SDL_GL_SwapWindow(mSDLWindow);
+	//GLCHECK(mGLSwapChain->Present((mWindow->mFlags & BFWINDOW_VSYNC) ? 1 : 0, 0));
 }
 
 void GLRenderWindow::CopyBitsTo(uint32* dest, int width, int height)
-{	
+{
 	mCurDrawLayer->Flush();
 
 	NOT_IMPL;
@@ -706,10 +560,12 @@ void GLRenderWindow::CopyBitsTo(uint32* dest, int width, int height)
 ///
 
 GLRenderDevice::GLRenderDevice()
-{	
+{
 	//mGLDevice = NULL;
+	mCurShader = NULL;
+	mGLVAO = 0;
 	mGLVertexBuffer = 0;
-	mGLIndexBuffer = 0;	
+	mGLIndexBuffer = 0;
 	mBlankTexture = 0;
     mFreeBatchHead = NULL;
 }
@@ -720,10 +576,27 @@ GLRenderDevice::~GLRenderDevice()
 
 bool GLRenderDevice::Init(BFApp* app)
 {
-	SdlBFApp* winApp = (SdlBFApp*) app;				
+	SdlBFApp* winApp = (SdlBFApp*) app;
+
+	//RenderState* glRenderState;
+	if (mDefaultRenderState == NULL)
+	{
+		auto dxRenderState = (RenderState*)CreateRenderState(NULL);
+
+		mDefaultRenderState = dxRenderState;
+		mDefaultRenderState->mDepthFunc = DepthFunc_Less;
+		mDefaultRenderState->mWriteDepthBuffer = true;
+
+		mPhysRenderState = mDefaultRenderState;
+	}
+	else
+	{
+		//glRenderState = (DXRenderState*)mDefaultRenderState;
+		//glRenderState->ReinitNative();
+	}
+
+	///
 
-	///	
-	
 	////Use GL10_CREATE_DEVICE_DEBUG for PIX
 	//GLCHECK(GL10CreateDevice(NULL, GL10_DRIVER_TYPE_HARDWARE, NULL, GL10_CREATE_DEVICE_DEBUG, GL10_SDK_VERSION, &mGLDevice));
 	////GLCHECK(GL10CreateDevice(NULL, GL10_DRIVER_TYPE_HARDWARE, NULL, 0, GL10_SDK_VERSION, &mGLDevice));
@@ -737,7 +610,7 @@ bool GLRenderDevice::Init(BFApp* app)
 	//IGLGIFactory* pGLGIFactory = NULL;
 	//GLCHECK(pGLGIAdapter->GetParent(__uuidof(IGLGIFactory), reinterpret_cast<void**>(&mGLGIFactory)));
 
-	////set rasterizer	
+	////set rasterizer
 	//GL10_RASTERIZER_DESC rasterizerState;
 	//rasterizerState.CullMode = GL10_CULL_NONE;
 	//rasterizerState.FillMode = GL10_FILL_SOLID;
@@ -751,10 +624,10 @@ bool GLRenderDevice::Init(BFApp* app)
 	//rasterizerState.MultisampleEnable = true;
  //   rasterizerState.AntialiasedLineEnable = true;
 	//
-	//mGLDevice->CreateRasterizerState( &rasterizerState, &mGLRasterizerStateClipped);	
+	//mGLDevice->CreateRasterizerState( &rasterizerState, &mGLRasterizerStateClipped);
 	//
 	//rasterizerState.ScissorEnable = false;
-	//mGLDevice->CreateRasterizerState( &rasterizerState, &mGLRasterizerStateUnclipped);	
+	//mGLDevice->CreateRasterizerState( &rasterizerState, &mGLRasterizerStateUnclipped);
 	//mGLDevice->RSSetState(mGLRasterizerStateUnclipped);
 	//
 	//IGL10BlendState* g_pBlendState = NULL;
@@ -782,192 +655,70 @@ bool GLRenderDevice::Init(BFApp* app)
 }
 
 void GLRenderDevice::FrameStart()
-{	
+{
 	mCurRenderTarget = NULL;
 	mPhysRenderWindow = NULL;
-	mPhysShader = NULL;
-	RenderWindowList::iterator itr = mRenderWindowList.begin();
-	while (itr != mRenderWindowList.end())
+
+	for (auto aRenderWindow : mRenderWindowList)
 	{
-		(*itr)->mHasBeenDrawnTo = false;
-		(*itr)->mHasBeenTargeted = false;
-		++itr;
-	}	
+		aRenderWindow->mHasBeenDrawnTo = false;
+		aRenderWindow->mHasBeenTargeted = false;
+	}
 }
 
 void GLRenderDevice::FrameEnd()
-{	
-	RenderWindowList::iterator itr = mRenderWindowList.begin();
-	while (itr != mRenderWindowList.end())
+{
+	for (auto aRenderWindow : mRenderWindowList)
 	{
-		RenderWindow* aRenderWindow = *itr;		
 		if (aRenderWindow->mHasBeenTargeted)
 		{
-			//aRenderWindow->mCurDrawLayer->Flush();
+			PhysSetRenderWindow(aRenderWindow);
+			PhysSetRenderState(mDefaultRenderState);
 
-			DrawLayerList::iterator drawLayerItr = aRenderWindow->mDrawLayerList.begin();
-			while (drawLayerItr != aRenderWindow->mDrawLayerList.end())
+			for (auto drawLayer : aRenderWindow->mDrawLayerList)
 			{
-				DrawLayer* drawLayer = *drawLayerItr;
 				drawLayer->Flush();
-				++drawLayerItr;
 			}
 
 			aRenderWindow->Present();
 		}
-		++itr;
 	}
 }
 
-Texture* GLRenderDevice::LoadTexture(ImageData* imageData, bool additive)
+Texture* GLRenderDevice::LoadTexture(ImageData* imageData, int flags)
 {
-	imageData->mIsAdditive = additive;	
+	imageData->mIsAdditive = (flags & TextureFlag_Additive) != 0;
 	imageData->PremultiplyAlpha();
 
 	//int w = power_of_two(imageData->mWidth);
 	//int h = power_of_two(imageData->mHeight);
-
-	if (mBlankTexture == 0)
-	{
-		glGenTextures(1, &mBlankTexture);
-		glBindTexture(GL_TEXTURE_2D, mBlankTexture);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-        /*if (bf_glCompressedTexImage2D != NULL)
-        {
-            uint64 hwData = 0;
-            bf_glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 4, 4, 0,
-                                      sizeof(hwData), (uint8*)&hwData);
-        }
-        else*/
-        {
-            uint16 color = 0;
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
-                         GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &color);
-        }
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-	}
-
 	GLTexture* glTexture = new GLTexture();
-	glTexture->mGLTexture2 = mBlankTexture;
-
-	int texCount = 0;
-	texCount = (imageData->mHWBitsType == HWBITS_PVRTC_2X4BPPV1) ? 2 : 1;
-    
-	for (int texNum = 0; texNum < 2/*texCount*/; texNum++)
-	{
-		GLuint glTextureID;
-		glGenTextures(1, &glTextureID);
-		glBindTexture(GL_TEXTURE_2D, glTextureID);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    
-		if (imageData->mHWBits != NULL)
-		{
-			int internalFormat = (imageData->mHWBitsType == HWBITS_PVRTC_2BPPV1) ?
-				GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG :
-				GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
-
-			int texSize = imageData->mHWBitsLength / texCount;
-
-			bf_glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageData->mWidth, imageData->mHeight, 0,
-				texSize, (uint8*)imageData->mHWBits /*+ (texNum * texSize)*/);
-		}
-		else
-		{
-			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageData->mWidth, imageData->mHeight, 0,
-				GL_RGBA, GL_UNSIGNED_BYTE, imageData->mBits);
-		}
-
-		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
-		if (texNum == 0)
-			glTexture->mGLTexture = glTextureID;
-		else
-			glTexture->mGLTexture2 = glTextureID;
-	}
-
+	glTexture->mRenderDevice = this;
 	glTexture->mWidth = imageData->mWidth;
 	glTexture->mHeight = imageData->mHeight;
-	glTexture->AddRef();
+	glTexture->mImageData = imageData;
+	imageData->AddRef();
 
 	return glTexture;
-
-	//IGL10ShaderResourceView* d3DShaderResourceView = NULL;
-
-	//imageData->PremultiplyAlpha();
-
-	//int aWidth = 0;
-	//int aHeight = 0;
-	//
-	//// Create the render target texture
-	//GL10_TEXTURE2D_DESC desc;
-	//ZeroMemory(&desc, sizeof(desc));
-	//desc.Width = imageData->mWidth;
-	//desc.Height = imageData->mHeight;
-	//desc.MipLevels = 1;
-	//desc.ArraySize = 1;
-	//desc.Format = GLGI_FORMAT_R8G8B8A8_UNORM;
-	//desc.SampleDesc.Count = 1;
-	//desc.Usage = GL10_USAGE_DYNAMIC;
-	//desc.CPUAccessFlags = GL10_CPU_ACCESS_WRITE;
-	//desc.BindFlags = GL10_BIND_SHADER_RESOURCE;
-
-	//IGL10Texture2D* d3DTexture = NULL;
-	//GLCHECK(mGLDevice->CreateTexture2D(&desc, NULL, &d3DTexture));
-
-	//aWidth = imageData->mWidth;
-	//aHeight = imageData->mHeight;
-
-	//GL10_MAPPED_TEXTURE2D mapTex;
-	//GLCHECK(d3DTexture->Map(GL10CalcSubresource(0, 0, 1), GL10_MAP_WRITE_DISCARD, 0, &mapTex));
-	//uint8* destPtr = (uint8*) mapTex.pData;
-	//uint8* srcPtr = (uint8*) imageData->mBits;
-	//for (int y = 0; y < imageData->mHeight; y++)
-	//{
-	//	memcpy(destPtr, srcPtr, aWidth*sizeof(uint32));
-	//	srcPtr += aWidth*sizeof(uint32);
-	//	destPtr += mapTex.RowPitch;
-	//}
-	//d3DTexture->Unmap(0);			
-
-	//GL10_SHADER_RESOURCE_VIEW_DESC srDesc;
-	//srDesc.Format = desc.Format;
-	//srDesc.ViewDimension = GL10_SRV_DIMENSION_TEXTURE2D;
-	//srDesc.Texture2D.MostDetailedMip = 0;
-	//srDesc.Texture2D.MipLevels = 1;	
-	//	
-	//GLCHECK(mGLDevice->CreateShaderResourceView(d3DTexture, &srDesc, &d3DShaderResourceView));
-
-	//GLTexture* aTexture = new GLTexture();
-	//aTexture->mWidth = aWidth;
-	//aTexture->mHeight = aHeight;
-	//aTexture->mGLTexture = d3DShaderResourceView;
-	//aTexture->AddRef();
-	//return aTexture;
 }
 
-Shader* GLRenderDevice::LoadShader(const StringImpl& fileName)
+Shader* GLRenderDevice::LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition)
 {
 	GLShader* glShader = new GLShader();
 
+	glShader->mVertexSize = sizeof(GLVertex3D);
 	glShader->mGLVertexShader = bf_glCreateShader(GL_VERTEX_SHADER);
 	glShader->mGLFragmentShader = bf_glCreateShader(GL_FRAGMENT_SHADER);
-    
+
 	GLint vertProgramLen = 0;
 	GLint fragProgramLen = 0;
-    
+
 #ifdef BF_PLATFORM_OPENGL_ES2
-	GLchar* vertProgram = (GLchar*)LoadBinaryData(fileName + L"_es.vert", &vertProgramLen);
-	GLchar* fragProgram = (GLchar*)LoadBinaryData(fileName + L"_es.frag", &fragProgramLen);
+	GLchar* vertProgram = (GLchar*)LoadBinaryData(fileName + "_es.vert", &vertProgramLen);
+	GLchar* fragProgram = (GLchar*)LoadBinaryData(fileName + "_es.frag", &fragProgramLen);
 #else
-	GLchar* vertProgram = (GLchar*)LoadBinaryData(fileName + L".vert", &vertProgramLen);
-	GLchar* fragProgram = (GLchar*)LoadBinaryData(fileName + L".frag", &fragProgramLen);
+	GLchar* vertProgram = (GLchar*)LoadBinaryData(fileName + ".vert", &vertProgramLen);
+	GLchar* fragProgram = (GLchar*)LoadBinaryData(fileName + ".frag", &fragProgramLen);
 #endif
 
 	if ((vertProgram == NULL) || (fragProgram == NULL))
@@ -979,17 +730,17 @@ Shader* GLRenderDevice::LoadShader(const StringImpl& fileName)
 
 	int infoLogLen = 0;
 	char infoLog[2048];
-		
+
 	bf_glShaderSource(glShader->mGLVertexShader, 1, (const GLchar**)&vertProgram, &vertProgramLen);
 	bf_glCompileShader(glShader->mGLVertexShader);
 	bf_glGetShaderInfoLog(glShader->mGLVertexShader, 2048, &infoLogLen, infoLog);
 	GLint compiled = 0;
-    
+
 	//bf_glGetObjectParameterivARB(glShader->mGLVertexShader, GL_COMPILE_STATUS, &compiled);
     bf_glGetShaderiv(glShader->mGLVertexShader, GL_COMPILE_STATUS, &compiled);
 	if (!compiled)
 		BF_FATAL(StrFormat("Shader error: %s", infoLog).c_str());
-	
+
 	bf_glShaderSource(glShader->mGLFragmentShader, 1, (const GLchar**)&fragProgram, &fragProgramLen);
 	bf_glCompileShader(glShader->mGLFragmentShader);
 	bf_glGetShaderInfoLog(glShader->mGLFragmentShader, 2048, &infoLogLen, infoLog);
@@ -1004,121 +755,155 @@ Shader* GLRenderDevice::LoadShader(const StringImpl& fileName)
 	bf_glAttachShader(glShader->mGLProgram, glShader->mGLFragmentShader);
 
 	bf_glLinkProgram(glShader->mGLProgram);
-	bf_glUseProgram(glShader->mGLProgram);
-	
-	glShader->mAttribPosition = bf_glGetAttribLocation(glShader->mGLProgram, "position");	
-	glShader->mAttribTexCoord0 = bf_glGetAttribLocation(glShader->mGLProgram, "texCoord0");	
-	glShader->mAttribColor = bf_glGetAttribLocation(glShader->mGLProgram, "color");	
-	glShader->mAttribTex0 = bf_glGetUniformLocation(glShader->mGLProgram, "tex");	
-	glShader->mAttribTex1 = bf_glGetUniformLocation(glShader->mGLProgram, "tex2");	
-
-	if (glShader->mAttribPosition >= 0)
-		bf_glEnableVertexAttribArray(glShader->mAttribPosition);
-	if (glShader->mAttribTexCoord0 >= 0)
-		bf_glEnableVertexAttribArray(glShader->mAttribTexCoord0);
-	if (glShader->mAttribColor >= 0)
-		bf_glEnableVertexAttribArray(glShader->mAttribColor);
+
+	glShader->mAttribPosition = bf_glGetAttribLocation(glShader->mGLProgram, "position");
+	glShader->mAttribTexCoord0 = bf_glGetAttribLocation(glShader->mGLProgram, "texCoord0");
+	glShader->mAttribColor = bf_glGetAttribLocation(glShader->mGLProgram, "color");
+	glShader->mAttribTex0 = bf_glGetUniformLocation(glShader->mGLProgram, "tex");
+	glShader->mAttribTex1 = bf_glGetUniformLocation(glShader->mGLProgram, "tex2");
 
 	return glShader;
 }
 
-void GLRenderDevice::SetShader(Shader* shader)
+void GLRenderDevice::PhysSetRenderState(RenderState* renderState)
 {
-	mShaderChanged = true;
-	mCurShader = shader;
-}
+	mCurShader = (GLShader*)renderState->mShader;
+	if (mCurShader != NULL)
+	{
+		bf_glUseProgram(mCurShader->mGLProgram);
 
-void GLRenderDevice::PhysSetAdditive(bool additive)
-{
-	if (additive)		
-		glBlendFunc(GL_SRC_ALPHA, GL_ONE);	
+		GLRenderDevice* aRenderDevice = (GLRenderDevice*)gBFApp->mRenderDevice;
+
+		//TODO: Cache more
+
+		GLfloat matrix[4][4];
+		CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix);
+		GLint matrixLoc = bf_glGetUniformLocation(mCurShader->mGLProgram, "screenMatrix");
+		//BF_ASSERT(matrixLoc >= 0);
+		if (matrixLoc >= 0)
+			bf_glUniformMatrix4fv(matrixLoc, 1, false, (float*)matrix);
+	}
+
+	if (renderState->mClipped)
+	{
+		glEnable(GL_SCISSOR_TEST);
+ 		glScissor((GLsizei)renderState->mClipRect.mX,
+			mPhysRenderWindow->mHeight - (GLsizei)renderState->mClipRect.mY - (GLsizei)renderState->mClipRect.mHeight,
+ 			(GLsizei)renderState->mClipRect.mWidth, (GLsizei)renderState->mClipRect.mHeight);
+	}
 	else
-		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);	
-	mCurAdditive = additive;
+	{
+		glDisable(GL_SCISSOR_TEST);
+	}
+
+	mPhysRenderState = renderState;
 }
 
-void GLRenderDevice::SetClip(float x, float y, float width, float height)
+Texture* GLRenderDevice::CreateRenderTarget(int width, int height, bool destAlpha)
 {
-	//TODO: Store state in draw batcher
-	mCurDrawLayer->Flush();
-	
 	NOT_IMPL;
-
-	/*GL10_RECT rects[1];
-	rects[0].left = (int) x;
-	rects[0].right = (int) (x + width);
-	rects[0].top = (int) y;
-	rects[0].bottom = (int) (y + height);
-
-	mGLDevice->RSSetScissorRects(1, rects);
-	mGLDevice->RSSetState(mGLRasterizerStateClipped);*/
 }
 
-void GLRenderDevice::DisableClip()
+void GLRenderDevice::SetRenderState(RenderState* renderState)
 {
-	mCurDrawLayer->Flush();
-	NOT_IMPL;
-	//mGLDevice->RSSetState(mGLRasterizerStateUnclipped);
+	mCurRenderState = renderState;
 }
 
-Texture* GLRenderDevice::CreateRenderTarget(int width, int height, bool destAlpha)
+
+void GLSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWindow)
 {
-	NOT_IMPL;
+/*#ifdef BF_PLATFORM_OPENGL_ES2
+	//bf_glClientActiveTexture(GL_TEXTURE0);
+	glActiveTexture(GL_TEXTURE0);
+	glBindTexture(GL_TEXTURE_2D, ((GLTexture*)mTexture)->mGLTexture);
+	glUniform1i(curShader->mAttribTex0, 0);
 
-	//IGL10ShaderResourceView* d3DShaderResourceView = NULL;
-	//
-	//int aWidth = 0;
-	//int aHeight = 0;
-	//
-	//// Create the render target texture
-	//GL10_TEXTURE2D_DESC desc;
-	//ZeroMemory(&desc, sizeof(desc));
-	//desc.Width = width;
-	//desc.Height = height;
-	//desc.MipLevels = 1;
-	//desc.ArraySize = 1;
-	//desc.Format = GLGI_FORMAT_R8G8B8A8_UNORM;
-	//desc.SampleDesc.Count = 1;	
-	//UINT qualityLevels = 0;
-
-	//int samples = 1;
-	//GLCHECK(mGLDevice->CheckMultisampleQualityLevels(GLGI_FORMAT_R8G8B8A8_UNORM, samples, &qualityLevels));
-
-	//desc.SampleDesc.Count = samples;
-	//desc.SampleDesc.Quality = qualityLevels-1;
-
-	//desc.Usage = GL10_USAGE_DEFAULT;
-	//desc.CPUAccessFlags = 0; //GL10_CPU_ACCESS_WRITE;
-	//desc.BindFlags = GL10_BIND_SHADER_RESOURCE | GL10_BIND_RENDER_TARGET;
-
-	//IGL10Texture2D* d3DTexture = NULL;
-	//GLCHECK(mGLDevice->CreateTexture2D(&desc, NULL, &d3DTexture));
-
-	//aWidth = width;
-	//aHeight = height;
-
-	//GL10_SHADER_RESOURCE_VIEW_DESC srDesc;
-	//srDesc.Format = desc.Format;
-	//srDesc.ViewDimension = GL10_SRV_DIMENSION_TEXTURE2D;
-	//srDesc.Texture2D.MostDetailedMip = 0;
-	//srDesc.Texture2D.MipLevels = 1;	
-	//
-	//if (qualityLevels != 0)
-	//{
-	//	srDesc.ViewDimension = GL10_SRV_DIMENSION_TEXTURE2DMS;
-	//}
+	//bf_glClientActiveTexture(GL_TEXTURE1);
 
-	//GLCHECK(mGLDevice->CreateShaderResourceView(d3DTexture, &srDesc, &d3DShaderResourceView));
-	//
-	//IGL10RenderTargetView*	d3DRenderTargetView;	
-	//GLCHECK(mGLDevice->CreateRenderTargetView(d3DTexture, NULL, &d3DRenderTargetView));
-
-	//GLTexture* aRenderTarget = new GLTexture();
-	//aRenderTarget->mWidth = width;
-	//aRenderTarget->mHeight = height;
-	//aRenderTarget->mRenderDevice = this;
-	//aRenderTarget->mGLTexture = d3DShaderResourceView;
-	//aRenderTarget->mGLRenderTargetView = d3DRenderTargetView;
-	//aRenderTarget->AddRef();
-	//return aRenderTarget;	
+	glActiveTexture(GL_TEXTURE1);
+	glBindTexture(GL_TEXTURE_2D, ((GLTexture*)mTexture)->mGLTexture2);
+	glUniform1i(curShader->mAttribTex1, 1);
+
+	//glEnable(GL_TEXTURE_2D);
+#else
+	glActiveTexture(GL_TEXTURE0 + mTextureIdx);
+	glBindTexture(GL_TEXTURE_2D, ((GLTexture*)mTexture)->mGLTexture);
+#endif*/
+
+	auto glTexture = (GLTexture*)mTexture;
+	auto glRenderDevice = (GLRenderDevice*)renderDevice;
+
+	if (glRenderDevice->mBlankTexture == 0)
+	{
+		glGenTextures(1, &glRenderDevice->mBlankTexture);
+		glBindTexture(GL_TEXTURE_2D, glRenderDevice->mBlankTexture);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+		/*if (bf_glCompressedTexImage2D != NULL)
+		{
+			uint64 hwData = 0;
+			bf_glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 4, 4, 0,
+									  sizeof(hwData), (uint8*)&hwData);
+		}
+		else*/
+		{
+			uint16 color = 0;
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
+				GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &color);
+		}
+		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+	}
+
+	if (glTexture->mImageData != NULL)
+	{
+		glTexture->mGLTexture2 = glRenderDevice->mBlankTexture;
+
+		int texCount = 1;
+		//texCount = (imageData->mHWBitsType == HWBITS_PVRTC_2X4BPPV1) ? 2 : 1;
+
+		for (int texNum = 0; texNum < 2/*texCount*/; texNum++)
+		{
+			GLuint glTextureID;
+			glGenTextures(1, &glTextureID);
+			glBindTexture(GL_TEXTURE_2D, glTextureID);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+			//if (imageData->mHWBits != NULL)
+			//{
+			//	int internalFormat = (imageData->mHWBitsType == HWBITS_PVRTC_2BPPV1) ?
+			//		GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG :
+			//		GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
+
+			//	int texSize = imageData->mHWBitsLength / texCount;
+
+			//	bf_glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageData->mWidth, imageData->mHeight, 0,
+			//		texSize, (uint8*)imageData->mHWBits /*+ (texNum * texSize)*/);
+			//}
+			//else
+			{
+				glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glTexture->mImageData->mWidth, glTexture->mImageData->mHeight, 0,
+					GL_RGBA, GL_UNSIGNED_BYTE, glTexture->mImageData->mBits);
+			}
+
+			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+			if (texNum == 0)
+				glTexture->mGLTexture = glTextureID;
+			else
+				glTexture->mGLTexture2 = glTextureID;
+		}
+
+		glTexture->mImageData->Deref();
+		glTexture->mImageData = NULL;
+	}
+
+	bf_glActiveTexture(GL_TEXTURE0 + mTextureIdx);
+	//glUniform1i(curShader->mAttribTex0, 0);
+	glBindTexture(GL_TEXTURE_2D, glTexture->mGLTexture);
 }

+ 39 - 19
BeefySysLib/platform/sdl/GLRenderDevice.h

@@ -1,11 +1,12 @@
 #pragma once
 
 #include "Common.h"
+#include "util/Dictionary.h"
 
 #ifdef BF_PLATFORM_OPENGL_ES2
-#include "SDL_opengles2.h"
+#include <SDL2/SDL_opengles2.h>
 #else
-#include "SDL_opengl.h"
+#include <SDL2/SDL_opengl.h>
 #endif
 
 #include "gfx/Shader.h"
@@ -26,6 +27,7 @@ public:
 	GLRenderDevice*			mRenderDevice;
 	GLuint					mGLTexture;
 	GLuint					mGLTexture2;
+	ImageData*				mImageData;
 	//IGL10RenderTargetView*	mGLRenderTargetView;
 
 public:
@@ -33,6 +35,7 @@ public:
 	~GLTexture();
 
 	virtual void			PhysSetAsTarget();
+	virtual void			Blt(ImageData* imageData, int x, int y) override;
 };
 
 class GLShaderParam : public ShaderParam
@@ -48,7 +51,7 @@ public:
 	virtual void			SetFloat4(float x, float y, float z, float w) override;
 };
 
-typedef std::map<String, GLShaderParam*> GLShaderParamMap;
+typedef Dictionary<String, GLShaderParam*> GLShaderParamMap;
 
 class GLShader : public Shader
 {
@@ -63,35 +66,46 @@ public:
 	GLint mAttribColor;
 	GLint mAttribTex0;
 	GLint mAttribTex1;
-	
-	GLShaderParamMap		mParamsMap;	
+
+	GLShaderParamMap		mParamsMap;
 
 public:
 	GLShader();
 	~GLShader();
-	
+
 	virtual ShaderParam*	GetShaderParam(const StringImpl& name) override;
 };
 
+class GLSetTextureCmd : public RenderCmd
+{
+public:
+	int						mTextureIdx;
+	Texture*				mTexture;
+
+public:
+	virtual void Render(RenderDevice* renderDevice, RenderWindow* renderWindow) override;
+};
+
+
 class GLDrawBatch : public DrawBatch
 {
 public:
 	//IGL10Buffer*			mGLBuffer;
 
 public:
-	GLDrawBatch(int minVtxSize = 0, int minIdxSize = 0);
+	GLDrawBatch();
 	~GLDrawBatch();
 
-	virtual void			Lock();
-	virtual void			Draw();
+	//virtual void			Lock();
+	virtual void			Render(RenderDevice* renderDevice, RenderWindow* renderWindow) override;
 };
 
 class GLDrawLayer : public DrawLayer
 {
 public:
 	virtual DrawBatch*		CreateDrawBatch();
-	virtual DrawBatch*		AllocateBatch(int minVtxCount, int minIdxCount) override;
-	virtual void			FreeBatch(DrawBatch* drawBatch) override;
+	virtual RenderCmd*		CreateSetTextureCmd(int textureIdx, Texture* texture) override;
+	virtual void			SetShaderConstantData(int usageIdx, int slotIdx, void* constData, int size) override;
 
 public:
 	GLDrawLayer();
@@ -108,7 +122,7 @@ public:
 	//IGL10RenderTargetView*	mGLRenderTargetView;
 	bool					mResizePending;
 	int						mPendingWidth;
-	int						mPendingHeight;		
+	int						mPendingHeight;
 
 public:
 	virtual void			PhysSetAsTarget();
@@ -136,9 +150,11 @@ public:
 	//IGL10RasterizerState*	mGLRasterizerStateClipped;
 	//IGL10RasterizerState*	mGLRasterizerStateUnclipped;
 
+	GLuint					mGLVAO;
 	GLuint					mGLVertexBuffer;
 	GLuint					mGLIndexBuffer;
 	GLuint					mBlankTexture;
+	GLShader*				mCurShader;
 
 	bool					mHasVSync;
 
@@ -146,10 +162,11 @@ public:
     GLDrawBatch*            mFreeBatchHead;
 
 public:
-	virtual void			PhysSetAdditive(bool additive);
-	virtual void			PhysSetShader(Shader* shaderPass);
+	//virtual void			PhysSetAdditive(bool additive);
+	//virtual void			PhysSetShader(Shader* shaderPass);
 	virtual void			PhysSetRenderWindow(RenderWindow* renderWindow);
-	virtual void			PhysSetRenderTarget(Texture* renderTarget);
+	virtual void			PhysSetRenderState(RenderState* renderState) override;
+	virtual void			PhysSetRenderTarget(Texture* renderTarget) override;
 
 public:
 	GLRenderDevice();
@@ -159,13 +176,16 @@ public:
 	void					FrameStart() override;
 	void					FrameEnd() override;
 
-	Texture*				LoadTexture(ImageData* imageData, bool additive) override;
-	Shader*					LoadShader(const StringImpl& fileName) override;
+	Texture*				LoadTexture(ImageData* imageData, int flags) override;
+	Shader*					LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition) override;
 	Texture*				CreateRenderTarget(int width, int height, bool destAlpha) override;
 
-	void					SetShader(Shader* shader) override;
+	virtual Texture*		CreateDynTexture(int width, int height) override { return NULL; }
+	virtual void			SetRenderState(RenderState* renderState) override;
+
+	/*void					SetShader(Shader* shader) override;
 	virtual void			SetClip(float x, float y, float width, float height) override;
-	virtual void			DisableClip() override;
+	virtual void			DisableClip() override;*/
 };
 
 NS_BF_END;

+ 66 - 404
BeefySysLib/platform/sdl/SdlBFApp.cpp

@@ -1,6 +1,7 @@
 #include "SdlBFApp.h"
 #include "GLRenderDevice.h"
-#include "SDL.h"
+#include "platform/PlatformHelper.h"
+#include <SDL2/SDL.h>
 
 USING_NS_BF;
 
@@ -9,6 +10,7 @@ USING_NS_BF;
 #pragma comment(lib, "imm32.lib")
 #pragma comment(lib, "version.lib")
 
+
 SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
 {
 	int sdlWindowFlags = 0;
@@ -19,362 +21,55 @@ SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
 #ifdef BF_PLATFORM_FULLSCREEN
     sdlWindowFlags |= SDL_WINDOW_FULLSCREEN;
 #endif
-    
+
 	mSDLWindow = SDL_CreateWindow(title.c_str(), x, y, width, height, sdlWindowFlags);
-	
-	if (!SDL_GL_CreateContext(mSDLWindow)) 
+
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+
+	if (!SDL_GL_CreateContext(mSDLWindow))
 	{
-		BF_FATAL(StrFormat("Unable to create OpenGL context: %s", SDL_GetError()).c_str());		
+		BF_FATAL(StrFormat("Unable to create OpenGL context: %s", SDL_GetError()).c_str());
 		SDL_Quit();
 		exit(2);
 	}
 
+	glEnable(GL_DEBUG_OUTPUT);
+	glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+
 	glEnable(GL_BLEND);
-	//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-	//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 #ifndef BF_PLATFORM_OPENGL_ES2
-	glEnableClientState(GL_INDEX_ARRAY);
+	//glEnableClientState(GL_INDEX_ARRAY);
 #endif
 
-	//glEnableClientState(GL_VERTEX_ARRAY);
-	//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	//glEnableClientState(GL_COLOR_ARRAY); 
-    
 	mIsMouseInside = false;
 	mRenderWindow = new GLRenderWindow((GLRenderDevice*)gBFApp->mRenderDevice, mSDLWindow);
 	mRenderWindow->mWindow = this;
 	gBFApp->mRenderDevice->AddRenderWindow(mRenderWindow);
 
-	if (parent != NULL)	
-		parent->mChildren.push_back(this);	
+	if (parent != NULL)
+		parent->mChildren.push_back(this);
 }
 
 SdlBFWindow::~SdlBFWindow()
-{	
+{
 	if (mSDLWindow != NULL)
 		TryClose();
 }
 
 bool SdlBFWindow::TryClose()
-{	
+{
 	SdlBFApp* app = (SdlBFApp*)gBFApp;
-	SdlWindowMap::iterator itr = app->mSdlWindowMap.find(SDL_GetWindowID(mSDLWindow));
-	app->mSdlWindowMap.erase(itr);
-	
+	app->mSdlWindowMap.Remove(SDL_GetWindowID(mSDLWindow));
+
 	SDL_DestroyWindow(mSDLWindow);
 	mSDLWindow = NULL;
 	return true;
 }
 
-//LRESULT SdlBFWindow::WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-//{	
-//	SdlBFApp* app = (SdlBFApp*) gBFApp;
-//
-//	switch (Msg)
-//	{
-//	case WM_CLOSE:
-//		{
-//			if (mCloseQueryFunc(this) != 0)
-//				gBFApp->RemoveWindow(this);
-//			return 0;
-//		}
-//		break;
-//	case WM_DESTROY:
-//		/*if (mFlags & BFWINDOW_QUIT_ON_CLOSE)
-//		{
-//			gBFApp->mRunning = false;				
-//		}*/
-//		mHWnd = NULL;
-//		break;	
-//	}
-//
-//	LRESULT result = 0;
-//	bool doResult = false;
-//
-//	if (!app->mInMsgProc)
-//	{
-//		app->mInMsgProc = true;
-//
-//		switch (Msg)
-//		{
-//		
-//		case WM_SIZE:
-//			mRenderWindow->Resized();
-//			if (mMovedFunc != NULL)
-//				mMovedFunc(this);
-//			break;
-//		case WM_PAINT:						
-//			break;
-//		case WM_LBUTTONDOWN:		
-//		case WM_RBUTTONDOWN:
-//		case WM_MBUTTONDOWN:
-//		case WM_LBUTTONDBLCLK:
-//		case WM_RBUTTONDBLCLK:
-//		case WM_LBUTTONUP:		
-//		case WM_RBUTTONUP:		
-//		case WM_MBUTTONUP:
-//		case WM_MOUSEWHEEL:
-//		case WM_MOUSEMOVE:	
-//			{
-//				int x = (short) LOWORD(lParam);
-//				int y = (short) HIWORD(lParam);
-//
-//				bool releaseCapture = false;
-//
-//				POINT point = {x, y};
-//				::ClientToScreen(hWnd, &point);
-//				HWND windowAtPoint = ::WindowFromPoint(point);
-//
-//				bool isMouseOver = windowAtPoint == hWnd;
-//
-//				if ((!mIsMouseInside) && (isMouseOver))
-//				{
-//					TRACKMOUSEEVENT tme;
-//					tme.cbSize = sizeof(TRACKMOUSEEVENT);
-//					tme.dwFlags = TME_LEAVE;
-//					tme.hwndTrack = hWnd;
-//					TrackMouseEvent(&tme);
-//					mIsMouseInside = true;
-//				}
-//
-//				if ((mIsMouseInside) && (!isMouseOver))
-//				{
-//					mIsMouseInside = false;
-//					mMouseLeaveFunc(this);
-//				}
-//
-//				switch (Msg)
-//				{
-//				case WM_LBUTTONDOWN:
-//					SetCapture(hWnd);
-//					mMouseDownFunc(this, x, y, 0, 1);
-//					break;
-//				case WM_RBUTTONDOWN:
-//					SetCapture(hWnd);
-//					mMouseDownFunc(this, x, y, 1, 1);						
-//					break;
-//				case WM_MBUTTONDOWN:
-//					SetCapture(hWnd);
-//					mMouseDownFunc(this, x, y, 2, 1);						
-//					break;
-//				case WM_LBUTTONDBLCLK:
-//					SetCapture(hWnd);
-//					mMouseDownFunc(this, x, y, 0, 2);
-//					break;
-//				case WM_RBUTTONDBLCLK:
-//					SetCapture(hWnd);
-//					mMouseDownFunc(this, x, y, 1, 2);
-//					break;
-//				case WM_MBUTTONDBLCLK:
-//					SetCapture(hWnd);
-//					mMouseDownFunc(this, x, y, 2, 2);
-//					break;
-//				case WM_LBUTTONUP:
-//					releaseCapture = true;					
-//					mMouseUpFunc(this, x, y, 0);
-//					break;
-//				case WM_RBUTTONUP:							
-//					releaseCapture = true;
-//					mMouseUpFunc(this, x, y, 1);
-//					break;
-//				case WM_MBUTTONUP:							
-//					releaseCapture = true;
-//					mMouseUpFunc(this, x, y, 2);
-//					break;			
-//				case WM_MOUSEWHEEL:
-//					{
-//						POINT pt = {x, y};
-//						ScreenToClient(mHWnd, &pt);
-//
-//						int delta = ((int16)HIWORD(wParam)) / 120;
-//						mMouseWheelFunc(this, pt.x, pt.y, delta);
-//					}
-//					break;
-//				case WM_MOUSEMOVE:
-//					{
-//						mMouseMoveFunc(this, x, y);
-//						
-//						if ((wParam != 0) && (gBFApp->mWindowList.size() > 1))
-//						{
-//							// See if our mouse is down and has entered into another window's space
-//							POINT point = {x, y};
-//							::ClientToScreen(hWnd, &point);
-//
-//							HWND windowAtPoint = ::WindowFromPoint(point);
-//
-//							BFWindowList::iterator itr = gBFApp->mWindowList.begin();
-//							while (itr != gBFApp->mWindowList.end())
-//							{
-//								SdlBFWindow* aWindow = (SdlBFWindow*) *itr;
-//								if (aWindow != this)
-//								{
-//									if (aWindow->mHWnd == windowAtPoint)
-//									{
-//										POINT clientPt = point;
-//										::ScreenToClient(aWindow->mHWnd, &clientPt);
-//										aWindow->mMouseProxyMoveFunc(this, clientPt.x, clientPt.y);
-//										aWindow->mIsMouseInside = true;
-//									}
-//									else if (aWindow->mIsMouseInside)
-//									{
-//										aWindow->mMouseLeaveFunc(this);
-//										aWindow->mIsMouseInside = false;
-//									}
-//								}
-//								++itr;
-//							}
-//						}						
-//					}
-//					break;
-//				}
-//
-//				if (releaseCapture)
-//				{
-//					ReleaseCapture();
-//
-//					BFWindowList::iterator itr = gBFApp->mWindowList.begin();
-//					while (itr != gBFApp->mWindowList.end())
-//					{
-//						SdlBFWindow* aWindow = (SdlBFWindow*) *itr;
-//						if ((aWindow != this) && (aWindow->mIsMouseInside))
-//						{
-//							aWindow->mMouseLeaveFunc(this);
-//							aWindow->mIsMouseInside = false;
-//						}
-//						++itr;
-//					}
-//				}
-//			}	
-//			break;
-//		
-//		case WM_COMMAND:
-//			{
-//				SdlBFMenu* aMenu = mMenuIDMap[(uint32)wParam];
-//				if (aMenu != NULL)
-//					mMenuItemSelectedFunc(this, aMenu);
-//			}
-//			break;
-//		case WM_INITMENUPOPUP:
-//			{
-//				HMENU hMenu = (HMENU) wParam;
-//				SdlBFMenu* aMenu = mHMenuMap[hMenu];
-//				if (aMenu != NULL)
-//					mMenuItemSelectedFunc(this, aMenu);
-//			}
-//			break;
-//
-//		case WM_MOUSEACTIVATE:
-//			if (mFlags & BFWINDOW_NO_MOUSE_ACTIVATE)
-//			{
-//				doResult = true;
-//				result = MA_NOACTIVATE;
-//			}
-//			break;
-//
-//		case WM_KILLFOCUS:
-//			mLostFocusFunc(this);
-//			break;
-//		case WM_SETFOCUS:
-//			mGotFocusFunc(this);
-//			break;
-//		case WM_MOUSELEAVE:			
-//			mIsMouseInside = false;
-//			mMouseLeaveFunc(this);
-//			break;
-//
-//		case WM_CHAR:
-//			mKeyCharFunc(this, (WCHAR)wParam);
-//			break;
-//		case WM_SYSKEYDOWN:
-//		case WM_KEYDOWN:
-//			{
-//				int keyCode = (int) wParam;
-//				mIsKeyDown[keyCode] = true;
-//
-//				WinMenuIDMap::iterator itr = mMenuIDMap.begin();
-//				while (itr != mMenuIDMap.end())
-//				{
-//					SdlBFMenu* aMenu = itr->second;
-//					if ((aMenu->mKeyCode == keyCode) &&
-//						(aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) &&
-//						(aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) &&
-//						(aMenu->mKeyAlt == mIsKeyDown[VK_MENU]))
-//					{
-//						mMenuItemSelectedFunc(this, aMenu);
-//						doResult = true;			
-//						break;
-//					}
-//					++itr;
-//				}
-//				mKeyDownFunc(this, (int) wParam, (lParam & 0x7FFF) != 0);
-//			}
-//			break;		
-//		case WM_SYSCHAR:
-//			{
-//				int keyCode = toupper((int) wParam);
-//
-//				WinMenuIDMap::iterator itr = mMenuIDMap.begin();
-//				while (itr != mMenuIDMap.end())
-//				{
-//					SdlBFMenu* aMenu = itr->second;
-//					if ((aMenu->mKeyCode == keyCode) &&
-//						(aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) &&
-//						(aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) &&
-//						(aMenu->mKeyAlt == mIsKeyDown[VK_MENU]))
-//					{						
-//						doResult = true;			
-//						break;
-//					}
-//					++itr;
-//				}
-//			}
-//			break;
-//		case WM_SYSKEYUP:
-//		case WM_KEYUP:
-//			{
-//				int keyCode = (int) wParam;
-//				if (mIsKeyDown[keyCode])
-//				{
-//					mKeyUpFunc(this, (int) wParam);
-//					mIsKeyDown[keyCode] = false;
-//				}
-//			}
-//			break;
-//
-//		case WM_TIMER:
-//			if (gBFApp->mSysDialogCnt == 0)
-//				gBFApp->Process();
-//			break;
-//
-//		case WM_SETCURSOR:
-//			gBFApp->PhysSetCursor();
-//			break;
-//
-//		case WM_MOVING:
-//			if (mMovedFunc != NULL)
-//				mMovedFunc(this);
-//			break;
-//		case WM_SIZING:
-//			mRenderWindow->Resized();
-//			if (mMovedFunc != NULL)
-//				mMovedFunc(this);
-//			if (gBFApp->mSysDialogCnt == 0)
-//				gBFApp->Process();		
-//			break;
-//		}
-//		
-//
-//		app->mInMsgProc = false;
-//	}
-//
-//	if (doResult)
-//		return result;
-//
-//	return DefWindowProc(hWnd, Msg, wParam, lParam);
-//}
-
 static int SDLConvertScanCode(int scanCode)
 {
 	if ((scanCode >= SDL_SCANCODE_A) && (scanCode <= SDL_SCANCODE_Z))
@@ -383,8 +78,8 @@ static int SDLConvertScanCode(int scanCode)
 		return (scanCode - SDL_SCANCODE_0) + '0';
 
 	switch (scanCode)
-	{	
-    case SDL_SCANCODE_CANCEL: return 0x03;    
+	{
+    case SDL_SCANCODE_CANCEL: return 0x03;
     case SDL_SCANCODE_AC_BACK: return 0x08;
     case SDL_SCANCODE_TAB: return 0x09;
     case SDL_SCANCODE_CLEAR: return 0x0C;
@@ -394,14 +89,14 @@ static int SDLConvertScanCode(int scanCode)
     case SDL_SCANCODE_LCTRL: return 0x11;
 	case SDL_SCANCODE_RCTRL: return 0x11;
     case SDL_SCANCODE_MENU: return 0x12;
-    case SDL_SCANCODE_PAUSE: return 0x13;    
+    case SDL_SCANCODE_PAUSE: return 0x13;
     case SDL_SCANCODE_LANG1: return 0x15;
     case SDL_SCANCODE_LANG2: return 0x15;
     case SDL_SCANCODE_LANG3: return 0x17;
     case SDL_SCANCODE_LANG4: return 0x18;
     case SDL_SCANCODE_LANG5: return 0x19;
     case SDL_SCANCODE_LANG6: return 0x19;
-    case SDL_SCANCODE_ESCAPE: return 0x1B;                
+    case SDL_SCANCODE_ESCAPE: return 0x1B;
     case SDL_SCANCODE_SPACE: return 0x20;
     case SDL_SCANCODE_PAGEUP: return 0x21;
     case SDL_SCANCODE_PAGEDOWN: return 0x22;
@@ -413,7 +108,7 @@ static int SDLConvertScanCode(int scanCode)
     case SDL_SCANCODE_DOWN: return 0x28;
     case SDL_SCANCODE_SELECT: return 0x29;
     case SDL_SCANCODE_PRINTSCREEN: return 0x2A;
-    case SDL_SCANCODE_EXECUTE: return 0x2B;    
+    case SDL_SCANCODE_EXECUTE: return 0x2B;
     case SDL_SCANCODE_INSERT: return 0x2D;
     case SDL_SCANCODE_DELETE: return 0x2E;
     case SDL_SCANCODE_HELP: return 0x2F;
@@ -461,62 +156,50 @@ extern HINSTANCE gDLLInstance;
 
 SdlBFApp::SdlBFApp()
 {
-    
-	//_CrtSetReportHook(SdlBFReportHook);
-
 	mRunning = false;
-	mRenderDevice = NULL;	
+	mRenderDevice = NULL;
 
-	wchar_t aStr[MAX_PATH];
-#ifdef _WIN32
-	GetModuleFileNameW(gDLLInstance, aStr, MAX_PATH);
-#else
-    GetModuleFileNameW(NULL, aStr, MAX_PATH);
-#endif
-    
-    if (aStr[0] == '!')
-    {
-        new SdlBFWindow(NULL, "", 0, 0, 0, 0, 0);
-    }
-    
-	mInstallDir = aStr;
-
-	int lastSlash = std::max((int)mInstallDir.rfind('\\'), (int)mInstallDir.rfind('/'));
+	Beefy::String exePath;
+	BfpGetStrHelper(exePath, [](char* outStr, int* inOutStrSize, BfpResult* result)
+		{
+			BfpSystem_GetExecutablePath(outStr, inOutStrSize, (BfpSystemResult*)result);
+		});
+
+	mInstallDir = GetFileDir(exePath) + "/";
+
+	int lastSlash = std::max((int)mInstallDir.LastIndexOf('\\'), (int)mInstallDir.LastIndexOf('/'));
 	if (lastSlash != -1)
-		mInstallDir = mInstallDir.substr(0, lastSlash);
+		mInstallDir = mInstallDir.Substring(0, lastSlash);
 
     //TODO: We're not properly using DataDir vs InstallDir
 #if (!defined BFSYSLIB_DYNAMIC) && (defined BF_RESOURCES_REL_DIR)
     mInstallDir += "/" + Beefy::UTF8Decode(BF_RESOURCES_REL_DIR);
 #endif
-    
+
     mInstallDir += "/";
 
-    //OutputDebugStrF(L"DataDir: %s\n", mInstallDir.c_str());
-    
 	mDataDir = mInstallDir;
-    
+
 	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
 		BF_FATAL(StrFormat("Unable to initialize SDL: %s", SDL_GetError()).c_str());
 }
 
 SdlBFApp::~SdlBFApp()
-{	
+{
 }
 
 SdlBFWindow* SdlBFApp::GetSdlWindowFromId(uint32 id)
 {
-	SdlWindowMap::iterator itr = mSdlWindowMap.find(id);
-	if (itr != mSdlWindowMap.end())
-		return itr->second;
-	return NULL;
+	SdlBFWindow* window = NULL;
+	mSdlWindowMap.TryGetValue(id, &window);
+	return window;
 }
 
 void SdlBFApp::Init()
 {
 	mRunning = true;
 	mInMsgProc = false;
-	
+
 	mRenderDevice = new GLRenderDevice();
 	mRenderDevice->Init(this);
 }
@@ -533,9 +216,9 @@ void SdlBFApp::Run()
                 if (!SDL_PollEvent(&sdlEvent))
                     break;
             }
-            
+
             //Beefy::DebugTimeGuard suspendTimeGuard(30, "BFApp::Run2");
-            
+
 			switch (sdlEvent.type)
 			{
 			case SDL_QUIT:
@@ -551,7 +234,7 @@ void SdlBFApp::Run()
 			case SDL_MOUSEBUTTONDOWN:
 				{
 					SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID);
-					sdlBFWindow->mMouseDownFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, sdlEvent.button.button, 1);					
+					sdlBFWindow->mMouseDownFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, sdlEvent.button.button, 1);
 				}
 				break;
 			case SDL_MOUSEMOTION:
@@ -572,10 +255,10 @@ void SdlBFApp::Run()
 					SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.key.windowID);
 					sdlBFWindow->mKeyUpFunc(sdlBFWindow, SDLConvertScanCode(sdlEvent.key.keysym.scancode));
 				}
-				break;			
+				break;
 			}
 		}
-		
+
         Process();
 	}
 }
@@ -586,25 +269,25 @@ int gBFDrawBatchCount = 0;
 void SdlBFApp::Draw()
 {
     //Beefy::DebugTimeGuard suspendTimeGuard(30, "SdlBFApp::Draw");
-    
+
     glDisable(GL_SCISSOR_TEST);
     glDisable(GL_CULL_FACE);
     glDisable(GL_DEPTH_TEST);
     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-    
+
     gPixelsDrawn = 0;
     gBFDrawBatchCount = 0;
-    
-	mRenderDevice->FrameStart();	
-	BFApp::Draw();	
+
+	mRenderDevice->FrameStart();
+	BFApp::Draw();
 	mRenderDevice->FrameEnd();
-    
+
     gFrameCount++;
     //if (gFrameCount % 60 == 0)
         //OutputDebugStrF("Pixels: %d  Batches: %d\n", gPixelsDrawn / 1000, gBFDrawBatchCount);
 }
- 
+
 BFWindow* SdlBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
 {
 	SdlBFWindow* aWindow = new SdlBFWindow(parent, title, x, y, width, height, windowFlags);
@@ -623,29 +306,7 @@ void SdlBFWindow::GetPosition(int* x, int* y, int* width, int* height, int* clie
 
 void SdlBFApp::PhysSetCursor()
 {
-	//
-	//static HCURSOR cursors [] = 
-	//	{	
-	//		::LoadCursor(NULL, IDC_ARROW),
-	//		
-	//		//TODO: mApp->mHandCursor);
-	//		::LoadCursor(NULL, IDC_ARROW),
-	//		//TODO: mApp->mDraggingCursor);
-	//		::LoadCursor(NULL, IDC_ARROW),
-
-	//		::LoadCursor(NULL, IDC_IBEAM),
-	//					
-	//		::LoadCursor(NULL, IDC_NO),		
-	//		::LoadCursor(NULL, IDC_SIZEALL),
-	//		::LoadCursor(NULL, IDC_SIZENESW),
-	//		::LoadCursor(NULL, IDC_SIZENS),		
-	//		::LoadCursor(NULL, IDC_SIZENWSE),
-	//		::LoadCursor(NULL, IDC_SIZEWE),		
-	//		::LoadCursor(NULL, IDC_WAIT),		
-	//		NULL
-	//	};	
-
-	//::SetCursor(cursors[mCursor]);
+
 }
 
 void SdlBFWindow::SetClientPosition(int x, int y)
@@ -668,7 +329,7 @@ uint32 SdlBFApp::GetClipboardFormat(const StringImpl& format)
 
 void* SdlBFApp::GetClipboardData(const StringImpl& format, int* size)
 {
-	return SDL_GetClipboardText();	
+	return SDL_GetClipboardText();
 }
 
 void SdlBFApp::ReleaseClipboardData(void* ptr)
@@ -677,17 +338,17 @@ void SdlBFApp::ReleaseClipboardData(void* ptr)
 }
 
 void SdlBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard)
-{	
+{
 	SDL_SetClipboardText((const char*)ptr);
 }
 
-BFMenu* SdlBFWindow::AddMenuItem(BFMenu* parent, const wchar_t* text, const wchar_t* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck)
-{	
+BFMenu* SdlBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* bitmap, bool enabled, int checkState, bool radioCheck)
+{
 	return NULL;
 }
 
 void SdlBFWindow::RemoveMenuItem(BFMenu* item)
-{	
+{
 }
 
 BFSysBitmap* SdlBFApp::LoadSysBitmap(const wchar_t* fileName)
@@ -706,20 +367,21 @@ DrawLayer* SdlBFApp::CreateDrawLayer(BFWindow* window)
 	GLDrawLayer* drawLayer = new GLDrawLayer();
 	if (window != NULL)
 	{
-		drawLayer->mRenderWindow = window->mRenderWindow;	
+		drawLayer->mRenderWindow = window->mRenderWindow;
 		window->mRenderWindow->mDrawLayerList.push_back(drawLayer);
 	}
+	drawLayer->mRenderDevice = mRenderDevice;
 	return drawLayer;
 }
 
 
-void SdlBFApp::GetDesktopResolution(int& width, int& height) override
+void SdlBFApp::GetDesktopResolution(int& width, int& height)
 {
 	width = 1024;
 	height = 768;
 }
 
-void SdlBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height) override
+void SdlBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height)
 {
 	x = 0;
 	y = 0;

+ 20 - 5
BeefySysLib/platform/sdl/SdlBFApp.h

@@ -3,6 +3,7 @@
 #include "BFApp.h"
 #include "BFWindow.h"
 #include <map>
+#include "util/Dictionary.h"
 
 struct SDL_Window;
 
@@ -16,24 +17,38 @@ class SdlBFWindow : public BFWindow
 {
 public:
 	SDL_Window*				mSDLWindow;
-	bool					mIsMouseInside;	
-	int						mModalCount;	
+	bool					mIsMouseInside;
+	int						mModalCount;
 
 public:
 	SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags);
 	~SdlBFWindow();
 
+	virtual void*			GetUnderlying() {return mSDLWindow; };
+	virtual void			Destroy() { }
+
+	virtual void			SetTitle(const char* title) override {}
+	virtual void			SetMinimumSize(int minWidth, int minHeight, bool clientSized) override {}
+	virtual void			GetPlacement(int* normX, int* normY, int* normWidth, int* normHeight, int* showKind) override { }
+	virtual void			Resize(int x, int y, int width, int height, int showKind) override {}
+	virtual void			SetMouseVisible(bool isMouseVisible) override {}
+
 	virtual bool			TryClose() override;
 	virtual void			GetPosition(int* x, int* y, int* width, int* height, int* clientX, int* clientY, int* clientWidth, int* clientHeight) override;
 	virtual void			SetClientPosition(int x, int y) override;
 	virtual void			SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible) override;
-    virtual BFMenu*         AddMenuItem(BFMenu* parent, const wchar_t* text, const wchar_t* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck);
-
+	virtual BFMenu*			AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* bitmap, bool enabled, int checkState, bool radioCheck) override;
+	virtual void			ModifyMenuItem(BFMenu* item, const char* text, const char* hotKey, BFSysBitmap* bitmap, bool enabled, int checkState, bool radioCheck) override {}
 	virtual void			RemoveMenuItem(BFMenu* item) override;
+
+	virtual void			LostFocus(BFWindow* newFocus) override {};
+
 	virtual void			ModalsRemoved() override;
+
+	virtual void			SetForeground() override {};
 };
 
-typedef std::map<uint32, SdlBFWindow*> SdlWindowMap;
+typedef Dictionary<uint32, SdlBFWindow*> SdlWindowMap;
 
 class SdlBFApp : public BFApp
 {

+ 10 - 0
IDE/dist/shaders/Std.frag

@@ -0,0 +1,10 @@
+uniform sampler2D tex;
+uniform sampler2D tex2;
+varying vec4 varying_color;
+varying vec2 varying_texCoord0;
+
+void main()
+{
+	vec4 texColor = texture2D(tex, varying_texCoord0);
+	gl_FragColor = texColor * varying_color;
+}

+ 12 - 0
IDE/dist/shaders/Std_font.frag

@@ -0,0 +1,12 @@
+uniform sampler2D tex;
+uniform sampler2D tex2;
+varying vec4 varying_color;
+varying vec2 varying_texCoord0;
+
+void main()
+{
+	vec4 texColor = texture2D(tex, varying_texCoord0);
+	float gray = varying_color.r * 0.299 + varying_color.g * 0.587 + varying_color.b * 0.114;
+	float a = mix(texColor.a, texColor.r, gray);
+    gl_FragColor = vec4(a, a, a, a) * varying_color;
+}

+ 15 - 0
IDE/dist/shaders/Std_font.vert

@@ -0,0 +1,15 @@
+uniform mat4 screenMatrix;
+
+attribute vec4 position;
+attribute vec2 texCoord0;
+attribute vec4 color;
+
+varying vec4 varying_color;
+varying vec2 varying_texCoord0;
+
+void main()
+{        
+	gl_Position = screenMatrix * position;    
+    varying_color = vec4(color.b * color.a, color.g * color.a, color.r * color.a, color.a);    
+    varying_texCoord0 = texCoord0;
+} 

+ 14 - 0
IDE/dist/shaders/Std_font_es.frag

@@ -0,0 +1,14 @@
+precision lowp float;
+
+uniform lowp sampler2D tex;
+uniform lowp sampler2D tex2;
+varying lowp vec4 varying_color;
+varying mediump vec2 varying_texCoord0;
+
+void main()
+{
+	lowp vec4 texColor = texture2D(tex, varying_texCoord0);
+	float gray = varying_color.r * 0.299 + varying_color.g * 0.587 + varying_color.b * 0.114;
+	float a = mix(texColor.a, texColor.r, gray);
+    gl_FragColor = vec4(a, a, a, a) * varying_color;
+}

+ 17 - 0
IDE/dist/shaders/Std_font_es.vert

@@ -0,0 +1,17 @@
+precision mediump float;
+uniform mat4 screenMatrix;
+
+attribute vec4 position;
+attribute vec2 texCoord0;
+attribute vec4 color;
+
+precision lowp float;
+varying lowp vec4 varying_color;
+varying mediump vec2 varying_texCoord0;
+
+void main()
+{        
+	gl_Position = screenMatrix * position;    
+    varying_color = vec4(color.b * color.a, color.g * color.a, color.r * color.a, color.a);    
+    varying_texCoord0 = texCoord0;
+}