Add a sample that uses multiple windows.

BUG=angleproject:521

Change-Id: I50858193518b4d07edcb2073caaa99ce37fcc4c3
Reviewed-on: https://chromium-review.googlesource.com/267000
Reviewed-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Geoff Lang
2015-04-23 12:27:56 -04:00
parent 5271025865
commit 681ad9d1bb
6 changed files with 239 additions and 2 deletions

View File

@@ -0,0 +1,186 @@
//
// Copyright (c) 2015 The ANGLE Project 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 "Matrix.h"
#include "SampleApplication.h"
#include "random_utils.h"
#include "shader_utils.h"
#include <vector>
#include <algorithm>
class MultiWindowSample : public SampleApplication
{
public:
MultiWindowSample::MultiWindowSample()
: SampleApplication("MultiWindow", 256, 256)
{
}
virtual bool initialize()
{
const std::string vs = SHADER_SOURCE
(
attribute vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
);
const std::string fs = SHADER_SOURCE
(
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
);
mProgram = CompileProgram(vs, fs);
if (!mProgram)
{
return false;
}
// Set an initial rotation
mRotation = 45.0f;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
window rootWindow;
rootWindow.osWindow = getWindow();
rootWindow.surface = getSurface();
mWindows.push_back(rootWindow);
const size_t numWindows = 5;
for (size_t i = 1; i < numWindows; i++)
{
window window;
window.osWindow = CreateOSWindow();
if (!window.osWindow->initialize("MultiWindow", 256, 256))
{
return false;
}
window.surface = eglCreateWindowSurface(getDisplay(), getConfig(), window.osWindow->getNativeWindow(), nullptr);
if (window.surface == EGL_NO_SURFACE)
{
return false;
}
window.osWindow->setVisible(true);
mWindows.push_back(window);
}
for (size_t i = 1; i < mWindows.size(); i++)
{
int x = rootWindow.osWindow->getX() + static_cast<int>(RandomBetween(0, 512));
int y = rootWindow.osWindow->getY() + static_cast<int>(RandomBetween(0, 512));
int width = static_cast<int>(RandomBetween(128, 512));
int height = static_cast<int>(RandomBetween(128, 512));
mWindows[i].osWindow->setPosition(x, y);
mWindows[i].osWindow->resize(width, height);
}
return true;
}
virtual void destroy()
{
glDeleteProgram(mProgram);
}
virtual void step(float dt, double totalTime)
{
mRotation = fmod(mRotation + (dt * 40.0f), 360.0f);
}
virtual void draw()
{
OSWindow* rootWindow = mWindows[0].osWindow;
int left = rootWindow->getX();
int right = rootWindow->getX() + rootWindow->getWidth();
int top = rootWindow->getY();
int bottom = rootWindow->getY() + rootWindow->getHeight();
for (size_t i = 1; i < mWindows.size(); i++)
{
OSWindow* window = mWindows[i].osWindow;
left = std::min(left, window->getX());
right = std::max(right, window->getX() + window->getWidth());
top = std::min(top, window->getY());
bottom = std::max(bottom, window->getY() + window->getHeight());
}
float midX = (left + right) * 0.5f;
float midY = (top + bottom) * 0.5f;
Matrix4 modelMatrix = Matrix4::translate(Vector3(midX, midY, 0.0f)) *
Matrix4::rotate(mRotation, Vector3(0.0f, 0.0f, 1.0f)) *
Matrix4::translate(Vector3(-midX, -midY, 0.0f));
Matrix4 viewMatrix = Matrix4::identity();
for (size_t i = 0; i < mWindows.size(); i++)
{
OSWindow* window = mWindows[i].osWindow;
EGLSurface surface = mWindows[i].surface;
eglMakeCurrent(getDisplay(), surface, surface, getContext());
Matrix4 orthoMatrix = Matrix4::ortho(static_cast<float>(window->getX()), static_cast<float>(window->getX() + window->getWidth()),
static_cast<float>(window->getY() + window->getHeight()), static_cast<float>(window->getY()),
0.0f, 1.0f);
Matrix4 mvpMatrix = orthoMatrix * viewMatrix * modelMatrix;
Vector3 vertices[] =
{
Matrix4::transform(mvpMatrix, Vector4(midX, static_cast<float>(top), 0.0f, 1.0f)),
Matrix4::transform(mvpMatrix, Vector4(static_cast<float>(left), static_cast<float>(bottom), 0.0f, 1.0f)),
Matrix4::transform(mvpMatrix, Vector4(static_cast<float>(right), static_cast<float>(bottom), 0.0f, 1.0f)),
};
// Set the viewport
glViewport(0, 0, window->getWidth(), window->getHeight());
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
// Use the program object
glUseProgram(mProgram);
// Load the vertex data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices[0].data);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(getDisplay(), surface);
}
}
private:
// Handle to a program object
GLuint mProgram;
// Current rotation
float mRotation;
// Window and surface data
struct window
{
OSWindow* osWindow;
EGLSurface surface;
};
std::vector<window> mWindows;
};
int main(int argc, char **argv)
{
MultiWindowSample app;
return app.run();
}

View File

@@ -100,6 +100,14 @@
]
},
{
'target_name': 'multi_window',
'type': 'executable',
'dependencies': [ 'sample_util' ],
'includes': [ '../build/common_defines.gypi', ],
'sources': [ 'multi_window/MultiWindow.cpp', ],
},
{
'target_name': 'multiple_draw_buffers',
'type': 'executable',

View File

@@ -7,7 +7,9 @@
#include "OSWindow.h"
OSWindow::OSWindow()
: mWidth(0),
: mX(0),
mY(0),
mWidth(0),
mHeight(0)
{
}
@@ -15,6 +17,16 @@ OSWindow::OSWindow()
OSWindow::~OSWindow()
{}
int OSWindow::getX() const
{
return mX;
}
int OSWindow::getY() const
{
return mY;
}
int OSWindow::getWidth() const
{
return mWidth;
@@ -43,6 +55,10 @@ void OSWindow::pushEvent(Event event)
{
switch (event.Type)
{
case Event::EVENT_MOVED:
mX = event.Move.X;
mY = event.Move.Y;
break;
case Event::EVENT_RESIZED:
mWidth = event.Size.Width;
mHeight = event.Size.Height;

View File

@@ -22,6 +22,8 @@ class OSWindow
virtual bool initialize(const std::string &name, size_t width, size_t height) = 0;
virtual void destroy() = 0;
int getX() const;
int getY() const;
int getWidth() const;
int getHeight() const;
@@ -34,6 +36,7 @@ class OSWindow
virtual void pushEvent(Event event);
virtual void setMousePosition(int x, int y) = 0;
virtual bool setPosition(int x, int y) = 0;
virtual bool resize(int width, int height) = 0;
virtual void setVisible(bool isVisible) = 0;
@@ -43,6 +46,8 @@ class OSWindow
bool didTestEventFire();
protected:
int mX;
int mY;
int mWidth;
int mHeight;

View File

@@ -518,6 +518,27 @@ OSWindow *CreateOSWindow()
return new Win32Window();
}
bool Win32Window::setPosition(int x, int y)
{
if (mX == x && mY == mY)
{
return true;
}
RECT windowRect;
if (!GetWindowRect(mParentWindow, &windowRect))
{
return false;
}
if (!MoveWindow(mParentWindow, x, y, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, TRUE))
{
return false;
}
return true;
}
bool Win32Window::resize(int width, int height)
{
if (width == mWidth && height == mHeight)
@@ -539,7 +560,7 @@ bool Win32Window::resize(int width, int height)
LONG diffX = (windowRect.right - windowRect.left) - clientRect.right;
LONG diffY = (windowRect.bottom - windowRect.top) - clientRect.bottom;
if (!MoveWindow(mParentWindow, windowRect.left, windowRect.top, width + diffX, height + diffY, FALSE))
if (!MoveWindow(mParentWindow, windowRect.left, windowRect.top, width + diffX, height + diffY, TRUE))
{
return false;
}

View File

@@ -28,6 +28,7 @@ class Win32Window : public OSWindow
void pushEvent(Event event) override;
void setMousePosition(int x, int y) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;