From 5a7152634684045ea46f9a3e54ae3039cbdc1b36 Mon Sep 17 00:00:00 2001 From: Marek Pikarski Date: Tue, 1 Oct 2013 09:40:30 +0200 Subject: [PATCH] Example: Added EGL application example running with DirectFB Added an EGL example application which directly renders into a DIrectFB surface. Signed-off-by: Marek Pikarski --- .../EGLDFBApplicationExample/CMakeLists.txt | 49 ++++ .../EGLDFBApplicationExample/include/egl_helper.h | 37 +++ .../include/gles2application.h | 39 ++++ .../src/eglDFB_application.cpp | 75 ++++++ .../EGLDFBApplicationExample/src/egl_helper.cpp | 255 ++++++++++++++++++++ .../src/gles2application.cpp | 259 +++++++++++++++++++++ 6 files changed, 714 insertions(+) create mode 100644 LayerManagerExamples/EGLDFBApplicationExample/CMakeLists.txt create mode 100644 LayerManagerExamples/EGLDFBApplicationExample/include/egl_helper.h create mode 100644 LayerManagerExamples/EGLDFBApplicationExample/include/gles2application.h create mode 100644 LayerManagerExamples/EGLDFBApplicationExample/src/eglDFB_application.cpp create mode 100644 LayerManagerExamples/EGLDFBApplicationExample/src/egl_helper.cpp create mode 100644 LayerManagerExamples/EGLDFBApplicationExample/src/gles2application.cpp diff --git a/LayerManagerExamples/EGLDFBApplicationExample/CMakeLists.txt b/LayerManagerExamples/EGLDFBApplicationExample/CMakeLists.txt new file mode 100644 index 0000000..bf08b16 --- /dev/null +++ b/LayerManagerExamples/EGLDFBApplicationExample/CMakeLists.txt @@ -0,0 +1,49 @@ +############################################################################ +# +# Copyright 2010-2012 BMW Car IT GmbH +# Copyright (c) 2013 DirectFB integrated media GmbH +# Copyright (c) 2013 Renesas Solutions Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################ + +cmake_minimum_required (VERSION 2.6) + +project_type(EXAMPLE) + +include_directories ("include") +include_directories ("../../LayerManagerClient/ilmClient/include") +include_directories ("../LayerSceneDescriptionExample/include") +include_directories ("../../LayerManagerUtils/include") +include_directories ("../../LayerManagerClient/ilmControl/include") + +add_executable(EGLDFBApplicationExample src/egl_helper.cpp src/eglDFB_application.cpp src/gles2application.cpp) + +add_dependencies(EGLDFBApplicationExample ilmClient) +add_dependencies(EGLDFBApplicationExample LayerManagerUtils) + +find_package (GLESv2 REQUIRED) +include_directories(${GLESv2_INCLUDE_DIR}) + +find_package (EGL REQUIRED) +include_directories(${EGL_INCLUDE_DIR}) + +find_package (DirectFB REQUIRED) +include_directories(${DIRECTFB_INTERNAL_INCLUDE_DIRS}) +include_directories(${DIRECTFB_EGL_INCLUDE_DIRS}) + +set(LIBS ${LIBS} ${GLESv2_LIBRARIES} ${DIRECTFB_LDFLAGS} ${DIRECTFB_LIBRARIES} ${DIRECTFB_EGL_LDFLAGS} ${DIRECTFB_EGL_LIBRARIES} ${EGL_LIBRARY} LayerManagerUtils) +target_link_libraries(EGLDFBApplicationExample ${LIBS} ilmClient ilmControl) + +install (TARGETS EGLDFBApplicationExample DESTINATION bin) diff --git a/LayerManagerExamples/EGLDFBApplicationExample/include/egl_helper.h b/LayerManagerExamples/EGLDFBApplicationExample/include/egl_helper.h new file mode 100644 index 0000000..871e7e8 --- /dev/null +++ b/LayerManagerExamples/EGLDFBApplicationExample/include/egl_helper.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * + * Copyright 2010,2011 BMW Car IT GmbH + * Copyright (c) 2013 DirectFB integrated media GmbH + * Copyright (c) 2013 Renesas Solutions Corp. + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#ifndef _EGL_HELPER_H_ +#define _EGL_HELPER_H_ + +#include "ilm_client.h" +#include +#include +#include + +t_ilm_uint GetTickCount(); +t_ilm_bool createDFBContext(t_ilm_int width, t_ilm_int height); +t_ilm_bool createEGLContext(t_ilm_int width, t_ilm_int height); +void destroyEglContext(); +void destroyDFBContext(); +void swapBuffers(); + +#endif /* _EGL_HELPER_H_ */ diff --git a/LayerManagerExamples/EGLDFBApplicationExample/include/gles2application.h b/LayerManagerExamples/EGLDFBApplicationExample/include/gles2application.h new file mode 100644 index 0000000..b62dff3 --- /dev/null +++ b/LayerManagerExamples/EGLDFBApplicationExample/include/gles2application.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * + * Copyright 2010,2011 BMW Car IT GmbH + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#ifndef _GLES2APPLICATION_H_ +#define _GLES2APPLICATION_H_ + +#include "ilm_client.h" +#include + +t_ilm_bool initGlApplication(); +t_ilm_bool initShader(); +t_ilm_bool destroyShader(); +t_ilm_bool initVertexBuffer(); + +void attachVertexBuffer(); +void detachVertexBuffer(); +void destroyVertexBuffer(); + +void draw(t_ilm_uint animTime); + +void destroyGlApplication(); + +#endif /* _GLES2APPLICATION_H_ */ diff --git a/LayerManagerExamples/EGLDFBApplicationExample/src/eglDFB_application.cpp b/LayerManagerExamples/EGLDFBApplicationExample/src/eglDFB_application.cpp new file mode 100644 index 0000000..df2d7fc --- /dev/null +++ b/LayerManagerExamples/EGLDFBApplicationExample/src/eglDFB_application.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * + * Copyright 2010,2011 BMW Car IT GmbH + * Copyright (c) 2013 DirectFB integrated media GmbH + * Copyright (c) 2013 Renesas Solutions Corp. + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include "ilm_client.h" +#include "egl_helper.h" +#include "gles2application.h" +#include +#include + +/********************* DEFINES **********************************************/ +// Max width and height of the window +#define SURFACE_WIDTH 200 +#define SURFACE_HEIGHT 200 + +#define LAYER_WIDTH 800 +#define LAYER_HEIGHT 480 +/****************************************************************************/ + +/********************* TYPEDEFS **********************************************/ + +/****************************************************************************/ + +int main(void) +{ + printf("Starting demo EGL DFB Application Example\n"); + + if (ilm_init() == ILM_FAILED) { + printf("Can't Init LayerManagement Communication\n"); + return -1; + } + + if (!createDFBContext(SURFACE_WIDTH, SURFACE_HEIGHT)) { + printf("Can't Create DFB Context\n"); + return -1; + } + + if (!createEGLContext(SURFACE_WIDTH, SURFACE_HEIGHT)) { + printf("Can't Create EGL Context\n"); + return -1; + } + + if (!initGlApplication()) { + printf("Can't Init GL Application\n"); + return -1; + } + + while (ILM_TRUE) { + draw(33); + usleep(1000); + } + + destroyEglContext(); + destroyDFBContext(); + destroyGlApplication(); + ilm_destroy(); + return 0; +} diff --git a/LayerManagerExamples/EGLDFBApplicationExample/src/egl_helper.cpp b/LayerManagerExamples/EGLDFBApplicationExample/src/egl_helper.cpp new file mode 100644 index 0000000..b7f8e33 --- /dev/null +++ b/LayerManagerExamples/EGLDFBApplicationExample/src/egl_helper.cpp @@ -0,0 +1,255 @@ +/************************************************************************** + * + * Copyright 2010,2011 BMW Car IT GmbH + * Copyright (c) 2013 DirectFB integrated media GmbH + * Copyright (c) 2013 Renesas Solutions Corp. + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#define EGL_EGLEXT_PROTOTYPES + +#include + +#include + +#include +#include +#include +#include +#include +#include + + +#define GL_GLEXT_PROTOTYPES + +#include + + +#include "egl_helper.h" +#include "LayerScene.h" +#include "ilm_control.h" + + +typedef struct t_eglContextStruct { + EGLDisplay display; + EGLConfig configs[2]; + EGLSurface surface; + EGLContext context; +} EGLContextStruct; + +typedef struct t_dfbContextStruct { + IDirectFB *dfb; + IDirectFBDisplayLayer *layer; + IDirectFBWindow *window; + IDirectFBSurface *primary; + DFBDimension size; +} DFBContextStruct; + +static EGLContextStruct g_eglContextStruct; +static DFBContextStruct g_dfbContextStruct; + +EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; + +static DFBResult InitDFB( DFBContextStruct *test, int width, int height ) +{ + DFBResult ret; + DFBWindowDescription wdesc; + + ret = DirectFBInit( 0, NULL ); + if (ret) { + printf( "EGLDFBApplicationExample: DirectFBInit() failed! (ret=%d)\n", ret ); + return ret; + } + + ret = DirectFBCreate( &test->dfb ); + if (ret) { + printf( "EGLDFBApplicationExample: DirectFBCreate() failed! (ret=%d)\n", ret ); + return ret; + } + + ret = test->dfb->GetDisplayLayer( test->dfb, DLID_PRIMARY, &test->layer ); + if (ret) { + printf( "EGLDFBApplicationExample: GetDisplayLayer() failed! (ret=%d)\n", ret ); + return ret; + } + + test->layer->SetCooperativeLevel( test->layer, DLSCL_ADMINISTRATIVE ); + test->layer->EnableCursor ( test->layer, 1 ); + + wdesc.flags = (DFBWindowDescriptionFlags)( DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS ); + wdesc.caps = DWCAPS_ALPHACHANNEL; + wdesc.posx = 0; + wdesc.posy = 0; + wdesc.width = width; + wdesc.height = height; + + ret = test->layer->CreateWindow( test->layer, &wdesc, &test->window ); + if (ret) { + printf( "EGLDFBApplicationExample: IDirectFB::CreateWindow() failed! (ret=%d)\n", ret ); + return ret; + } + + ret = test->window->GetSurface( test->window, &test->primary ); + if (ret) { + printf( "EGLDFBApplicationExample: IDirectFB::CreateSurface( DSCAPS_PRIMARY | DSCAPS_FLIPPING ) failed! (ret=%d)\n", ret ); + return ret; + } + + test->primary->AllowAccess( test->primary, "*" ); + test->primary->GetSize( test->primary, &test->size.w, &test->size.h ); + test->primary->Clear( test->primary, 0, 0, 0, 0 ); + test->primary->Flip( test->primary, NULL, DSFLIP_NONE ); + + return DFB_OK; +} + +static void ShutdownDFB( DFBContextStruct *test ) +{ + if (test->primary) + test->primary->Release( test->primary ); + + if (test->window) + test->window->Release( test->window ); + + if (test->layer) + test->layer->Release( test->layer ); + + if (test->dfb) + test->dfb->Release( test->dfb ); +} + +t_ilm_bool createDFBContext(t_ilm_int width, t_ilm_int height) +{ + if (InitDFB( &g_dfbContextStruct, width, height )) + return ILM_FALSE; + + return ILM_TRUE; +} + +#define EGL_CHECK(cmd) \ + if (cmd) { \ + fprintf(stderr, "!!! %s failed\n", #cmd); \ + goto quit; \ + } + +static DFBResult InitEGL( EGLContextStruct *test, int width, int height ) +{ + EGLint major, minor, nconfigs; + EGLint attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_BUFFER_SIZE, EGL_DONT_CARE, + EGL_DEPTH_SIZE, 16, + EGL_RED_SIZE, 0, + EGL_GREEN_SIZE, 0, + EGL_BLUE_SIZE, 0, + EGL_ALPHA_SIZE, 0, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + EGLint context_attrs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE + }; + EGLint surface_attrs[] = { + EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE + }; + EGLNativeDisplayType disp = EGL_DEFAULT_DISPLAY; + + // get display + EGL_CHECK((test->display = eglGetDisplay(disp)) == EGL_NO_DISPLAY) + + // init + EGL_CHECK(!eglInitialize(test->display, &major, &minor)) + + EGL_CHECK(!eglGetConfigAttribsDIRECTFB(test->display, (EGLNativeWindowType)g_dfbContextStruct.primary, attribs, 0)) + + // get configs + EGL_CHECK(!eglGetConfigs(test->display, test->configs, 2, &nconfigs)) + + // choose config + EGL_CHECK(!eglChooseConfig(test->display, attribs, test->configs, 2, &nconfigs)) + + // create a surface + EGL_CHECK((test->surface = eglCreateWindowSurface(test->display, test->configs[0], (EGLNativeWindowType)g_dfbContextStruct.primary, surface_attrs)) == EGL_NO_SURFACE) + + EGL_CHECK(eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) + + // create context + EGL_CHECK((test->context = eglCreateContext(test->display, test->configs[0], EGL_NO_CONTEXT, context_attrs)) == EGL_NO_CONTEXT) + + EGL_CHECK(eglMakeCurrent(test->display, test->surface, test->surface, test->context) != EGL_TRUE) + + eglSwapInterval( test->display, 1 ); + + /* Setup the viewport */ + glViewport( 0, 0, width, height ); + + return DFB_OK; +quit: + return DFB_FAILURE; +} + +t_ilm_bool createEGLContext(t_ilm_int width, t_ilm_int height) +{ + if (InitEGL( &g_eglContextStruct, g_dfbContextStruct.size.w, g_dfbContextStruct.size.h )) + return ILM_FALSE; + + // register surfaces to layermanager + t_ilm_layer layerid = (t_ilm_layer)LAYER_EXAMPLE_X_APPLICATIONS; + t_ilm_surface surfaceid; + + DFBWindowID dfb_wid = 0; + g_dfbContextStruct.window->GetID(g_dfbContextStruct.window, &dfb_wid); + surfaceid = dfb_wid; + ilm_surfaceCreate((t_ilm_nativehandle) dfb_wid, width, height, ILM_PIXELFORMAT_RGBA_8888, &surfaceid); + + ilm_surfaceSetDestinationRectangle(surfaceid, 0, 0, width, height); + + ilm_surfaceSetSourceRectangle(surfaceid, 0, 0, width, height); + + ilm_layerAddSurface(layerid, surfaceid); + + ilm_surfaceSetVisibility(surfaceid, ILM_TRUE); + + ilm_surfaceSetOpacity(surfaceid, 1.0f); + + return(ILM_SUCCESS == ilm_commitChanges()) ? ILM_TRUE : ILM_FALSE; +} + +void destroyEglContext() +{ + if (g_eglContextStruct.display != NULL) { + eglMakeCurrent(g_eglContextStruct.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglTerminate(g_eglContextStruct.display); + } +} + +void destroyDFBContext() +{ + ShutdownDFB( &g_dfbContextStruct ); +} + +t_ilm_uint GetTickCount() +{ + struct timeval ts; + gettimeofday(&ts, 0); + return(t_ilm_uint) (ts.tv_sec * 1000 + (ts.tv_usec / 1000)); +} + +void swapBuffers() +{ + eglSwapBuffers(g_eglContextStruct.display, g_eglContextStruct.surface); +} + diff --git a/LayerManagerExamples/EGLDFBApplicationExample/src/gles2application.cpp b/LayerManagerExamples/EGLDFBApplicationExample/src/gles2application.cpp new file mode 100644 index 0000000..682433c --- /dev/null +++ b/LayerManagerExamples/EGLDFBApplicationExample/src/gles2application.cpp @@ -0,0 +1,259 @@ +/*************************************************************************** + * + * Copyright 2010,2011 BMW Car IT GmbH + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include "egl_helper.h" +#include "gles2application.h" +#include "IlmMatrix.h" +#include +#include +#include + +typedef struct t_shaderObject { + GLuint fragmentShaderId; + GLuint vertexShaderId; + GLuint shaderProgramId; + GLint matrixLocation; + GLint colorLocation; +} gles2Shader; + +typedef struct vertexBufferObject { + GLuint vbo; +} gles2VertexBuffer; + +static gles2Shader shader; +static gles2VertexBuffer vertexBuffer; + +// Fragment and vertex shaders code +const char * sourceFragShader = "\ + uniform mediump vec4 u_color;\ + void main (void)\ + {\ + gl_FragColor = u_color;\ + }"; + +const char * sourceVertShader = "\ + attribute highp vec4 a_vertex;\ + uniform mediump mat4 u_matrix;\ + void main(void)\ + {\ + gl_Position = u_matrix*a_vertex;\ + }"; + +GLfloat triangleVertexData[] = +{ + -0.4f, -0.4f, 0.0f, -0.2f, -0.4f, 0.0f, -0.3f, -0.2f, 0.0f, + -0.2f, -0.4f, 0.0f, -0.0f, -0.4f, 0.0f, -0.1f, -0.2f, 0.0f, + -0.0f, -0.4f, 0.0f, 0.2f, -0.4f, 0.0f, 0.1f, -0.2f, 0.0f, + 0.2f, -0.4f, 0.0f, 0.4f, -0.4f, 0.0f, 0.3f, -0.2f, 0.0f, + -0.3f, -0.2f, 0.0f, -0.1f, -0.2f, 0.0f, -0.2f, -0.0f, 0.0f, + 0.1f, -0.2f, 0.0f, 0.3f, -0.2f, 0.0f, 0.2f, -0.0f, 0.0f, + -0.2f, -0.0f, 0.0f, -0.0f, -0.0f, 0.0f, -0.1f, 0.2f, 0.0f, + 0.0f, -0.0f, 0.0f, 0.2f, -0.0f, 0.0f, 0.1f, 0.2f, 0.0f, + -0.1f, 0.2f, 0.0f, 0.1f, 0.2f, 0.0f, 0.0f, 0.4f, 0.0f +}; + +t_ilm_bool initGlApplication() +{ + if (!initShader()) { + return ILM_FALSE; + } + + if (!initVertexBuffer()) { + return ILM_FALSE; + } + + glClearColor(1.0f, 1.0f, 1.0f, 0.0f); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + return ILM_TRUE; +} + +t_ilm_bool initShader() +{ + t_ilm_bool result = ILM_TRUE; + + // Create the fragment shader object + shader.fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); + + // Load Fragment Source + glShaderSource(shader.fragmentShaderId, 1, (const char**) &sourceFragShader, NULL); + + // Compile the source code of fragment shader + glCompileShader(shader.fragmentShaderId); + + glGetShaderiv(shader.fragmentShaderId, GL_COMPILE_STATUS, (GLint*) &result); + + if (!result) { + t_ilm_int infoLength; + t_ilm_int numberChars; + glGetShaderiv(shader.fragmentShaderId, GL_INFO_LOG_LENGTH, &infoLength); + + // Allocate Log Space + char* info = (char*) malloc(sizeof(char) * infoLength); + glGetShaderInfoLog(shader.fragmentShaderId, infoLength, &numberChars, info); + + // Print the error + printf("Failed to compile fragment shader: %s\n", info); + free(info); + return ILM_FALSE; + } + + // Create the fragment shader object + shader.vertexShaderId = glCreateShader(GL_VERTEX_SHADER); + + // Load Fragment Source + glShaderSource(shader.vertexShaderId, 1, (const char**) &sourceVertShader, NULL); + + // Compile the source code of fragment shader + glCompileShader(shader.vertexShaderId); + + glGetShaderiv(shader.vertexShaderId, GL_COMPILE_STATUS, (GLint*) &result); + + if (!result) { + t_ilm_int infoLength; + t_ilm_int numberChars; + glGetShaderiv(shader.vertexShaderId, GL_INFO_LOG_LENGTH, &infoLength); + + // Allocate Log Space + char* info = (char*) malloc(sizeof(char) * infoLength); + glGetShaderInfoLog(shader.vertexShaderId, infoLength, &numberChars, info); + + // Print the error + printf("Failed to compile vertex shader: %s\n", info); + free(info); + return ILM_FALSE; + } + + shader.shaderProgramId = glCreateProgram(); + + glAttachShader(shader.shaderProgramId, shader.fragmentShaderId); + glAttachShader(shader.shaderProgramId, shader.vertexShaderId); + + glBindAttribLocation(shader.shaderProgramId, 0, "a_vertex"); + + glLinkProgram(shader.shaderProgramId); + + glGetProgramiv(shader.shaderProgramId, GL_LINK_STATUS, (GLint*) &result); + + if (!result) { + t_ilm_int infoLength; + t_ilm_int numberChars; + glGetShaderiv(shader.shaderProgramId, GL_INFO_LOG_LENGTH, &infoLength); + + // Allocate Log Space + char* info = (char*) malloc(sizeof(char) * infoLength); + glGetShaderInfoLog(shader.shaderProgramId, infoLength, &numberChars, + info); + + // Print the error + printf("Failed to link program: %s\n", info); + free(info); + return ILM_FALSE; + } + glUseProgram(shader.shaderProgramId); + shader.matrixLocation = glGetUniformLocation(shader.shaderProgramId, "u_matrix"); + shader.colorLocation = glGetUniformLocation(shader.shaderProgramId, "u_color"); + return result; +} + +t_ilm_bool destroyShader() +{ + t_ilm_bool result = ILM_TRUE; + glDeleteProgram(shader.shaderProgramId); + glDeleteShader(shader.fragmentShaderId); + glDeleteShader(shader.vertexShaderId); + return result; +} + +t_ilm_bool initVertexBuffer() +{ + t_ilm_bool result = ILM_TRUE; + + glGenBuffers(1, &vertexBuffer.vbo); + + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.vbo); + + unsigned int uiSize = 27 * (sizeof(GLfloat) * 3); // TODO: remove hard coded values + glBufferData(GL_ARRAY_BUFFER, uiSize, &triangleVertexData[0], GL_STATIC_DRAW); + + return result; +} + +void attachVertexBuffer() +{ + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.vbo); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); +} + +void detachVertexBuffer() +{ + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void destroyVertexBuffer() +{ + glDeleteBuffers(1, &vertexBuffer.vbo); +} + +void draw(t_ilm_uint animTime) +{ + static t_ilm_uint startTime = 0; + static t_ilm_uint currentTime = 0; + static float angle = 0; + IlmMatrix matrix; + + currentTime = GetTickCount(); + + if ((currentTime - startTime) > animTime) { + float currentAngle = 0; + int i = 0; + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(shader.shaderProgramId); + attachVertexBuffer(); + for (i = 10; i > 0; i--) { + currentAngle = angle - ((float) i) * 10.0f; + IlmMatrixIdentity(matrix); + IlmMatrixRotateZ(matrix, currentAngle); + float color[4] = { 0.0f, 1.0f, 1.0f, 0.5f + (0.3f / (float) i)}; + float lineColor[4] = { 0.0f, 0.0f, 0.0f, 0.5f + (0.4f / (float) i)}; + + glUniformMatrix4fv(shader.matrixLocation, 1, GL_FALSE, &matrix.f[0]); + glUniform4fv(shader.colorLocation, 1, &color[0]); + glDrawArrays(GL_TRIANGLES, 0, 27); // TODO: remove hard coded values + + glUniform4fv(shader.colorLocation, 1, &lineColor[0]); + int j = 0; + for (j = 0; j < 9; j++) { // TODO: remove hard coded values + glDrawArrays(GL_LINE_LOOP, j * 3, 3); // TODO: remove hard coded values + } + } + angle += 10.0f; + detachVertexBuffer(); + swapBuffers(); + startTime = currentTime; + } +} + +void destroyGlApplication() +{ + destroyShader(); + destroyVertexBuffer(); +} + -- 2.7.4