@@ -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) | ||||