summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authorbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-19 16:52:37 +0000
committerbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-19 16:52:37 +0000
commit6243aa16ff0c14fb1df4b6dc63db262bed067c83 (patch)
treea0a9ad932f7cdf19a12f6a2ab974b01b4c257526 /native_client_sdk
parent36fc6ac1d42146f01a2ff7545ec32f1903c745f9 (diff)
downloadchromium_src-6243aa16ff0c14fb1df4b6dc63db262bed067c83.zip
chromium_src-6243aa16ff0c14fb1df4b6dc63db262bed067c83.tar.gz
chromium_src-6243aa16ff0c14fb1df4b6dc63db262bed067c83.tar.bz2
[NaCl SDK] Add simple graphics2d example.
BUG=none R=sbc@chromium.org, noelallen@chromium.org Review URL: https://codereview.chromium.org/28613002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229587 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/src/build_tools/sdk_files.list1
-rw-r--r--native_client_sdk/src/examples/api/graphics_2d/example.dsc17
-rw-r--r--native_client_sdk/src/examples/api/graphics_2d/graphics_2d.cc253
-rw-r--r--native_client_sdk/src/examples/api/graphics_2d/index.html23
4 files changed, 294 insertions, 0 deletions
diff --git a/native_client_sdk/src/build_tools/sdk_files.list b/native_client_sdk/src/build_tools/sdk_files.list
index 9bcd608..3fea6cc 100644
--- a/native_client_sdk/src/build_tools/sdk_files.list
+++ b/native_client_sdk/src/build_tools/sdk_files.list
@@ -4,6 +4,7 @@ examples/api/audio/*
examples/api/core/*
examples/api/file_io/*
examples/api/gamepad/*
+examples/api/graphics_2d/*
examples/api/graphics_3d/*
examples/api/input_event/*
[win]examples/api/make.bat
diff --git a/native_client_sdk/src/examples/api/graphics_2d/example.dsc b/native_client_sdk/src/examples/api/graphics_2d/example.dsc
new file mode 100644
index 0000000..a9b31c77
--- /dev/null
+++ b/native_client_sdk/src/examples/api/graphics_2d/example.dsc
@@ -0,0 +1,17 @@
+{
+ 'TOOLS': ['newlib', 'glibc', 'pnacl', 'win', 'linux'],
+ 'TARGETS': [
+ {
+ 'NAME' : 'graphics_2d',
+ 'TYPE' : 'main',
+ 'SOURCES' : [
+ 'graphics_2d.cc',
+ ],
+ 'LIBS': ['ppapi_cpp', 'ppapi', 'pthread']
+ }
+ ],
+ 'DEST': 'examples/api',
+ 'NAME': 'graphics_2d',
+ 'TITLE': 'Graphics 2D',
+ 'GROUP': 'API'
+}
diff --git a/native_client_sdk/src/examples/api/graphics_2d/graphics_2d.cc b/native_client_sdk/src/examples/api/graphics_2d/graphics_2d.cc
new file mode 100644
index 0000000..10b1609
--- /dev/null
+++ b/native_client_sdk/src/examples/api/graphics_2d/graphics_2d.cc
@@ -0,0 +1,253 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ppapi/c/ppb_image_data.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/input_event.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/utility/completion_callback_factory.h"
+
+#ifdef WIN32
+#undef PostMessage
+// Allow 'this' in initializer list
+#pragma warning(disable : 4355)
+#endif
+
+namespace {
+
+static const int kMouseRadius = 20;
+
+uint8_t RandUint8(uint8_t min, uint8_t max) {
+ uint64_t r = rand();
+ uint8_t result = static_cast<uint8_t>(r * (max - min + 1) / RAND_MAX) + min;
+ return result;
+}
+
+uint32_t MakeColor(uint8_t r, uint8_t g, uint8_t b) {
+ uint8_t a = 255;
+ PP_ImageDataFormat format = pp::ImageData::GetNativeImageDataFormat();
+ if (format == PP_IMAGEDATAFORMAT_BGRA_PREMUL) {
+ return (a << 24) | (r << 16) | (g << 8) | b;
+ } else {
+ return (a << 24) | (b << 16) | (g << 8) | r;
+ }
+}
+
+} // namespace
+
+
+class Graphics2DInstance : public pp::Instance {
+ public:
+ explicit Graphics2DInstance(PP_Instance instance)
+ : pp::Instance(instance),
+ callback_factory_(this),
+ mouse_down_(false),
+ buffer_(NULL) {}
+
+ ~Graphics2DInstance() {
+ delete[] buffer_;
+ }
+
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
+
+ unsigned int seed = 1;
+ srand(seed);
+ CreatePalette();
+ return true;
+ }
+
+ virtual void DidChangeView(const pp::View& view) {
+ pp::Size new_size = view.GetRect().size();
+ bool had_context = !context_.is_null();
+
+ if (!CreateContext(new_size)) {
+ // failed.
+ return;
+ }
+
+ if (!had_context) {
+ MainLoop(0);
+ }
+ }
+
+ virtual bool HandleInputEvent(const pp::InputEvent& event) {
+ if (!buffer_)
+ return true;
+
+ if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN ||
+ event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE) {
+ pp::MouseInputEvent mouse_event(event);
+
+ if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_NONE)
+ return true;
+
+ mouse_ = mouse_event.GetPosition();
+ mouse_down_ = true;
+ }
+
+ if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP) {
+ mouse_down_ = false;
+ }
+
+ return true;
+ }
+
+ private:
+ void CreatePalette() {
+ for (int i = 0; i < 64; ++i) {
+ // Black -> Red
+ palette_[i] = MakeColor(i * 2, 0, 0);
+ palette_[i + 64] = MakeColor(128 + i * 2, 0, 0);
+ // Red -> Yellow
+ palette_[i + 128] = MakeColor(255, i * 4, 0);
+ // Yellow -> White
+ palette_[i + 192] = MakeColor(255, 255, i * 4);
+ }
+ }
+
+ bool CreateContext(const pp::Size& new_size) {
+ const bool kIsAlwaysOpaque = true;
+ context_ = pp::Graphics2D(this, new_size, kIsAlwaysOpaque);
+ if (!BindGraphics(context_)) {
+ fprintf(stderr, "Unable to bind 2d context!\n");
+ context_ = pp::Graphics2D();
+ return false;
+ }
+
+ // Create an ImageData object we can draw to that is the same size as the
+ // Graphics2D context.
+ const bool kInitToZero = true;
+ PP_ImageDataFormat format = pp::ImageData::GetNativeImageDataFormat();
+ image_data_ = pp::ImageData(this, format, new_size, kInitToZero);
+
+ // Allocate a buffer of palette entries of the same size.
+ buffer_ = new uint8_t[new_size.width() * new_size.height()];
+
+ return true;
+ }
+
+ void Update() {
+ // Old-school fire technique cribbed from
+ // http://ionicsolutions.net/2011/12/30/demo-fire-effect/
+ UpdateCoals();
+ DrawMouse();
+ UpdateFlames();
+ }
+
+ void UpdateCoals() {
+ const pp::Size& size = image_data_.size();
+ int width = size.width();
+ int height = size.height();
+ size_t span = 0;
+
+ // Draw two rows of random values at the bottom.
+ for (int y = height - 2; y < height; ++y) {
+ size_t offset = y * width;
+ for (int x = 0; x < width; ++x) {
+ // On a random chance, draw some longer strips of brighter colors.
+ if (span || RandUint8(1, 4) == 1) {
+ if (!span)
+ span = RandUint8(10, 20);
+ buffer_[offset + x] = RandUint8(128, 255);
+ span--;
+ } else {
+ buffer_[offset + x] = RandUint8(32, 96);
+ }
+ }
+ }
+ }
+
+ void UpdateFlames() {
+ const pp::Size& size = image_data_.size();
+ int width = size.width();
+ int height = size.height();
+ for (int y = 1; y < height - 1; ++y) {
+ size_t offset = y * width;
+ for (int x = 1; x < width - 1; ++x) {
+ int sum = 0;
+ sum += buffer_[offset - width + x - 1];
+ sum += buffer_[offset - width + x + 1];
+ sum += buffer_[offset + x - 1];
+ sum += buffer_[offset + x + 1];
+ sum += buffer_[offset + width + x - 1];
+ sum += buffer_[offset + width + x];
+ sum += buffer_[offset + width + x + 1];
+ buffer_[offset - width + x] = sum / 7;
+ }
+ }
+ }
+
+ void DrawMouse() {
+ if (!mouse_down_)
+ return;
+
+ const pp::Size& size = image_data_.size();
+ int width = size.width();
+ int height = size.height();
+
+ // Draw a circle at the mouse position.
+ int radius = kMouseRadius;
+ int cx = mouse_.x();
+ int cy = mouse_.y();
+ int minx = cx - radius <= 0 ? 1 : cx - radius;
+ int maxx = cx + radius >= width ? width - 1 : cx + radius;
+ int miny = cy - radius <= 0 ? 1 : cy - radius;
+ int maxy = cy + radius >= height ? height - 1 : cy + radius;
+ for (int y = miny; y < maxy; ++y) {
+ for (int x = minx; x < maxx; ++x) {
+ if ((x - cx) * (x - cx) + (y - cy) * (y - cy) < radius * radius) {
+ buffer_[y * width + x] = RandUint8(192, 255);
+ }
+ }
+ }
+ }
+
+ void Paint() {
+ const pp::Size& size = image_data_.size();
+ uint32_t* data = static_cast<uint32_t*>(image_data_.data());
+ uint32_t num_pixels = size.width() * size.height();
+ size_t offset = 0;
+ for (uint32_t i = 0; i < num_pixels; ++i) {
+ data[offset] = palette_[buffer_[offset]];
+ offset++;
+ }
+ context_.PaintImageData(image_data_, pp::Point());
+ }
+
+ void MainLoop(int32_t) {
+ Update();
+ Paint();
+ context_.Flush(
+ callback_factory_.NewCallback(&Graphics2DInstance::MainLoop));
+ }
+
+ pp::CompletionCallbackFactory<Graphics2DInstance> callback_factory_;
+ pp::Graphics2D context_;
+ pp::ImageData image_data_;
+ pp::Point mouse_;
+ bool mouse_down_;
+ uint8_t* buffer_;
+ uint32_t palette_[256];
+};
+
+class Graphics2DModule : public pp::Module {
+ public:
+ Graphics2DModule() : pp::Module() {}
+ virtual ~Graphics2DModule() {}
+
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new Graphics2DInstance(instance);
+ }
+};
+
+namespace pp {
+Module* CreateModule() { return new Graphics2DModule(); }
+} // namespace pp
diff --git a/native_client_sdk/src/examples/api/graphics_2d/index.html b/native_client_sdk/src/examples/api/graphics_2d/index.html
new file mode 100644
index 0000000..f667472
--- /dev/null
+++ b/native_client_sdk/src/examples/api/graphics_2d/index.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<!--
+Copyright (c) 2012 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<head>
+ <meta http-equiv="Pragma" content="no-cache">
+ <meta http-equiv="Expires" content="-1">
+ <title>{{title}}</title>
+ <script type="text/javascript" src="common.js"></script>
+</head>
+<body data-width="500" data-height="500" {{attrs}}>
+ <h1>{{title}}</h1>
+ <h2>Status: <code id="statusField">NO-STATUS</code></h2>
+ <p>The Graphics2D example demonstrates a simple flame effect.</p>
+ <p>Click and hold to add a flame.</p>
+ <!-- The NaCl plugin will be embedded inside the element with id "listener".
+ See common.js.-->
+ <div id="listener"></div>
+</body>
+</html>