Added GLES 1.x spinning cube-rendering code to eglbringuptest bug235_bringup_0
authorGareth Stockwell <gareth.stockwell@accenture.com>
Fri, 05 Nov 2010 17:31:20 +0000
branchbug235_bringup_0
changeset 215 097e92a68d68
parent 213 deb2534f581f
Added GLES 1.x spinning cube-rendering code to eglbringuptest The coordinate, color and index data are uploaded to server-side buffers by the CGLES1Cube::KhrSetup function. CGLES1Cube::KhrPaint just sets the view matrix and issues a draw command. Which demo to display can be selected by passing its name on the command line, e.g. eglbringuptest vgline eglbringuptest gles1cube If no name is provided, the application defaults to vgline.
egl/sfegltest/group/eglbringuptest.mmp
egl/sfegltest/inc/eglrendering.h
egl/sfegltest/inc/gles1cube.h
egl/sfegltest/inc/vgline.h
egl/sfegltest/src/eglrendering.cpp
egl/sfegltest/src/gles1cube.cpp
egl/sfegltest/src/main.cpp
egl/sfegltest/src/vgline.cpp
--- a/egl/sfegltest/group/eglbringuptest.mmp	Fri Nov 05 13:02:33 2010 +0000
+++ b/egl/sfegltest/group/eglbringuptest.mmp	Fri Nov 05 17:31:20 2010 +0000
@@ -43,13 +43,16 @@
 sourcepath		../src
 source			main.cpp
 source			eglrendering.cpp
+source			gles1cube.cpp
 source			vgline.cpp
 
+library			bafl.lib
 library         euser.lib
 library         libc.lib
 library         ws32.lib
 library			libegl.lib
 library			libopenvg.lib
+library			libgles_cm.lib
 
 smpsafe
 
--- a/egl/sfegltest/inc/eglrendering.h	Fri Nov 05 13:02:33 2010 +0000
+++ b/egl/sfegltest/inc/eglrendering.h	Fri Nov 05 17:31:20 2010 +0000
@@ -17,8 +17,9 @@
 
 #include <e32base.h>
 #include <w32std.h>
-#include <EGL/egl.h>
-#include <VG/openvg.h>
+#include <egl/egl.h>
+#include <vg/openvg.h>
+#include <gles/gl.h>
 
 class CEGLRendering : public CBase
 	{
@@ -29,8 +30,9 @@
     void Redraw();
 
 protected:
-    CEGLRendering(RWindow& aWindow);
+    CEGLRendering(RWindow& aWindow, EGLenum aApi);
     void ConstructL();
+    TSize WindowSize() const;
 
 	void StartRedrawTimer();
 	void StopRedrawTimer();
@@ -38,6 +40,7 @@
     static void EGLCheckError();
     static void EGLCheckReturnError(EGLBoolean aBool);
     static void VGCheckError();
+    static void GLCheckError();
 
 private:
     void EglSetupL();
@@ -47,6 +50,7 @@
 
 private:
 	RWindow& iWindow;
+	const EGLenum iApi;
 	CPeriodic* iRedrawTimer;
 	EGLDisplay iDisplay;
 	EGLSurface iSurface;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egl/sfegltest/inc/gles1cube.h	Fri Nov 05 17:31:20 2010 +0000
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Accenture - initial contribution.
+//
+// Contributors:
+//
+// Description:
+
+#ifndef __GLES1CUBE_H__
+#define __GLES1CUBE_H__
+
+#include "eglrendering.h"
+
+class CGLES1Cube : public CEGLRendering
+    {
+public:
+    static CEGLRendering* NewL(RWindow& aWindow);
+    ~CGLES1Cube();
+    static const TDesC& Name();
+
+private:
+    CGLES1Cube(RWindow& aWindow);
+    void KhrSetup();
+    void KhrPaint();
+
+private:
+    TReal iAngle;
+    GLuint iCoordinateColorBuffer;
+    GLuint iIndexBuffer;
+    };
+
+#endif
+
--- a/egl/sfegltest/inc/vgline.h	Fri Nov 05 13:02:33 2010 +0000
+++ b/egl/sfegltest/inc/vgline.h	Fri Nov 05 17:31:20 2010 +0000
@@ -20,7 +20,8 @@
 class CVGLine : public CEGLRendering
     {
 public:
-    static CVGLine* NewL(RWindow& aWindow);
+    static CEGLRendering* NewL(RWindow& aWindow);
+    static const TDesC& Name();
 
 private:
     CVGLine(RWindow& aWindow);
--- a/egl/sfegltest/src/eglrendering.cpp	Fri Nov 05 13:02:33 2010 +0000
+++ b/egl/sfegltest/src/eglrendering.cpp	Fri Nov 05 17:31:20 2010 +0000
@@ -58,8 +58,19 @@
         }
     }
 
-CEGLRendering::CEGLRendering(RWindow& aWindow)
+void CEGLRendering::GLCheckError()
+    {
+	GLenum error = glGetError();
+    if(GL_NO_ERROR != error)
+        {
+        RDebug::Printf("[EBT] CEglRendering::GLCheckError error %d", error);
+        User::Panic(_L("EBT-GL"), error);
+        }
+    }
+
+CEGLRendering::CEGLRendering(RWindow& aWindow, EGLenum aApi)
 	:  iWindow(aWindow)
+	,  iApi(aApi)
 	{
 	}
 
@@ -85,6 +96,11 @@
 	EglSwapBuffers();
 	}
 
+TSize CEGLRendering::WindowSize() const
+	{
+	return iWindow.Size();
+	}
+
 void CEGLRendering::EglSetupL()
     {
     RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglGetDisplay");
@@ -121,8 +137,8 @@
         User::Leave(KErrNotSupported);
         }
 
-    RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglBindApi");
-    EGLCheckReturnError(eglBindAPI(EGL_OPENVG_API));
+    RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglBindApi 0x%x", iApi);
+    EGLCheckReturnError(eglBindAPI(iApi));
 
     RDebug::Printf("[EBT] CEGLRendering::EglSetupL eglCreateWindowSurface");
     iSurface = eglCreateWindowSurface(iDisplay, chosenConfig, &iWindow, NULL);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egl/sfegltest/src/gles1cube.cpp	Fri Nov 05 17:31:20 2010 +0000
@@ -0,0 +1,240 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+
+#include "gles1cube.h"
+
+_LIT(KGLES1CubeName, "gles1cube");
+
+CEGLRendering* CGLES1Cube::NewL(RWindow& aWindow)
+    {
+    CGLES1Cube* self = new (ELeave) CGLES1Cube(aWindow);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+const TDesC& CGLES1Cube::Name()
+	{
+	return KGLES1CubeName;
+	}
+
+CGLES1Cube::CGLES1Cube(RWindow& aWindow)
+    :   CEGLRendering(aWindow, EGL_OPENGL_ES_API)
+    {
+
+    }
+
+CGLES1Cube::~CGLES1Cube()
+	{
+	RDebug::Printf("[EBT] CGLES1Cube::~CGLES1Cube");
+	glDeleteBuffers(1, &iCoordinateColorBuffer);
+	glDeleteBuffers(1, &iIndexBuffer);
+	}
+
+/*
+    v6----- v4
+   /|      /|
+  v0------v2|
+  | |     | |
+  | |v7---|-|v5
+  |/      |/
+  v1------v3
+
+v0: -1.0, +1.0, +1.0,
+v1: -1.0, -1.0, +1.0,
+v2: +1.0, +1.0, +1.0,
+v3: +1.0, -1.0, +1.0,
+v4: +1.0, +1.0, -1.0,
+v5: +1.0, -1.0, -1.0,
+v6: -1.0, +1.0, -1.0,
+v7: -1.0, -1.0, -1.0,
+*/
+
+static GLfloat CoordinateData[] =
+	{
+	-1.0, +1.0, +1.0,	// v0
+	-1.0, -1.0, +1.0,	// v1
+	+1.0, +1.0, +1.0,	// v2
+	+1.0, -1.0, +1.0,	// v3
+	+1.0, +1.0, -1.0,	// v4
+	+1.0, -1.0, -1.0,	// v5
+	-1.0, +1.0, -1.0,	// v6
+	-1.0, -1.0, -1.0	// v7
+	};
+
+static const TInt CoordinateElementCount = 3; // XYZ
+
+static GLfloat ColorData[] =
+	{
+	 0.0,  1.0,  1.0,  1.0,	// v0
+	 0.0,  0.0,  1.0,  1.0,	// v1
+	 1.0,  1.0,  1.0,  1.0,	// v2
+	 1.0,  0.0,  1.0,  1.0,	// v3
+	 1.0,  1.0,  0.0,  1.0,	// v4
+	 1.0,  0.0,  0.0,  1.0,	// v5
+	 0.0,  1.0,  0.0,  1.0,	// v6
+	 0.0,  0.0,  0.0,  1.0	// v7
+	};
+
+static const TInt ColorElementCount = 4; // RGBA
+
+static GLubyte FaceData[] =
+	{
+	0, 1, 3, 2, // front
+	2, 3, 5, 4, // right
+	4, 5, 7, 6, // left
+	6, 7, 1, 0, // back
+	6, 0, 2, 4, // top
+	1, 7, 5, 3
+	};
+
+static const TInt VerticesPerFace = 4;
+static const TInt VertexCount = sizeof(FaceData) / sizeof(GLubyte);
+static const TInt FaceCount = VertexCount / VerticesPerFace;
+
+static const TInt TrianglesPerFace = 2;
+static const TInt VerticesPerTriangle = 3;
+
+static const TInt IndexCount = FaceCount * TrianglesPerFace * VerticesPerTriangle;
+
+static GLubyte FaceIndexData[] =
+	{
+	0, 2, 1,
+	0, 3, 2
+	};
+
+void CGLES1Cube::KhrSetup()
+    {
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup");
+
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup vertexCount %d", VertexCount);
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup faceCount %d", FaceCount);
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup indexCount %d", IndexCount);
+
+	const GLsizeiptr coordinateSize = CoordinateElementCount * sizeof(GLfloat);
+	const GLsizeiptr coordinateDataSize = VertexCount * coordinateSize;
+	const GLsizeiptr colorSize = ColorElementCount * sizeof(GLfloat);
+	const GLsizeiptr colorDataSize = VertexCount * colorSize;
+
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glViewport %d x %d", WindowSize().iWidth, WindowSize().iHeight);
+	glViewport(0, 0, WindowSize().iWidth, WindowSize().iHeight);
+	GLCheckError();
+
+	glEnable(GL_DEPTH_TEST);
+	glEnable(GL_CULL_FACE);
+	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
+
+	// Create coordinate/color buffer
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glGenBuffers vertex/color");
+	glGenBuffers(1, &iCoordinateColorBuffer);
+	GLCheckError();
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glBindBuffer vertex/color");
+	glBindBuffer(GL_ARRAY_BUFFER, iCoordinateColorBuffer);
+	GLCheckError();
+
+	// Allocate memory for coordinate/color buffer
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glBufferData coordinate/color");
+	glBufferData(GL_ARRAY_BUFFER, coordinateDataSize + colorDataSize, 0, GL_STATIC_DRAW);
+	GLCheckError();
+
+	// Upload coordinate/color data
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup supply coordinate/color data");
+	GLubyte indexData[IndexCount];
+	for (TInt i=0; i<FaceCount; ++i)
+		{
+		RDebug::Printf("[EBT] CGLES1Cube::KhrSetup face %d", i);
+		// Upload coordinate/color data for this face
+		for (TInt j=0; j<VerticesPerFace; ++j)
+			{
+			const TInt vertexIndex = FaceData[i * VerticesPerFace + j];
+			const TInt destIndex = (i * VerticesPerFace) + j;
+			const GLfloat *coordSrc = CoordinateData + vertexIndex * CoordinateElementCount;
+			const TInt coordDest = destIndex * coordinateSize;
+			const GLfloat *colorSrc = ColorData + vertexIndex * ColorElementCount;
+			const TInt colorDest = coordinateDataSize + destIndex * colorSize;
+			RDebug::Printf("[EBT] CGLES1Cube::KhrSetup vertex %d (%d) destIndex %d coordDest %d colorDest %d",
+					       j, vertexIndex, destIndex, coordDest, colorDest);
+			RDebug::Printf("[EBT] CGLES1Cube::KhrSetup coord %3.1f %3.1f %3.1f",
+						   *(coordSrc), *(coordSrc + 1), *(coordSrc + 2));
+			RDebug::Printf("[EBT] CGLES1Cube::KhrSetup color %3.1f %3.1f %3.1f",
+						   *(colorSrc), *(colorSrc + 1), *(colorSrc + 2));
+			glBufferSubData(GL_ARRAY_BUFFER, coordDest, coordinateSize, coordSrc);
+			GLCheckError();
+			glBufferSubData(GL_ARRAY_BUFFER, colorDest, colorSize, colorSrc);
+			GLCheckError();
+			}
+
+		// Store vertex indices for this face
+		TInt indexDataOffset = i * TrianglesPerFace * VerticesPerTriangle;
+		TInt indexBase = i * VerticesPerFace;
+		for (TInt j=0; j<TrianglesPerFace * VerticesPerTriangle; ++j)
+			{
+			RDebug::Printf("[EBT] CGLES1Cube::KhrSetup index %d offset %d value %d",
+						   j, indexDataOffset, indexBase + FaceIndexData[j]);
+			indexData[indexDataOffset++] = indexBase + FaceIndexData[j];
+			}
+		}
+
+	// Tell GL engine how to unpack coordinate/color buffer
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glVertexPointer");
+	glVertexPointer(CoordinateElementCount, GL_FLOAT, 0, 0);
+	GLCheckError();
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glColorPointer");
+	glColorPointer(ColorElementCount, GL_FLOAT, 0, reinterpret_cast<GLvoid*>(coordinateDataSize));
+	GLCheckError();
+
+	// Create index buffer
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glGenBuffers index");
+	glGenBuffers(1, &iIndexBuffer);
+	GLCheckError();
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glBindBuffer index");
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iIndexBuffer);
+	GLCheckError();
+
+	// Allocate memory for index buffer and upload index data
+	RDebug::Printf("[EBT] CGLES1Cube::KhrSetup glBufferData index");
+	glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexCount, indexData, GL_STATIC_DRAW);
+	GLCheckError();
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	GLCheckError();
+	glEnableClientState(GL_COLOR_ARRAY);
+	GLCheckError();
+
+	StartRedrawTimer();
+    }
+
+void CGLES1Cube::KhrPaint()
+	{
+	RDebug::Printf("[EBT] CGLES1Cube::KhrPaint");
+
+	glLoadIdentity();
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrthof(-1.5f, 1.5f, -2.5f, 2.5f, -10.5f, 10.5f);
+
+	glMatrixMode(GL_MODELVIEW);
+	iAngle = (iAngle + 1.0f);
+	if (iAngle > 360.0f)
+		{
+		iAngle -= 360.0f;
+		}
+	glRotatef(iAngle, 0.0f, 1.0f, 0.5f);
+
+	glDrawElements(GL_TRIANGLES, IndexCount, GL_UNSIGNED_BYTE, 0);
+    }
+
--- a/egl/sfegltest/src/main.cpp	Fri Nov 05 13:02:33 2010 +0000
+++ b/egl/sfegltest/src/main.cpp	Fri Nov 05 17:31:20 2010 +0000
@@ -16,6 +16,8 @@
 #include <w32std.h>
 #include <e32math.h>
 #include <e32keys.h>
+#include <bacline.h>
+#include "gles1cube.h"
 #include "vgline.h"
 
 #define KDefaultScreenNo 0
@@ -224,6 +226,10 @@
 	return self;
 	}
 
+_LIT(KOptionScreen, "-screen");
+
+typedef CEGLRendering* (*RendererFactoryFunctionL)(RWindow&);
+
 /**
  * Constructor for CWsApp
  *
@@ -236,22 +242,56 @@
 	RDebug::Printf("[EBT] CWsApp::ConstructL");
 
 	iScrId = KDefaultScreenNo;
-	if (User::CommandLineLength() > 0)
+	HBufC* rendererName = 0;
+	CCommandLineArguments* args = CCommandLineArguments::NewLC();
+	for (TInt i=1; i<args->Count(); ++i)
 		{
-		TBuf<1> arg;
-		User::CommandLine(arg);
-		iScrId = (TInt)(arg[0]-'0');
+		const TPtrC arg = args->Arg(i);
+		if (!arg.Compare(KOptionScreen))
+			{
+			if (++i < args->Count())
+				{
+				TLex lex(args->Arg(i));
+				User::LeaveIfError(lex.Val(iScrId));
+				RDebug::Printf("[EBT] CWsApp::ConstructL screenId %d", iScrId);
+				}
+			}
+		else if (!rendererName)
+			{
+			RDebug::Print(_L("[EBT] CWsApp::ConstructL rendererName %S"), &arg);
+			rendererName = HBufC::NewL(arg.Length());
+			rendererName->Des() = arg;
+			}
+		else
+			{
+			RDebug::Print(_L("[EBT] CWsApp::ConstructL ignoring argument %S"), &arg);
+			}
 		}
 
-	RDebug::Printf("[EBT] CWsApp::ConstructL 1");
+	CleanupStack::PopAndDestroy(args);
+	if (rendererName)
+		{
+		CleanupStack::PushL(rendererName);
+		}
+
 	iAppView = CWsCanvas::NewL(iScrId, iPos);
-	RDebug::Printf("[EBT] CWsApp::ConstructL 2");
+    iSz = iAppView->ScreenSize();
 	iEventHandler = new (ELeave) CWsEventHandler(iAppView->Session(), iAppView->Window(), *this);
-	RDebug::Printf("[EBT] CWsApp::ConstructL 3");
-	iDemo = CVGLine::NewL(iAppView->Window());
-	RDebug::Printf("[EBT] CWsApp::ConstructL 4");
-	iSz = iAppView->ScreenSize();
-	RDebug::Printf("[EBT] CWsApp::ConstructL 5");
+
+	RendererFactoryFunctionL factoryFunctionL = CVGLine::NewL;
+	if (rendererName)
+		{
+		if (!rendererName->Des().Compare(CGLES1Cube::Name()))
+			{
+			factoryFunctionL = CGLES1Cube::NewL;
+			}
+		if (!rendererName->Des().Compare(CVGLine::Name()))
+			{
+			factoryFunctionL = CVGLine::NewL;
+			}
+		CleanupStack::PopAndDestroy(rendererName);
+		}
+	iDemo = (*factoryFunctionL)(iAppView->Window());
 	}
 
 void CWsApp::Start()
@@ -274,13 +314,9 @@
 
 CWsApp::~CWsApp()
 	{
-    RDebug::Printf("[EBT] CWsApp::~CWsApp");
 	delete iDemo;
-	RDebug::Printf("[EBT] CWsApp::~CWsApp 1");
 	delete iEventHandler;
-    RDebug::Printf("[EBT] CWsApp::~CWsApp 2");
 	delete iAppView;
-    RDebug::Printf("[EBT] CWsApp::~CWsApp 3");
 	}
 
 /**
--- a/egl/sfegltest/src/vgline.cpp	Fri Nov 05 13:02:33 2010 +0000
+++ b/egl/sfegltest/src/vgline.cpp	Fri Nov 05 17:31:20 2010 +0000
@@ -14,7 +14,9 @@
 
 #include "vgline.h"
 
-CVGLine* CVGLine::NewL(RWindow& aWindow)
+_LIT(KVGLineName, "vgline");
+
+CEGLRendering* CVGLine::NewL(RWindow& aWindow)
     {
     CVGLine* self = new (ELeave) CVGLine(aWindow);
     CleanupStack::PushL(self);
@@ -23,9 +25,14 @@
     return self;
     }
 
+const TDesC& CVGLine::Name()
+	{
+	return KVGLineName;
+	}
+
 CVGLine::CVGLine(RWindow& aWindow)
-    :   CEGLRendering(aWindow)
-    {
+    :   CEGLRendering(aWindow, EGL_OPENVG_API)
+	{
     }
 
 void CVGLine::KhrSetup()