1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
15 #include "ppapi/c/pp_rect.h"
16 #include "ppapi/c/pp_size.h"
18 #include "ppapi_simple/ps_context_2d.h"
19 #include "ppapi_simple/ps_main.h"
27 // The goose sprites rotate in increments of 5 degrees.
28 const double kGooseHeadingIncrement
= (5.0 * M_PI
) / 180.0;
37 Sprite
* g_goose_sprite
;
38 std::vector
<Goose
> g_geese
;
39 std::vector
<Vector2
> g_attractors
;
42 void ResetFlock(PSContext2D_t
* ctx
, size_t count
) {
43 Vector2
center(0.5 * ctx
->width
, 0.5 * ctx
->height
);
45 g_geese
.resize(count
);
46 for (size_t i
= 0; i
< count
; i
++) {
47 double dx
= (double) rand() / (double) RAND_MAX
;
48 double dy
= (double) rand() / (double) RAND_MAX
;
49 g_geese
[i
] = Goose(center
, Vector2(dx
, dy
));
53 void Render(PSContext2D_t
* ctx
) {
54 PSContext2DGetBuffer(ctx
);
55 const size_t num_geese
= g_geese
.size();
57 if (NULL
== g_goose_sprite
) return;
58 if (NULL
== ctx
->data
) return;
61 memset(ctx
->data
, 0xFF, ctx
->stride
* ctx
->height
);
63 int32_t sprite_side_length
= g_goose_sprite
->size().height();
64 pp::Rect
sprite_src_rect(0, 0, sprite_side_length
, sprite_side_length
);
65 pp::Rect
canvas_bounds(pp::Size(ctx
->width
, ctx
->height
));
68 // Run the simulation for each goose.
69 for (size_t i
= 0; i
< num_geese
; i
++) {
70 Goose
& goose
= g_geese
[i
];
72 // Update position and orientation
73 goose
.SimulationTick(g_geese
, g_attractors
, canvas_bounds
);
74 pp::Point
dest_point(goose
.location().x() - sprite_side_length
/ 2,
75 goose
.location().y() - sprite_side_length
/ 2);
77 // Compute image to use
78 double heading
= goose
.velocity().Heading();
80 heading
= M_PI
* 2.0 + heading
;
82 int32_t sprite_index
=
83 static_cast<int32_t>(heading
/ kGooseHeadingIncrement
);
85 sprite_src_rect
.set_x(sprite_index
* sprite_side_length
);
86 g_goose_sprite
->CompositeFromRectToPoint(
88 ctx
->data
, canvas_bounds
, 0,
92 PSContext2DSwapBuffer(ctx
);
96 * Starting point for the module. We do not use main since it would
97 * collide with main in libppapi_cpp.
99 int example_main(int argc
, char *argv
[]) {
104 PSEventSetFilter(PSE_ALL
);
106 // Mount the images directory as an HTTP resource.
107 mount("images", "/images", "httpfs", 0, "");
109 FILE* fp
= fopen("/images/flock_green.raw", "rb");
110 fread(&fmt
, sizeof(fmt
), 1, fp
);
112 len
= fmt
.width
* fmt
.height
* fmt
.channels
;
113 buffer
= new uint32_t[len
];
114 fread(buffer
, 1, len
, fp
);
117 g_goose_sprite
= new Sprite(buffer
, pp::Size(fmt
.width
, fmt
.height
), 0);
119 PSContext2D_t
* ctx
= PSContext2DAllocate(PP_IMAGEDATAFORMAT_BGRA_PREMUL
);
124 // Consume all available events
125 while ((event
= PSEventTryAcquire()) != NULL
) {
126 PSContext2DHandleEvent(ctx
, event
);
127 PSEventRelease(event
);
133 // If not bound, wait for an event which may signal a context becoming
134 // available, instead of spinning.
135 event
= PSEventWaitAcquire();
136 if (PSContext2DHandleEvent(ctx
, event
))
138 PSEventRelease(event
);
146 * Register the function to call once the Instance Object is initialized.
147 * see: pappi_simple/ps_main.h
149 PPAPI_SIMPLE_REGISTER_MAIN(example_main
);