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