| @@ -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: | |||
| # - linux-i386 | |||
| # - linux-amd64 | |||
| # - nacl-i386 | |||
| # - nacl-amd64 | |||
| # - ios-arm | |||
| # - osx-amd64 | |||
| @@ -119,9 +120,11 @@ configure() | |||
| cd monsterz/android | |||
| 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) | |||
| # 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) | |||
| 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) | |||
| LIBS="${save_LIBS}" | |||
| dnl Use SDL? (always required on Linux or Win32) | |||
| ac_cv_my_have_sdl="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") | |||
| 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? | |||
| ac_cv_my_have_egl="no" | |||
| 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/sdlinput.cpp platform/sdl/sdlinput.h | |||
| if USE_NACL | |||
| 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 | |||
| 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 | |||
| #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 | |||
| #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> | |||
| #endif | |||
| #if defined __native_client__ | |||
| # define main old_main | |||
| #endif | |||
| #if defined _WIN32 | |||
| # undef main /* FIXME: still needed? */ | |||
| #endif | |||
| @@ -59,7 +59,12 @@ public: | |||
| /* Window size decides the world aspect ratio. For instance, 640×480 | |||
| * will be mapped to (-0.66,-0.5) - (0.66,0.5). */ | |||
| #if !defined __native_client__ | |||
| 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) | |||
| m_window2world = 0.5 / m_window_size.y; | |||
| else | |||
| @@ -76,7 +81,11 @@ public: | |||
| m_dirty[i] = 2; | |||
| } | |||
| m_center = -0.75; | |||
| #if defined __CELLOS_LV2__ || defined __native_client__ | |||
| m_zoom_speed = -0.0025; | |||
| #else | |||
| m_zoom_speed = 0.0; | |||
| #endif | |||
| m_radius = 5.0; | |||
| m_ready = false; | |||
| @@ -100,9 +109,14 @@ public: | |||
| uint8_t red = r * 255.99f; | |||
| uint8_t green = g * 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->SetPos(ivec3(5, m_window_size.y - 15, 1)); | |||
| Ticker::Ref(m_centertext); | |||
| @@ -114,6 +128,7 @@ public: | |||
| m_zoomtext = new Text(NULL, "gfx/font/ascii.png"); | |||
| m_zoomtext->SetPos(ivec3(5, m_window_size.y - 43, 1)); | |||
| Ticker::Ref(m_zoomtext); | |||
| #endif | |||
| position = ivec3(0, 0, 0); | |||
| bbox[0] = position; | |||
| @@ -124,9 +139,11 @@ public: | |||
| ~Fractal() | |||
| { | |||
| Input::UntrackMouse(this); | |||
| #if !defined __native_client__ | |||
| Ticker::Unref(m_centertext); | |||
| Ticker::Unref(m_mousetext); | |||
| Ticker::Unref(m_zoomtext); | |||
| #endif | |||
| delete m_pixels; | |||
| delete m_tmppixels; | |||
| delete m_palette; | |||
| @@ -158,9 +175,7 @@ public: | |||
| f64cmplx worldmouse = m_center + ScreenToWorldOffset(mousepos); | |||
| 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) | |||
| { | |||
| double zoom = buttons[0] ? -0.0005 : 0.0005; | |||
| @@ -182,13 +197,20 @@ public: | |||
| double oldradius = m_radius; | |||
| double zoom = pow(2.0, deltams * m_zoom_speed); | |||
| if (m_radius * zoom > 8.0) | |||
| { | |||
| m_zoom_speed *= -1.0; | |||
| zoom = 8.0 / m_radius; | |||
| } | |||
| else if (m_radius * zoom < 1e-14) | |||
| { | |||
| m_zoom_speed *= -1.0; | |||
| zoom = 1e-14 / m_radius; | |||
| } | |||
| 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.65823419062254, .50221777363480); | |||
| #else | |||
| m_center = (m_center - worldmouse) * zoom + worldmouse; | |||
| 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]; | |||
| } | |||
| #if !defined __native_client__ | |||
| char buf[128]; | |||
| sprintf(buf, "center: %+16.14f%+16.14fi", m_center.x, m_center.y); | |||
| m_centertext->SetText(buf); | |||
| @@ -237,6 +260,7 @@ public: | |||
| m_mousetext->SetText(buf); | |||
| sprintf(buf, " zoom: %g", 1.0 / m_radius); | |||
| m_zoomtext->SetText(buf); | |||
| #endif | |||
| u8vec4 *m_pixelstart = m_pixels + m_size.x * m_size.y / 4 * m_frame; | |||
| @@ -284,7 +308,7 @@ public: | |||
| } | |||
| else | |||
| { | |||
| *m_pixelstart++ = u8vec4(0, 0, 0, 0); | |||
| *m_pixelstart++ = u8vec4(0, 0, 0, 255); | |||
| } | |||
| } | |||
| } | |||
| @@ -334,16 +358,35 @@ public: | |||
| m_shader = Shader::Create( | |||
| #if !defined __CELLOS_LV2__ | |||
| #if !defined HAVE_GLES_2X | |||
| "#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;" | |||
| "void main(void) {" | |||
| " 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" | |||
| #else | |||
| "precision highp float;" | |||
| #endif | |||
| "" | |||
| #if defined HAVE_GLES_2X | |||
| "varying vec2 pass_TexCoord;" | |||
| #endif | |||
| "uniform vec4 in_TexelSize;" | |||
| "uniform mat4 in_ZoomSettings;" | |||
| "uniform sampler2D in_Texture;" | |||
| @@ -411,7 +454,11 @@ public: | |||
| "}" | |||
| "" | |||
| "void main(void) {" | |||
| #if defined HAVE_GLES_2X | |||
| " vec2 coord = pass_TexCoord;" | |||
| #else | |||
| " vec2 coord = gl_TexCoord[0].xy;" | |||
| #endif | |||
| /* Slightly shift our pixel so that it does not lie at | |||
| * an exact texel boundary. This would lead to visual | |||
| * artifacts. */ | |||
| @@ -513,7 +560,9 @@ public: | |||
| /* FIXME: this object never cleans up */ | |||
| } | |||
| #if !defined HAVE_GLES_2X | |||
| glEnable(GL_TEXTURE_2D); | |||
| #endif | |||
| glBindTexture(GL_TEXTURE_2D, m_texid); | |||
| if (m_dirty[m_frame]) | |||
| @@ -598,7 +647,9 @@ private: | |||
| double m_deltascale[4]; | |||
| /* Debug information */ | |||
| #if !defined __native_client__ | |||
| Text *m_centertext, *m_mousetext, *m_zoomtext; | |||
| #endif | |||
| }; | |||
| int main(int argc, char **argv) | |||