| @@ -0,0 +1,10 @@ | |||||
| #!/bin/sh | |||||
| # This can't hurt | |||||
| make distclean | |||||
| set -e | |||||
| ./build/lol-build bootstrap nacl-i386 | |||||
| ./build/lol-build configure nacl-i386 | |||||
| ./build/lol-build build nacl-i386 | |||||
| @@ -15,6 +15,7 @@ | |||||
| # And <platform> is one of: | # And <platform> is one of: | ||||
| # - linux-i386 | # - linux-i386 | ||||
| # - linux-amd64 | # - linux-amd64 | ||||
| # - nacl-i386 | |||||
| # - nacl-amd64 | # - nacl-amd64 | ||||
| # - ios-arm | # - ios-arm | ||||
| # - osx-amd64 | # - osx-amd64 | ||||
| @@ -119,9 +120,11 @@ configure() | |||||
| cd monsterz/android | cd monsterz/android | ||||
| android update project --path . | android update project --path . | ||||
| ;; | ;; | ||||
| nacl-i386) | |||||
| ./configure CXX=i686-nacl-g++ CC=i686-nacl-gcc ac_cv_exeext=.32.nexe --host=none LOL_LIBS="-lppapi -lppapi_gles2 -lppapi_cpp -u _ZN2pp12CreateModuleEv" | |||||
| ;; | |||||
| nacl-amd64) | nacl-amd64) | ||||
| # no need for "-u _ZN2pp12CreateModuleEv" but it could be helpful | |||||
| ./configure CXX=x86_64-nacl-g++ CC=x86_64-nacl-gcc ac_cv_exeext=.nexe --host=none LOL_LIBS="-lppapi -lppapi_gles2 -lppapi_cpp" | |||||
| ./configure CXX=x86_64-nacl-g++ CC=x86_64-nacl-gcc ac_cv_exeext=.64.nexe --host=none LOL_LIBS="-lppapi -lppapi_gles2 -lppapi_cpp -u _ZN2pp12CreateModuleEv" | |||||
| ;; | ;; | ||||
| ps3-ppu) | ps3-ppu) | ||||
| PATH="$PATH" ./configure CXX=ppu-lv2-g++ CC=ppu-lv2-gcc ac_cv_exeext=.elf --host=none | PATH="$PATH" ./configure CXX=ppu-lv2-g++ CC=ppu-lv2-gcc ac_cv_exeext=.elf --host=none | ||||
| @@ -191,6 +191,7 @@ LIBS="${LIBS} ${GL_LIBS} ${GLES2_LIBS}" | |||||
| AC_CHECK_FUNCS(glBegin) | AC_CHECK_FUNCS(glBegin) | ||||
| LIBS="${save_LIBS}" | LIBS="${save_LIBS}" | ||||
| dnl Use SDL? (always required on Linux or Win32) | dnl Use SDL? (always required on Linux or Win32) | ||||
| ac_cv_my_have_sdl="no" | ac_cv_my_have_sdl="no" | ||||
| ac_cv_my_have_sdl_image="no" | ac_cv_my_have_sdl_image="no" | ||||
| @@ -252,6 +253,13 @@ AM_CONDITIONAL(USE_SDL_MIXER, test "${ac_cv_my_have_sdl_mixer}" = "yes") | |||||
| AM_CONDITIONAL(USE_SDL_IMAGE, test "${ac_cv_my_have_sdl_image}" = "yes") | AM_CONDITIONAL(USE_SDL_IMAGE, test "${ac_cv_my_have_sdl_image}" = "yes") | ||||
| dnl Use NativeClient? | |||||
| ac_cv_my_have_nacl="no" | |||||
| AC_LANG_PUSH(C++) | |||||
| AC_CHECK_HEADERS(ppapi/cpp/instance.h, [ac_cv_my_have_nacl="yes"]) | |||||
| AC_LANG_POP(C++) | |||||
| AM_CONDITIONAL(USE_NACL, test "${ac_cv_my_have_nacl}" != "no") | |||||
| dnl Use EGL? | dnl Use EGL? | ||||
| ac_cv_my_have_egl="no" | ac_cv_my_have_egl="no" | ||||
| PKG_CHECK_MODULES(EGL, egl, [ac_cv_my_have_egl="yes"], [:]) | PKG_CHECK_MODULES(EGL, egl, [ac_cv_my_have_egl="yes"], [:]) | ||||
| @@ -43,8 +43,14 @@ sdl_sources = \ | |||||
| platform/sdl/sdlapp.cpp platform/sdl/sdlapp.h \ | platform/sdl/sdlapp.cpp platform/sdl/sdlapp.h \ | ||||
| platform/sdl/sdlinput.cpp platform/sdl/sdlinput.h | platform/sdl/sdlinput.cpp platform/sdl/sdlinput.h | ||||
| if USE_NACL | |||||
| nacl_sources = \ | nacl_sources = \ | ||||
| platform/nacl/naclapp.cpp platform/nacl/naclapp.h | |||||
| platform/nacl/naclapp.cpp platform/nacl/naclapp.h \ | |||||
| platform/nacl/nacl_instance.cpp platform/nacl/nacl_instance.h \ | |||||
| platform/nacl/nacl_module.cpp \ | |||||
| platform/nacl/opengl_context.cpp platform/nacl/opengl_context.h \ | |||||
| platform/nacl/opengl_context_ptrs.h | |||||
| endif | |||||
| if HAVE_PS3 | if HAVE_PS3 | ||||
| ps3_sources = \ | ps3_sources = \ | ||||
| @@ -0,0 +1,118 @@ | |||||
| // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #if defined HAVE_CONFIG_H | |||||
| # include "config.h" | |||||
| #endif | |||||
| #include <cstdlib> | |||||
| #include <cstdio> | |||||
| #include <cstring> | |||||
| #include <string> | |||||
| #include <vector> | |||||
| #include <ppapi/cpp/rect.h> | |||||
| #include <ppapi/cpp/size.h> | |||||
| #include <ppapi/cpp/var.h> | |||||
| #include <ppapi/cpp/module.h> | |||||
| #include <ppapi/cpp/completion_callback.h> | |||||
| #include "core.h" | |||||
| #include "debug/quad.h" | |||||
| #include "platform/nacl/nacl_instance.h" | |||||
| #include "platform/nacl/opengl_context.h" | |||||
| namespace lol | |||||
| { | |||||
| NaClInstance::NaClInstance(PP_Instance instance) | |||||
| : pp::Instance(instance), | |||||
| m_size(0, 0) | |||||
| { | |||||
| ; | |||||
| } | |||||
| NaClInstance::~NaClInstance() | |||||
| { | |||||
| // Destroy the cube view while GL context is current. | |||||
| opengl_context_->MakeContextCurrent(this); | |||||
| } | |||||
| static double const DELTA_MS = 1000.0 / 60.0; | |||||
| void TickCallback(void* data, int32_t result) | |||||
| { | |||||
| NaClInstance *instance = (NaClInstance *)data; | |||||
| instance->DrawSelf(); | |||||
| /* FIXME: only set if if Ticker isn't finished */ | |||||
| pp::Module::Get()->core()->CallOnMainThread( | |||||
| DELTA_MS, pp::CompletionCallback(&TickCallback, data), PP_OK); | |||||
| } | |||||
| } | |||||
| #define main OLDMAIN | |||||
| #include "../test/tutorial/tut03.cpp" | |||||
| #undef main | |||||
| namespace lol { | |||||
| bool NaClInstance::Init(uint32_t /* argc */, | |||||
| const char* /* argn */[], | |||||
| const char* /* argv */[]) | |||||
| { | |||||
| Ticker::Setup(60.0f); | |||||
| //new Kub(); | |||||
| //new DebugQuad(); | |||||
| new Fractal(ivec2(640, 480)); | |||||
| // My timer callback | |||||
| pp::Module::Get()->core()->CallOnMainThread( | |||||
| DELTA_MS, pp::CompletionCallback(&TickCallback, this), PP_OK); | |||||
| return true; | |||||
| } | |||||
| void NaClInstance::HandleMessage(const pp::Var& message) | |||||
| { | |||||
| if (!message.is_string()) | |||||
| return; | |||||
| /* FIXME: do some shit here */ | |||||
| } | |||||
| void NaClInstance::DidChangeView(const pp::Rect& position, const pp::Rect& clip) | |||||
| { | |||||
| if (position.size().width() == m_size.x && | |||||
| position.size().height() == m_size.y) | |||||
| return; // Size didn't change, no need to update anything. | |||||
| m_size = ivec2(position.size().width(), position.size().height()); | |||||
| if (opengl_context_ == NULL) | |||||
| opengl_context_.reset(new OpenGLContext(this)); | |||||
| opengl_context_->InvalidateContext(this); | |||||
| opengl_context_->ResizeContext(position.size()); | |||||
| if (!opengl_context_->MakeContextCurrent(this)) | |||||
| return; | |||||
| Video::Setup(m_size); | |||||
| DrawSelf(); | |||||
| } | |||||
| void NaClInstance::DrawSelf() | |||||
| { | |||||
| if (opengl_context_ == NULL) | |||||
| return; | |||||
| Ticker::ClampFps(); | |||||
| Ticker::TickGame(); | |||||
| opengl_context_->MakeContextCurrent(this); | |||||
| Ticker::TickDraw(); | |||||
| opengl_context_->FlushContext(); | |||||
| } | |||||
| } // namespace lol | |||||
| @@ -0,0 +1,53 @@ | |||||
| // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef EXAMPLES_TUMBLER_TUMBLER_H_ | |||||
| #define EXAMPLES_TUMBLER_TUMBLER_H_ | |||||
| #include <pthread.h> | |||||
| #include <map> | |||||
| #include <vector> | |||||
| #include <ppapi/cpp/instance.h> | |||||
| #include "platform/nacl/opengl_context.h" | |||||
| #include "platform/nacl/opengl_context_ptrs.h" | |||||
| namespace lol { | |||||
| class NaClInstance : public pp::Instance { | |||||
| public: | |||||
| explicit NaClInstance(PP_Instance instance); | |||||
| // The dtor makes the 3D context current before deleting the cube view, then | |||||
| // destroys the 3D context both in the module and in the browser. | |||||
| virtual ~NaClInstance(); | |||||
| // Called by the browser when the NaCl module is loaded and all ready to go. | |||||
| virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); | |||||
| // Called whenever the in-browser window changes size. | |||||
| virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip); | |||||
| // Called by the browser to handle the postMessage() call in Javascript. | |||||
| virtual void HandleMessage(const pp::Var& message); | |||||
| // Bind and publish the module's methods to JavaScript. | |||||
| //void InitializeMethods(ScriptingBridge* bridge); | |||||
| // Called to draw the contents of the module's browser area. | |||||
| void DrawSelf(); | |||||
| // private: | |||||
| // Browser connectivity and scripting support. | |||||
| // ScriptingBridge scripting_bridge_; | |||||
| SharedOpenGLContext opengl_context_; | |||||
| ivec2 m_size; | |||||
| }; | |||||
| } // namespace lol | |||||
| #endif // EXAMPLES_TUMBLER_TUMBLER_H_ | |||||
| @@ -0,0 +1,60 @@ | |||||
| // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #if defined HAVE_CONFIG_H | |||||
| # include "config.h" | |||||
| #endif | |||||
| #include <ppapi/cpp/instance.h> | |||||
| #include <ppapi/cpp/module.h> | |||||
| #include <ppapi/gles2/gl2ext_ppapi.h> | |||||
| #include "core.h" | |||||
| #include "lolgl.h" | |||||
| #include "platform/nacl/nacl_instance.h" | |||||
| /// The Module class. The browser calls the CreateInstance() method to create | |||||
| /// an instance of your NaCl module on the web page. The browser creates a new | |||||
| /// instance for each <embed> tag with type="application/x-nacl". | |||||
| class NaClModule : public pp::Module | |||||
| { | |||||
| public: | |||||
| NaClModule() : pp::Module() {} | |||||
| virtual ~NaClModule() | |||||
| { | |||||
| glTerminatePPAPI(); | |||||
| } | |||||
| /// Called by the browser when the module is first loaded and ready to run. | |||||
| /// This is called once per module, not once per instance of the module on | |||||
| /// the page. | |||||
| virtual bool Init() | |||||
| { | |||||
| return glInitializePPAPI(get_browser_interface()) == GL_TRUE; | |||||
| } | |||||
| /// Create and return a Lol instance object. | |||||
| /// @param[in] instance The browser-side instance. | |||||
| /// @return the plugin-side instance. | |||||
| virtual pp::Instance* CreateInstance(PP_Instance instance) | |||||
| { | |||||
| return new lol::NaClInstance(instance); | |||||
| } | |||||
| }; | |||||
| namespace pp | |||||
| { | |||||
| /// Factory function called by the browser when the module is first loaded. | |||||
| /// The browser keeps a singleton of this module. It calls the | |||||
| /// CreateInstance() method on the object you return to make instances. There | |||||
| /// is one instance per <embed> tag on the page. This is the main binding | |||||
| /// point for your NaCl module with the browser. | |||||
| Module* CreateModule() | |||||
| { | |||||
| return new NaClModule(); | |||||
| } | |||||
| } // namespace pp | |||||
| @@ -13,9 +13,9 @@ | |||||
| #endif | #endif | ||||
| #if defined __native_client__ | #if defined __native_client__ | ||||
| # include "ppapi/cpp/instance.h" | |||||
| # include "ppapi/cpp/module.h" | |||||
| # include "ppapi/cpp/var.h" | |||||
| # include <ppapi/cpp/instance.h> | |||||
| # include <ppapi/cpp/module.h> | |||||
| # include <ppapi/cpp/var.h> | |||||
| #endif | #endif | ||||
| #include "core.h" | #include "core.h" | ||||
| @@ -0,0 +1,90 @@ | |||||
| // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #if defined HAVE_CONFIG_H | |||||
| # include "config.h" | |||||
| #endif | |||||
| #include <pthread.h> | |||||
| #include <ppapi/cpp/completion_callback.h> | |||||
| #include <ppapi/gles2/gl2ext_ppapi.h> | |||||
| #include "core.h" | |||||
| #include "platform/nacl/opengl_context.h" | |||||
| namespace { | |||||
| // This is called by the brower when the 3D context has been flushed to the | |||||
| // browser window. | |||||
| void FlushCallback(void* data, int32_t result) { | |||||
| static_cast<lol::OpenGLContext*>(data)->set_flush_pending(false); | |||||
| } | |||||
| } // namespace | |||||
| namespace lol { | |||||
| OpenGLContext::OpenGLContext(pp::Instance* instance) | |||||
| : pp::Graphics3DClient(instance), | |||||
| flush_pending_(false) { | |||||
| pp::Module* module = pp::Module::Get(); | |||||
| assert(module); | |||||
| gles2_interface_ = static_cast<const struct PPB_OpenGLES2*>( | |||||
| module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)); | |||||
| assert(gles2_interface_); | |||||
| } | |||||
| OpenGLContext::~OpenGLContext() { | |||||
| glSetCurrentContextPPAPI(0); | |||||
| } | |||||
| bool OpenGLContext::MakeContextCurrent(pp::Instance* instance) { | |||||
| if (instance == NULL) { | |||||
| glSetCurrentContextPPAPI(0); | |||||
| return false; | |||||
| } | |||||
| // Lazily create the Pepper context. | |||||
| if (context_.is_null()) { | |||||
| int32_t attribs[] = { | |||||
| PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, | |||||
| PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24, | |||||
| PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8, | |||||
| PP_GRAPHICS3DATTRIB_SAMPLES, 0, | |||||
| PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, | |||||
| PP_GRAPHICS3DATTRIB_WIDTH, size_.width(), | |||||
| PP_GRAPHICS3DATTRIB_HEIGHT, size_.height(), | |||||
| PP_GRAPHICS3DATTRIB_NONE | |||||
| }; | |||||
| context_ = pp::Graphics3D(instance, pp::Graphics3D(), attribs); | |||||
| if (context_.is_null()) { | |||||
| glSetCurrentContextPPAPI(0); | |||||
| return false; | |||||
| } | |||||
| instance->BindGraphics(context_); | |||||
| } | |||||
| glSetCurrentContextPPAPI(context_.pp_resource()); | |||||
| return true; | |||||
| } | |||||
| void OpenGLContext::InvalidateContext(pp::Instance* instance) { | |||||
| glSetCurrentContextPPAPI(0); | |||||
| } | |||||
| void OpenGLContext::ResizeContext(const pp::Size& size) { | |||||
| size_ = size; | |||||
| if (!context_.is_null()) { | |||||
| context_.ResizeBuffers(size.width(), size.height()); | |||||
| } | |||||
| } | |||||
| void OpenGLContext::FlushContext() { | |||||
| if (flush_pending()) { | |||||
| // A flush is pending so do nothing; just drop this flush on the floor. | |||||
| return; | |||||
| } | |||||
| set_flush_pending(true); | |||||
| context_.SwapBuffers(pp::CompletionCallback(&FlushCallback, this)); | |||||
| } | |||||
| } // namespace lol | |||||
| @@ -0,0 +1,94 @@ | |||||
| // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef EXAMPLES_TUMBLER_OPENGL_CONTEXT_H_ | |||||
| #define EXAMPLES_TUMBLER_OPENGL_CONTEXT_H_ | |||||
| /// | |||||
| /// @file | |||||
| /// OpenGLContext manages the OpenGL context in the browser that is associated | |||||
| /// with a @a pp::Instance instance. | |||||
| /// | |||||
| #include <assert.h> | |||||
| #include <pthread.h> | |||||
| #include <algorithm> | |||||
| #include <string> | |||||
| #include <ppapi/c/ppb_opengles2.h> | |||||
| #include <ppapi/cpp/graphics_3d_client.h> | |||||
| #include <ppapi/cpp/graphics_3d.h> | |||||
| #include <ppapi/cpp/instance.h> | |||||
| #include <ppapi/cpp/size.h> | |||||
| #include "platform/nacl/opengl_context_ptrs.h" | |||||
| namespace lol { | |||||
| /// OpenGLContext manages an OpenGL rendering context in the browser. | |||||
| /// | |||||
| class OpenGLContext : public pp::Graphics3DClient { | |||||
| public: | |||||
| explicit OpenGLContext(pp::Instance* instance); | |||||
| /// Release all the in-browser resources used by this context, and make this | |||||
| /// context invalid. | |||||
| virtual ~OpenGLContext(); | |||||
| /// The Graphics3DClient interfcace. | |||||
| virtual void Graphics3DContextLost() { | |||||
| assert(!"Unexpectedly lost graphics context"); | |||||
| } | |||||
| /// Make @a this the current 3D context in @a instance. | |||||
| /// @param instance The instance of the NaCl module that will receive the | |||||
| /// the current 3D context. | |||||
| /// @return success. | |||||
| bool MakeContextCurrent(pp::Instance* instance); | |||||
| /// Flush the contents of this context to the browser's 3D device. | |||||
| void FlushContext(); | |||||
| /// Make the underlying 3D device invalid, so that any subsequent rendering | |||||
| /// commands will have no effect. The next call to MakeContextCurrent() will | |||||
| /// cause the underlying 3D device to get rebound and start receiving | |||||
| /// receiving rendering commands again. Use InvalidateContext(), for | |||||
| /// example, when resizing the context's viewing area. | |||||
| void InvalidateContext(pp::Instance* instance); | |||||
| /// Resize the context. | |||||
| void ResizeContext(const pp::Size& size); | |||||
| /// The OpenGL ES 2.0 interface. | |||||
| const struct PPB_OpenGLES2* gles2() const { | |||||
| return gles2_interface_; | |||||
| } | |||||
| /// The PP_Resource needed to make GLES2 calls through the Pepper interface. | |||||
| const PP_Resource gl_context() const { | |||||
| return context_.pp_resource(); | |||||
| } | |||||
| /// Indicate whether a flush is pending. This can only be called from the | |||||
| /// main thread; it is not thread safe. | |||||
| bool flush_pending() const { | |||||
| return flush_pending_; | |||||
| } | |||||
| void set_flush_pending(bool flag) { | |||||
| flush_pending_ = flag; | |||||
| } | |||||
| private: | |||||
| pp::Size size_; | |||||
| pp::Graphics3D context_; | |||||
| bool flush_pending_; | |||||
| const struct PPB_OpenGLES2* gles2_interface_; | |||||
| }; | |||||
| } // namespace lol | |||||
| #endif // EXAMPLES_TUMBLER_OPENGL_CONTEXT_H_ | |||||
| @@ -0,0 +1,22 @@ | |||||
| // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef EXAMPLES_TUMBLER_OPENGL_CONTEXT_PTRS_H_ | |||||
| #define EXAMPLES_TUMBLER_OPENGL_CONTEXT_PTRS_H_ | |||||
| // A convenience wrapper for a shared OpenGLContext pointer type. As other | |||||
| // smart pointer types are needed, add them here. | |||||
| #include <tr1/memory> | |||||
| namespace lol { | |||||
| class OpenGLContext; | |||||
| typedef std::tr1::shared_ptr<OpenGLContext> SharedOpenGLContext; | |||||
| } // namespace lol | |||||
| #endif // EXAMPLES_TUMBLER_OPENGL_CONTEXT_PTRS_H_ | |||||
| @@ -23,6 +23,10 @@ using namespace lol; | |||||
| # include <SDL_main.h> | # include <SDL_main.h> | ||||
| #endif | #endif | ||||
| #if defined __native_client__ | |||||
| # define main old_main | |||||
| #endif | |||||
| #if defined _WIN32 | #if defined _WIN32 | ||||
| # undef main /* FIXME: still needed? */ | # undef main /* FIXME: still needed? */ | ||||
| #endif | #endif | ||||
| @@ -59,7 +59,12 @@ public: | |||||
| /* Window size decides the world aspect ratio. For instance, 640×480 | /* Window size decides the world aspect ratio. For instance, 640×480 | ||||
| * will be mapped to (-0.66,-0.5) - (0.66,0.5). */ | * will be mapped to (-0.66,-0.5) - (0.66,0.5). */ | ||||
| #if !defined __native_client__ | |||||
| m_window_size = Video::GetSize(); | m_window_size = Video::GetSize(); | ||||
| #else | |||||
| /* FIXME: it's illegal to call this on the game thread! */ | |||||
| m_window_size = ivec2(640, 480); | |||||
| #endif | |||||
| if (m_window_size.y < m_window_size.x) | if (m_window_size.y < m_window_size.x) | ||||
| m_window2world = 0.5 / m_window_size.y; | m_window2world = 0.5 / m_window_size.y; | ||||
| else | else | ||||
| @@ -76,7 +81,11 @@ public: | |||||
| m_dirty[i] = 2; | m_dirty[i] = 2; | ||||
| } | } | ||||
| m_center = -0.75; | m_center = -0.75; | ||||
| #if defined __CELLOS_LV2__ || defined __native_client__ | |||||
| m_zoom_speed = -0.0025; | |||||
| #else | |||||
| m_zoom_speed = 0.0; | m_zoom_speed = 0.0; | ||||
| #endif | |||||
| m_radius = 5.0; | m_radius = 5.0; | ||||
| m_ready = false; | m_ready = false; | ||||
| @@ -100,9 +109,14 @@ public: | |||||
| uint8_t red = r * 255.99f; | uint8_t red = r * 255.99f; | ||||
| uint8_t green = g * 255.99f; | uint8_t green = g * 255.99f; | ||||
| uint8_t blue = b * 255.99f; | uint8_t blue = b * 255.99f; | ||||
| m_palette[i] = u8vec4(blue, green, red, 0); | |||||
| #if defined __native_client__ | |||||
| m_palette[i] = u8vec4(red, green, blue, 255); | |||||
| #else | |||||
| m_palette[i] = u8vec4(blue, green, red, 255); | |||||
| #endif | |||||
| } | } | ||||
| #if !defined __native_client__ | |||||
| m_centertext = new Text(NULL, "gfx/font/ascii.png"); | m_centertext = new Text(NULL, "gfx/font/ascii.png"); | ||||
| m_centertext->SetPos(ivec3(5, m_window_size.y - 15, 1)); | m_centertext->SetPos(ivec3(5, m_window_size.y - 15, 1)); | ||||
| Ticker::Ref(m_centertext); | Ticker::Ref(m_centertext); | ||||
| @@ -114,6 +128,7 @@ public: | |||||
| m_zoomtext = new Text(NULL, "gfx/font/ascii.png"); | m_zoomtext = new Text(NULL, "gfx/font/ascii.png"); | ||||
| m_zoomtext->SetPos(ivec3(5, m_window_size.y - 43, 1)); | m_zoomtext->SetPos(ivec3(5, m_window_size.y - 43, 1)); | ||||
| Ticker::Ref(m_zoomtext); | Ticker::Ref(m_zoomtext); | ||||
| #endif | |||||
| position = ivec3(0, 0, 0); | position = ivec3(0, 0, 0); | ||||
| bbox[0] = position; | bbox[0] = position; | ||||
| @@ -124,9 +139,11 @@ public: | |||||
| ~Fractal() | ~Fractal() | ||||
| { | { | ||||
| Input::UntrackMouse(this); | Input::UntrackMouse(this); | ||||
| #if !defined __native_client__ | |||||
| Ticker::Unref(m_centertext); | Ticker::Unref(m_centertext); | ||||
| Ticker::Unref(m_mousetext); | Ticker::Unref(m_mousetext); | ||||
| Ticker::Unref(m_zoomtext); | Ticker::Unref(m_zoomtext); | ||||
| #endif | |||||
| delete m_pixels; | delete m_pixels; | ||||
| delete m_tmppixels; | delete m_tmppixels; | ||||
| delete m_palette; | delete m_palette; | ||||
| @@ -158,9 +175,7 @@ public: | |||||
| f64cmplx worldmouse = m_center + ScreenToWorldOffset(mousepos); | f64cmplx worldmouse = m_center + ScreenToWorldOffset(mousepos); | ||||
| ivec3 buttons = Input::GetMouseButtons(); | ivec3 buttons = Input::GetMouseButtons(); | ||||
| #ifdef __CELLOS_LV2__ | |||||
| m_zoom_speed = 0.0005; | |||||
| #else | |||||
| #if !defined __CELLOS_LV2__ && !defined __native_client__ | |||||
| if ((buttons[0] || buttons[2]) && mousepos.x != -1) | if ((buttons[0] || buttons[2]) && mousepos.x != -1) | ||||
| { | { | ||||
| double zoom = buttons[0] ? -0.0005 : 0.0005; | double zoom = buttons[0] ? -0.0005 : 0.0005; | ||||
| @@ -182,13 +197,20 @@ public: | |||||
| double oldradius = m_radius; | double oldradius = m_radius; | ||||
| double zoom = pow(2.0, deltams * m_zoom_speed); | double zoom = pow(2.0, deltams * m_zoom_speed); | ||||
| if (m_radius * zoom > 8.0) | if (m_radius * zoom > 8.0) | ||||
| { | |||||
| m_zoom_speed *= -1.0; | |||||
| zoom = 8.0 / m_radius; | zoom = 8.0 / m_radius; | ||||
| } | |||||
| else if (m_radius * zoom < 1e-14) | else if (m_radius * zoom < 1e-14) | ||||
| { | |||||
| m_zoom_speed *= -1.0; | |||||
| zoom = 1e-14 / m_radius; | zoom = 1e-14 / m_radius; | ||||
| } | |||||
| m_radius *= zoom; | m_radius *= zoom; | ||||
| #ifdef __CELLOS_LV2__ | |||||
| m_center = f64cmplx(-.22815528839841, -1.11514249704382); | |||||
| #if defined __CELLOS_LV2__ || defined __native_client__ | |||||
| //m_center = f64cmplx(-.22815528839841, -1.11514249704382); | |||||
| //m_center = f64cmplx(0.001643721971153, 0.822467633298876); | //m_center = f64cmplx(0.001643721971153, 0.822467633298876); | ||||
| m_center = f64cmplx(-0.65823419062254, .50221777363480); | |||||
| #else | #else | ||||
| m_center = (m_center - worldmouse) * zoom + worldmouse; | m_center = (m_center - worldmouse) * zoom + worldmouse; | ||||
| worldmouse = m_center + ScreenToWorldOffset(mousepos); | worldmouse = m_center + ScreenToWorldOffset(mousepos); | ||||
| @@ -230,6 +252,7 @@ public: | |||||
| m_zoom_settings[cur_index][2] = m_zoom_settings[prev_index][2] * m_deltascale[cur_index]; | m_zoom_settings[cur_index][2] = m_zoom_settings[prev_index][2] * m_deltascale[cur_index]; | ||||
| } | } | ||||
| #if !defined __native_client__ | |||||
| char buf[128]; | char buf[128]; | ||||
| sprintf(buf, "center: %+16.14f%+16.14fi", m_center.x, m_center.y); | sprintf(buf, "center: %+16.14f%+16.14fi", m_center.x, m_center.y); | ||||
| m_centertext->SetText(buf); | m_centertext->SetText(buf); | ||||
| @@ -237,6 +260,7 @@ public: | |||||
| m_mousetext->SetText(buf); | m_mousetext->SetText(buf); | ||||
| sprintf(buf, " zoom: %g", 1.0 / m_radius); | sprintf(buf, " zoom: %g", 1.0 / m_radius); | ||||
| m_zoomtext->SetText(buf); | m_zoomtext->SetText(buf); | ||||
| #endif | |||||
| u8vec4 *m_pixelstart = m_pixels + m_size.x * m_size.y / 4 * m_frame; | u8vec4 *m_pixelstart = m_pixels + m_size.x * m_size.y / 4 * m_frame; | ||||
| @@ -284,7 +308,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| *m_pixelstart++ = u8vec4(0, 0, 0, 0); | |||||
| *m_pixelstart++ = u8vec4(0, 0, 0, 255); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -334,16 +358,35 @@ public: | |||||
| m_shader = Shader::Create( | m_shader = Shader::Create( | ||||
| #if !defined __CELLOS_LV2__ | #if !defined __CELLOS_LV2__ | ||||
| #if !defined HAVE_GLES_2X | |||||
| "#version 120\n" | "#version 120\n" | ||||
| "attribute vec2 in_TexCoord;\n" | |||||
| #else | |||||
| "precision highp float;" | |||||
| #endif | |||||
| "" | |||||
| #if defined HAVE_GLES_2X | |||||
| "varying vec2 pass_TexCoord;" | |||||
| #endif | |||||
| "attribute vec2 in_TexCoord;" | |||||
| "attribute vec2 in_Vertex;" | "attribute vec2 in_Vertex;" | ||||
| "void main(void) {" | "void main(void) {" | ||||
| " gl_Position = vec4(in_Vertex, 0.0, 1.0);" | " gl_Position = vec4(in_Vertex, 0.0, 1.0);" | ||||
| " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n" | |||||
| #if defined HAVE_GLES_2X | |||||
| " pass_TexCoord = in_TexCoord;" | |||||
| #else | |||||
| " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);" | |||||
| #endif | |||||
| "}", | "}", | ||||
| #if !defined HAVE_GLES_2X | |||||
| "#version 120\n" | "#version 120\n" | ||||
| #else | |||||
| "precision highp float;" | |||||
| #endif | |||||
| "" | "" | ||||
| #if defined HAVE_GLES_2X | |||||
| "varying vec2 pass_TexCoord;" | |||||
| #endif | |||||
| "uniform vec4 in_TexelSize;" | "uniform vec4 in_TexelSize;" | ||||
| "uniform mat4 in_ZoomSettings;" | "uniform mat4 in_ZoomSettings;" | ||||
| "uniform sampler2D in_Texture;" | "uniform sampler2D in_Texture;" | ||||
| @@ -411,7 +454,11 @@ public: | |||||
| "}" | "}" | ||||
| "" | "" | ||||
| "void main(void) {" | "void main(void) {" | ||||
| #if defined HAVE_GLES_2X | |||||
| " vec2 coord = pass_TexCoord;" | |||||
| #else | |||||
| " vec2 coord = gl_TexCoord[0].xy;" | " vec2 coord = gl_TexCoord[0].xy;" | ||||
| #endif | |||||
| /* Slightly shift our pixel so that it does not lie at | /* Slightly shift our pixel so that it does not lie at | ||||
| * an exact texel boundary. This would lead to visual | * an exact texel boundary. This would lead to visual | ||||
| * artifacts. */ | * artifacts. */ | ||||
| @@ -513,7 +560,9 @@ public: | |||||
| /* FIXME: this object never cleans up */ | /* FIXME: this object never cleans up */ | ||||
| } | } | ||||
| #if !defined HAVE_GLES_2X | |||||
| glEnable(GL_TEXTURE_2D); | glEnable(GL_TEXTURE_2D); | ||||
| #endif | |||||
| glBindTexture(GL_TEXTURE_2D, m_texid); | glBindTexture(GL_TEXTURE_2D, m_texid); | ||||
| if (m_dirty[m_frame]) | if (m_dirty[m_frame]) | ||||
| @@ -598,7 +647,9 @@ private: | |||||
| double m_deltascale[4]; | double m_deltascale[4]; | ||||
| /* Debug information */ | /* Debug information */ | ||||
| #if !defined __native_client__ | |||||
| Text *m_centertext, *m_mousetext, *m_zoomtext; | Text *m_centertext, *m_mousetext, *m_zoomtext; | ||||
| #endif | |||||
| }; | }; | ||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||