diff options
Diffstat (limited to 'src/drivers/PicoAndroid')
5 files changed, 283 insertions, 57 deletions
diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.cxx b/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.cxx index 81fa3efab..fd042bef4 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.cxx +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.cxx @@ -20,10 +20,19 @@ #include "../../config_lib.h" #include "Fl_PicoAndroid_Graphics_Driver.h" +#include <jni.h> +#include <errno.h> + +#include <EGL/egl.h> +#include <GLES/gl.h> + +#include <android/log.h> +#include <android_native_app_glue.h> + #include <FL/Fl.H> -//#define __APPLE__ -//#include <SDL2/SDL.h> -//#undef __APPLE__ + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) + /* * By linking this module, the following static method will instatiate the @@ -35,31 +44,137 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() } -void Fl_PicoAndroid_Graphics_Driver::rectf(int x, int y, int w, int h) + + +static GLint vertices[][3] = { + { -0x10000, -0x10000, -0x10000 }, + { 0x10000, -0x10000, -0x10000 }, + { 0x10000, 0x10000, -0x10000 }, + { -0x10000, 0x10000, -0x10000 }, + { -0x10000, -0x10000, 0x10000 }, + { 0x10000, -0x10000, 0x10000 }, + { 0x10000, 0x10000, 0x10000 }, + { -0x10000, 0x10000, 0x10000 } +}; + +static GLint colors[][4] = { + { 0x00000, 0x00000, 0x00000, 0x10000 }, + { 0x10000, 0x00000, 0x00000, 0x10000 }, + { 0x10000, 0x10000, 0x00000, 0x10000 }, + { 0x00000, 0x10000, 0x00000, 0x10000 }, + { 0x00000, 0x00000, 0x10000, 0x10000 }, + { 0x10000, 0x00000, 0x10000, 0x10000 }, + { 0x10000, 0x10000, 0x10000, 0x10000 }, + { 0x00000, 0x10000, 0x10000, 0x10000 } +}; + +GLubyte indices[] = { + 0, 4, 5, 0, 5, 1, + 1, 5, 6, 1, 6, 2, + 2, 6, 7, 2, 7, 3, + 3, 7, 4, 3, 4, 0, + 4, 7, 6, 4, 6, 5, + 3, 0, 1, 3, 1, 2 +}; + +static void drawSomething() { -// uchar r, g, b; + /* + static float _angle = 0.0f; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -3.0f); + glRotatef(_angle, 0, 1, 0); + glRotatef(_angle*0.25f, 1, 0, 0); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glFrontFace(GL_CW); + glVertexPointer(3, GL_FIXED, 0, vertices); + glColorPointer(4, GL_FIXED, 0, colors); + glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices); + + _angle += 1.2f; + */ + + GLfloat q3[] = { + -10,-10, + 10,-10, + 10,10, + -10,10 + }; + + uchar r, g, b; + Fl::get_color(FL_RED, r, g, b); // Fl::get_color(Fl_Graphics_Driver::color(), r, g, b); -// SDL_SetRenderDrawColor((SDL_Renderer*)fl_window, r, g, b, SDL_ALPHA_OPAQUE); -// SDL_Rect rect = {x, y, w, h}; -// SDL_RenderFillRect((SDL_Renderer*)fl_window, &rect); + glColor4ub(r, g, b, 255); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, q3); + glDrawArrays(GL_TRIANGLE_FAN,0,4); + glDisableClientState(GL_VERTEX_ARRAY); +} + + + +void Fl_PicoAndroid_Graphics_Driver::rectf(int x, int y, int w, int h) +{ + GLfloat q3[] = { + x, y, + x, y+h-3, + x+w-3, y+h-3, + x+w-3, y + }; + + uchar r, g, b; + Fl::get_color(Fl_Graphics_Driver::color(), r, g, b); + glColor4ub(r, g, b, 255); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, q3); + glDrawArrays(GL_TRIANGLE_FAN,0,4); + glDisableClientState(GL_VERTEX_ARRAY); + + LOGI("Rect: %d %d %d %d", x, y, w, h); } void Fl_PicoAndroid_Graphics_Driver::line(int x, int y, int x1, int y1) { -// uchar r, g, b; -// Fl::get_color(Fl_Graphics_Driver::color(), r, g, b); -// SDL_SetRenderDrawColor((SDL_Renderer*)fl_window, r, g, b, SDL_ALPHA_OPAQUE); -// SDL_RenderDrawLine((SDL_Renderer*)fl_window, x, y, x1, y1); + GLfloat q3[] = { + x, y, + x1, y1 + }; + + uchar r, g, b; + Fl::get_color(Fl_Graphics_Driver::color(), r, g, b); + glColor4ub(r, g, b, 255); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, q3); + glDrawArrays(GL_LINES,0,2); + glDisableClientState(GL_VERTEX_ARRAY); } void Fl_PicoAndroid_Graphics_Driver::point(int x, int y) { -// uchar r, g, b; -// Fl::get_color(Fl_Graphics_Driver::color(), r, g, b); -// SDL_SetRenderDrawColor((SDL_Renderer*)fl_window, r, g, b, SDL_ALPHA_OPAQUE); -// SDL_RenderDrawPoint((SDL_Renderer*)fl_window, x, y); + GLfloat q3[] = { + x, y + }; + + uchar r, g, b; + Fl::get_color(Fl_Graphics_Driver::color(), r, g, b); + glColor4ub(r, g, b, 255); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_POINTS, 0, q3); + glDrawArrays(GL_LINES,0,1); + glDisableClientState(GL_VERTEX_ARRAY); } diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H index e9b10fb5a..b966312c9 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H @@ -30,20 +30,35 @@ #include <jni.h> #include <errno.h> +#include <EGL/egl.h> +#include <GLES/gl.h> + #include <android/sensor.h> #include <android/log.h> #include <android_native_app_glue.h> +class Fl_PicoAndroid_Window_Driver; + class FL_EXPORT Fl_PicoAndroid_Screen_Driver : public Fl_Pico_Screen_Driver { + friend class Fl_PicoAndroid_Window_Driver; + struct android_app* pApp; + EGLDisplay pDisplay; + EGLSurface pSurface; + EGLContext pContext; + int32_t pWidth; + int32_t pHeight; static void handleAppCmdCB(struct android_app* app, int32_t cmd); void handleAppCmd(struct android_app* app, int32_t cmd); static int32_t handleInputEventCB(struct android_app* app, AInputEvent* event); int32_t handleInputEvent(struct android_app* app, AInputEvent* event); + void initDisplay(); + void termDisplay(); + void drawFrame(); public: Fl_PicoAndroid_Screen_Driver(); diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx index 670c998f9..0e75a28b7 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx @@ -16,13 +16,12 @@ // http://www.fltk.org/str.php // +// http://developer.android.com/ndk/reference/group___native_activity.html + #include "../../config_lib.h" #include "Fl_PicoAndroid_Screen_Driver.H" -#include <EGL/egl.h> -#include <GLES/gl.h> - #include <FL/x.H> #include <FL/Fl.H> #include <FL/Fl_Window.H> @@ -30,12 +29,115 @@ #include <FL/Fl_Window_Driver.H> #include <FL/Fl_Image_Surface.H> #include <FL/Fl_Graphics_Driver.H> +#include <FL/fl_draw.h> #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__)) +void Fl_PicoAndroid_Screen_Driver::initDisplay() +{ + // initialize OpenGL ES and EGL + + /* + * Here specify the attributes of the desired configuration. + * Below, we select an EGLConfig with at least 8 bits per color + * component compatible with on-screen windows + */ + const EGLint attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_BLUE_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_RED_SIZE, 8, + EGL_NONE + }; + EGLint w, h, dummy, format; + EGLint numConfigs; + EGLConfig config; + EGLSurface surface; + EGLContext context; + + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + + eglInitialize(display, 0, 0); + + /* Here, the application chooses the configuration it desires. In this + * sample, we have a very simplified selection process, where we pick + * the first EGLConfig that matches our criteria */ + eglChooseConfig(display, attribs, &config, 1, &numConfigs); + + /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is + * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). + * As soon as we picked a EGLConfig, we can safely reconfigure the + * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ + eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); + + ANativeWindow_setBuffersGeometry(pApp->window, 0, 0, format); + + surface = eglCreateWindowSurface(display, config, pApp->window, NULL); + context = eglCreateContext(display, config, NULL, NULL); + + if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { + LOGW("Unable to eglMakeCurrent"); + return; + } + + eglQuerySurface(display, surface, EGL_WIDTH, &w); + eglQuerySurface(display, surface, EGL_HEIGHT, &h); + + this->pDisplay = display; + pContext = context; + pSurface = surface; + pWidth = w; + pHeight = h; + + // Initialize GL state. + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + glEnable(GL_CULL_FACE); + glShadeModel(GL_SMOOTH); + glDisable(GL_DEPTH_TEST); + + glViewport(0, 100, w, h-200); + + // make adjustments for screen ratio + float ratio = 3.0 * (float) w / h; + glMatrixMode(GL_PROJECTION); // set matrix to projection mode + glLoadIdentity(); // reset the matrix to its default state + // glFrustumf(-ratio, ratio, -3, 3, 3, 30); // apply the projection matrix + glOrthof(0, w/3, h/3, 0, -30, 30); // apply the projection matrix + glLineWidth(3); +} + + +void Fl_PicoAndroid_Screen_Driver::termDisplay() +{ + if (pDisplay != EGL_NO_DISPLAY) { + eglMakeCurrent(pDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (pContext != EGL_NO_CONTEXT) { + eglDestroyContext(pDisplay, pContext); + } + if (pSurface != EGL_NO_SURFACE) { + eglDestroySurface(pDisplay, pSurface); + } + eglTerminate(pDisplay); + } + pDisplay = EGL_NO_DISPLAY; + pContext = EGL_NO_CONTEXT; + pSurface = EGL_NO_SURFACE; +} + + +void Fl_PicoAndroid_Screen_Driver::drawFrame() +{ + if (pDisplay == NULL) { + return; + } + eglSwapBuffers(pDisplay, pSurface); + LOGI("Swapping buffers"); +} + + void Fl_PicoAndroid_Screen_Driver::handleAppCmdCB(struct android_app* app, int32_t cmd) { Fl_PicoAndroid_Screen_Driver *This = (Fl_PicoAndroid_Screen_Driver*)(app->userData); @@ -56,14 +158,14 @@ void Fl_PicoAndroid_Screen_Driver::handleAppCmd(struct android_app* app, int32_t break; case APP_CMD_INIT_WINDOW: // The window is being shown, get it ready. -// if (engine->app->window != NULL) { -// engine_init_display(engine); -// engine_draw_frame(engine); -// } + if (pApp->window != NULL) { + initDisplay(); + drawFrame(); + } break; case APP_CMD_TERM_WINDOW: // The window is being hidden or closed, clean it up. -// engine_term_display(engine); + termDisplay(); break; case APP_CMD_GAINED_FOCUS: // When our app gains focus, we start monitoring the accelerometer. @@ -103,6 +205,7 @@ int32_t Fl_PicoAndroid_Screen_Driver::handleInputEvent(struct android_app* app, int x = AMotionEvent_getX(event, 0); int y = AMotionEvent_getY(event, 0); LOGI("Motion at %d, %d", x, y); + Fl_X::first->w->redraw(); return 1; } return 0; @@ -222,6 +325,9 @@ Fl_Screen_Driver* Fl_Screen_Driver::newScreenDriver() Fl_PicoAndroid_Screen_Driver::Fl_PicoAndroid_Screen_Driver() { + pDisplay = EGL_NO_DISPLAY; + pContext = EGL_NO_CONTEXT; + pSurface = EGL_NO_SURFACE; } Fl_PicoAndroid_Screen_Driver::~Fl_PicoAndroid_Screen_Driver() @@ -232,33 +338,6 @@ Fl_PicoAndroid_Screen_Driver::~Fl_PicoAndroid_Screen_Driver() double Fl_PicoAndroid_Screen_Driver::wait(double time_to_wait) { Fl::flush(); -// SDL_Event e; -// if (SDL_PollEvent(&e)) { -// switch (e.type) { -// case SDL_QUIT: -// exit(0); -// case SDL_WINDOWEVENT_EXPOSED: -// case SDL_WINDOWEVENT_SHOWN: -// { // not happening! -// //event->window.windowID -// Fl_Window *window = Fl::first_window(); -// if ( !window ) break;; -// Fl_X *i = Fl_X::i(Fl::first_window()); -// i->wait_for_expose = 0; -// -// if ( i->region ) { -// XDestroyRegion(i->region); -// i->region = 0; -// } -// window->clear_damage(FL_DAMAGE_ALL); -// i->flush(); -// window->clear_damage(); -// Fl_X::first->wait_for_expose = 0; -// } -// break; -// -// } -// } // Read all pending events. int ident; int events; diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.H b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.H index 250280a12..adf0acbd3 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.H +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.H @@ -27,14 +27,13 @@ #include "../Pico/Fl_Pico_Window_Driver.H" -//#define __APPLE__ -//#include <SDL2/SDL.h> -//#undef __APPLE__ +#include <jni.h> +#include <android_native_app_glue.h> class FL_EXPORT Fl_PicoAndroid_Window_Driver : public Fl_Pico_Window_Driver { -// SDL_Window *pNativeWindow; + ANativeWindow *pNativeWindow; public: Fl_PicoAndroid_Window_Driver(Fl_Window *win); virtual ~Fl_PicoAndroid_Window_Driver(); diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx index 34001a695..6e06c85ab 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx @@ -20,6 +20,15 @@ #include "../../config_lib.h" #include "Fl_PicoAndroid_Window_Driver.H" +#include "Fl_PicoAndroid_Screen_Driver.H" + +#include <jni.h> +#include <errno.h> + +#include <android/sensor.h> +#include <android/log.h> +#include <android_native_app_glue.h> + #include <FL/x.H> #include <FL/Fl.H> #include <FL/Fl_Window.H> @@ -45,6 +54,8 @@ Fl_PicoAndroid_Window_Driver::~Fl_PicoAndroid_Window_Driver() Fl_X *Fl_PicoAndroid_Window_Driver::makeWindow() { + Fl_PicoAndroid_Screen_Driver *scr = (Fl_PicoAndroid_Screen_Driver*)Fl::screen_driver(); + Fl_Group::current(0); if (pWindow->parent() && !Fl_X::i(pWindow->window())) { pWindow->set_visible(); @@ -65,6 +76,7 @@ Fl_X *Fl_PicoAndroid_Window_Driver::makeWindow() } else { // pNativeWindow = SDL_CreateWindow(pWindow->label(), pWindow->x(), pWindow->y(), pWindow->w(), pWindow->h(), 0); } + pNativeWindow = scr->pApp->window; // x->xid = SDL_CreateRenderer(pNativeWindow, -1, SDL_RENDERER_ACCELERATED); x->next = Fl_X::first; x->wait_for_expose = 0; @@ -81,12 +93,18 @@ Fl_X *Fl_PicoAndroid_Window_Driver::makeWindow() return x; } +#include <FL/fl_draw.h> void Fl_PicoAndroid_Window_Driver::flush() { -// SDL_RenderClear((SDL_Renderer*)fl_window); + Fl_PicoAndroid_Screen_Driver *scr = (Fl_PicoAndroid_Screen_Driver*)Fl::screen_driver(); +// LOGI("Flush..."); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); pWindow->flush(); -// SDL_RenderPresent((SDL_Renderer*)fl_window); +// fl_color(FL_RED); +// fl_rectf(10, 10, 300, 400); + scr->drawFrame(); } |
