1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker #include "SampleApplication.h"
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
10*8975f5c5SAndroid Build Coastguard Worker #include <cmath>
11*8975f5c5SAndroid Build Coastguard Worker #include <vector>
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard Worker #include "util/Matrix.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "util/random_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker class MultiWindowSample : public SampleApplication
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker public:
MultiWindowSample(int argc,char ** argv)22*8975f5c5SAndroid Build Coastguard Worker MultiWindowSample(int argc, char **argv)
23*8975f5c5SAndroid Build Coastguard Worker : SampleApplication("MultiWindow", argc, argv, ClientType::ES2, 256, 256)
24*8975f5c5SAndroid Build Coastguard Worker {}
25*8975f5c5SAndroid Build Coastguard Worker
initialize()26*8975f5c5SAndroid Build Coastguard Worker bool initialize() override
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(attribute vec4 vPosition;
29*8975f5c5SAndroid Build Coastguard Worker void main()
30*8975f5c5SAndroid Build Coastguard Worker {
31*8975f5c5SAndroid Build Coastguard Worker gl_Position = vPosition;
32*8975f5c5SAndroid Build Coastguard Worker })";
33*8975f5c5SAndroid Build Coastguard Worker
34*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(precision mediump float;
35*8975f5c5SAndroid Build Coastguard Worker void main()
36*8975f5c5SAndroid Build Coastguard Worker {
37*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
38*8975f5c5SAndroid Build Coastguard Worker })";
39*8975f5c5SAndroid Build Coastguard Worker
40*8975f5c5SAndroid Build Coastguard Worker mProgram = CompileProgram(kVS, kFS);
41*8975f5c5SAndroid Build Coastguard Worker if (!mProgram)
42*8975f5c5SAndroid Build Coastguard Worker {
43*8975f5c5SAndroid Build Coastguard Worker return false;
44*8975f5c5SAndroid Build Coastguard Worker }
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker // Set an initial rotation
47*8975f5c5SAndroid Build Coastguard Worker mRotation = 45.0f;
48*8975f5c5SAndroid Build Coastguard Worker
49*8975f5c5SAndroid Build Coastguard Worker glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker window rootWindow;
52*8975f5c5SAndroid Build Coastguard Worker rootWindow.osWindow = getWindow();
53*8975f5c5SAndroid Build Coastguard Worker rootWindow.surface = getSurface();
54*8975f5c5SAndroid Build Coastguard Worker mWindows.push_back(rootWindow);
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker const size_t numWindows = 5;
57*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 1; i < numWindows; i++)
58*8975f5c5SAndroid Build Coastguard Worker {
59*8975f5c5SAndroid Build Coastguard Worker window window;
60*8975f5c5SAndroid Build Coastguard Worker
61*8975f5c5SAndroid Build Coastguard Worker window.osWindow = OSWindow::New();
62*8975f5c5SAndroid Build Coastguard Worker if (!window.osWindow->initialize("MultiWindow", 256, 256))
63*8975f5c5SAndroid Build Coastguard Worker {
64*8975f5c5SAndroid Build Coastguard Worker return false;
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker window.surface = eglCreateWindowSurface(getDisplay(), getConfig(),
68*8975f5c5SAndroid Build Coastguard Worker window.osWindow->getNativeWindow(), nullptr);
69*8975f5c5SAndroid Build Coastguard Worker if (window.surface == EGL_NO_SURFACE)
70*8975f5c5SAndroid Build Coastguard Worker {
71*8975f5c5SAndroid Build Coastguard Worker return false;
72*8975f5c5SAndroid Build Coastguard Worker }
73*8975f5c5SAndroid Build Coastguard Worker
74*8975f5c5SAndroid Build Coastguard Worker window.osWindow->setVisible(true);
75*8975f5c5SAndroid Build Coastguard Worker
76*8975f5c5SAndroid Build Coastguard Worker mWindows.push_back(window);
77*8975f5c5SAndroid Build Coastguard Worker }
78*8975f5c5SAndroid Build Coastguard Worker
79*8975f5c5SAndroid Build Coastguard Worker int baseX = rootWindow.osWindow->getX();
80*8975f5c5SAndroid Build Coastguard Worker int baseY = rootWindow.osWindow->getY();
81*8975f5c5SAndroid Build Coastguard Worker for (auto &window : mWindows)
82*8975f5c5SAndroid Build Coastguard Worker {
83*8975f5c5SAndroid Build Coastguard Worker int x = baseX + mRNG.randomIntBetween(0, 512);
84*8975f5c5SAndroid Build Coastguard Worker int y = baseY + mRNG.randomIntBetween(0, 512);
85*8975f5c5SAndroid Build Coastguard Worker int width = mRNG.randomIntBetween(128, 512);
86*8975f5c5SAndroid Build Coastguard Worker int height = mRNG.randomIntBetween(128, 512);
87*8975f5c5SAndroid Build Coastguard Worker window.osWindow->setPosition(x, y);
88*8975f5c5SAndroid Build Coastguard Worker window.osWindow->resize(width, height);
89*8975f5c5SAndroid Build Coastguard Worker }
90*8975f5c5SAndroid Build Coastguard Worker
91*8975f5c5SAndroid Build Coastguard Worker return true;
92*8975f5c5SAndroid Build Coastguard Worker }
93*8975f5c5SAndroid Build Coastguard Worker
destroy()94*8975f5c5SAndroid Build Coastguard Worker void destroy() override { glDeleteProgram(mProgram); }
95*8975f5c5SAndroid Build Coastguard Worker
step(float dt,double totalTime)96*8975f5c5SAndroid Build Coastguard Worker void step(float dt, double totalTime) override
97*8975f5c5SAndroid Build Coastguard Worker {
98*8975f5c5SAndroid Build Coastguard Worker mRotation = fmod(mRotation + (dt * 40.0f), 360.0f);
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker for (auto &window : mWindows)
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker window.osWindow->messageLoop();
103*8975f5c5SAndroid Build Coastguard Worker }
104*8975f5c5SAndroid Build Coastguard Worker }
105*8975f5c5SAndroid Build Coastguard Worker
draw()106*8975f5c5SAndroid Build Coastguard Worker void draw() override
107*8975f5c5SAndroid Build Coastguard Worker {
108*8975f5c5SAndroid Build Coastguard Worker OSWindow *rootWindow = mWindows[0].osWindow;
109*8975f5c5SAndroid Build Coastguard Worker int left = rootWindow->getX();
110*8975f5c5SAndroid Build Coastguard Worker int right = rootWindow->getX() + rootWindow->getWidth();
111*8975f5c5SAndroid Build Coastguard Worker int top = rootWindow->getY();
112*8975f5c5SAndroid Build Coastguard Worker int bottom = rootWindow->getY() + rootWindow->getHeight();
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker for (auto &windowRecord : mWindows)
115*8975f5c5SAndroid Build Coastguard Worker {
116*8975f5c5SAndroid Build Coastguard Worker OSWindow *window = windowRecord.osWindow;
117*8975f5c5SAndroid Build Coastguard Worker left = std::min(left, window->getX());
118*8975f5c5SAndroid Build Coastguard Worker right = std::max(right, window->getX() + window->getWidth());
119*8975f5c5SAndroid Build Coastguard Worker top = std::min(top, window->getY());
120*8975f5c5SAndroid Build Coastguard Worker bottom = std::max(bottom, window->getY() + window->getHeight());
121*8975f5c5SAndroid Build Coastguard Worker }
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker float midX = (left + right) * 0.5f;
124*8975f5c5SAndroid Build Coastguard Worker float midY = (top + bottom) * 0.5f;
125*8975f5c5SAndroid Build Coastguard Worker
126*8975f5c5SAndroid Build Coastguard Worker Matrix4 modelMatrix = Matrix4::translate(Vector3(midX, midY, 0.0f)) *
127*8975f5c5SAndroid Build Coastguard Worker Matrix4::rotate(mRotation, Vector3(0.0f, 0.0f, 1.0f)) *
128*8975f5c5SAndroid Build Coastguard Worker Matrix4::translate(Vector3(-midX, -midY, 0.0f));
129*8975f5c5SAndroid Build Coastguard Worker Matrix4 viewMatrix = Matrix4::identity();
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker for (auto &windowRecord : mWindows)
132*8975f5c5SAndroid Build Coastguard Worker {
133*8975f5c5SAndroid Build Coastguard Worker OSWindow *window = windowRecord.osWindow;
134*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface = windowRecord.surface;
135*8975f5c5SAndroid Build Coastguard Worker
136*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(getDisplay(), surface, surface, getContext());
137*8975f5c5SAndroid Build Coastguard Worker
138*8975f5c5SAndroid Build Coastguard Worker Matrix4 orthoMatrix =
139*8975f5c5SAndroid Build Coastguard Worker Matrix4::ortho(static_cast<float>(window->getX()),
140*8975f5c5SAndroid Build Coastguard Worker static_cast<float>(window->getX() + window->getWidth()),
141*8975f5c5SAndroid Build Coastguard Worker static_cast<float>(window->getY() + window->getHeight()),
142*8975f5c5SAndroid Build Coastguard Worker static_cast<float>(window->getY()), 0.0f, 1.0f);
143*8975f5c5SAndroid Build Coastguard Worker Matrix4 mvpMatrix = orthoMatrix * viewMatrix * modelMatrix;
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker Vector3 vertices[] = {
146*8975f5c5SAndroid Build Coastguard Worker Matrix4::transform(mvpMatrix, Vector4(midX, static_cast<float>(top), 0.0f, 1.0f)),
147*8975f5c5SAndroid Build Coastguard Worker Matrix4::transform(mvpMatrix, Vector4(static_cast<float>(left),
148*8975f5c5SAndroid Build Coastguard Worker static_cast<float>(bottom), 0.0f, 1.0f)),
149*8975f5c5SAndroid Build Coastguard Worker Matrix4::transform(mvpMatrix, Vector4(static_cast<float>(right),
150*8975f5c5SAndroid Build Coastguard Worker static_cast<float>(bottom), 0.0f, 1.0f)),
151*8975f5c5SAndroid Build Coastguard Worker };
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker // Set the viewport
154*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, window->getWidth(), window->getHeight());
155*8975f5c5SAndroid Build Coastguard Worker
156*8975f5c5SAndroid Build Coastguard Worker // Clear the color buffer
157*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
158*8975f5c5SAndroid Build Coastguard Worker
159*8975f5c5SAndroid Build Coastguard Worker // Use the program object
160*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mProgram);
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker // Load the vertex data
163*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices[0].data());
164*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(0);
165*8975f5c5SAndroid Build Coastguard Worker
166*8975f5c5SAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, 3);
167*8975f5c5SAndroid Build Coastguard Worker
168*8975f5c5SAndroid Build Coastguard Worker eglSwapBuffers(getDisplay(), surface);
169*8975f5c5SAndroid Build Coastguard Worker }
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker
172*8975f5c5SAndroid Build Coastguard Worker // Override swap to do nothing as we already swapped the root
173*8975f5c5SAndroid Build Coastguard Worker // window in draw() and swapping another time would invalidate
174*8975f5c5SAndroid Build Coastguard Worker // the content of the default framebuffer.
swap()175*8975f5c5SAndroid Build Coastguard Worker void swap() override {}
176*8975f5c5SAndroid Build Coastguard Worker
177*8975f5c5SAndroid Build Coastguard Worker private:
178*8975f5c5SAndroid Build Coastguard Worker // Handle to a program object
179*8975f5c5SAndroid Build Coastguard Worker GLuint mProgram;
180*8975f5c5SAndroid Build Coastguard Worker
181*8975f5c5SAndroid Build Coastguard Worker // Current rotation
182*8975f5c5SAndroid Build Coastguard Worker float mRotation;
183*8975f5c5SAndroid Build Coastguard Worker
184*8975f5c5SAndroid Build Coastguard Worker // Window and surface data
185*8975f5c5SAndroid Build Coastguard Worker struct window
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker OSWindow *osWindow;
188*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface;
189*8975f5c5SAndroid Build Coastguard Worker };
190*8975f5c5SAndroid Build Coastguard Worker std::vector<window> mWindows;
191*8975f5c5SAndroid Build Coastguard Worker
192*8975f5c5SAndroid Build Coastguard Worker RNG mRNG;
193*8975f5c5SAndroid Build Coastguard Worker };
194*8975f5c5SAndroid Build Coastguard Worker
main(int argc,char ** argv)195*8975f5c5SAndroid Build Coastguard Worker int main(int argc, char **argv)
196*8975f5c5SAndroid Build Coastguard Worker {
197*8975f5c5SAndroid Build Coastguard Worker MultiWindowSample app(argc, argv);
198*8975f5c5SAndroid Build Coastguard Worker return app.run();
199*8975f5c5SAndroid Build Coastguard Worker }
200