From patchwork Thu Oct 13 16:06:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 4663 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 536A623E51 for ; Thu, 13 Oct 2011 16:18:54 +0000 (UTC) Received: from mail-dy0-f52.google.com (mail-dy0-f52.google.com [209.85.220.52]) by fiordland.canonical.com (Postfix) with ESMTP id 37A8FA18641 for ; Thu, 13 Oct 2011 16:18:54 +0000 (UTC) Received: by dyj10 with SMTP id 10so118190dyj.11 for ; Thu, 13 Oct 2011 09:18:54 -0700 (PDT) Received: by 10.223.60.73 with SMTP id o9mr6991621fah.18.1318522423008; Thu, 13 Oct 2011 09:13:43 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.24.41 with SMTP id r9cs266726laf; Thu, 13 Oct 2011 09:13:27 -0700 (PDT) Received: by 10.227.13.67 with SMTP id b3mr1494584wba.61.1318522406616; Thu, 13 Oct 2011 09:13:26 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id es15si3327054wbb.78.2011.10.13.09.13.26 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 13 Oct 2011 09:13:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1RENuQ-0006JU-2T for ; Thu, 13 Oct 2011 16:13:26 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 38FE0E0030 for ; Thu, 13 Oct 2011 16:06:15 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 155 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 155: SceneDesktop: Add drop shadow effect. Message-Id: <20111013160615.6113.86013.launchpad@ackee.canonical.com> Date: Thu, 13 Oct 2011 16:06:15 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="14124"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 2ea9d82fdc376794a81c7ae2949269674350b579 Merge authors: Alexandros Frantzis (afrantzis) Related merge proposals: https://code.launchpad.net/~linaro-graphics-wg/glmark2/desktop-shadow/+merge/79268 proposed by: Alexandros Frantzis (afrantzis) review: Approve - Jesse Barker (jesse-barker) ------------------------------------------------------------ revno: 155 [merge] committer: Alexandros Frantzis branch nick: trunk timestamp: Thu 2011-10-13 18:59:20 +0300 message: SceneDesktop: Add drop shadow effect. added: data/textures/desktop-shadow-corner.png data/textures/desktop-shadow.png modified: src/android.cpp src/main.cpp src/scene-desktop.cpp --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === added file 'data/textures/desktop-shadow-corner.png' Binary files data/textures/desktop-shadow-corner.png 1970-01-01 00:00:00 +0000 and data/textures/desktop-shadow-corner.png 2011-10-13 12:20:03 +0000 differ === added file 'data/textures/desktop-shadow.png' Binary files data/textures/desktop-shadow.png 1970-01-01 00:00:00 +0000 and data/textures/desktop-shadow.png 2011-10-13 12:20:03 +0000 differ === modified file 'src/android.cpp' --- src/android.cpp 2011-10-13 13:44:52 +0000 +++ src/android.cpp 2011-10-13 15:59:20 +0000 @@ -45,6 +45,7 @@ "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;", "pulsar:quads=5:texture=false:light=false", "desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true", + "desktop:windows=4:effect=shadow", "buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=map:interleave=false", "buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=subdata:interleave=false", "buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=map:interleave=true", === modified file 'src/main.cpp' --- src/main.cpp 2011-10-10 16:10:04 +0000 +++ src/main.cpp 2011-10-13 15:58:38 +0000 @@ -56,6 +56,7 @@ "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;", "pulsar:quads=5:texture=false:light=false", "desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true", + "desktop:windows=4:effect=shadow", "buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=map:interleave=false", "buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=subdata:interleave=false", "buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=map:interleave=true", === modified file 'src/scene-desktop.cpp' --- src/scene-desktop.cpp 2011-09-21 15:00:40 +0000 +++ src/scene-desktop.cpp 2011-10-13 12:20:03 +0000 @@ -104,7 +104,7 @@ class RenderObject { public: - RenderObject() : texture_(0), fbo_(0) { } + RenderObject() : texture_(0), fbo_(0), rotation_rad_(0) { } virtual ~RenderObject() { release(); } @@ -199,17 +199,29 @@ virtual void render_to(RenderObject& target, Program& program = main_program) { - LibMatrix::vec2 final_pos(pos_ + size_); - LibMatrix::vec2 ll(target.normalize_position(pos_)); - LibMatrix::vec2 ur(target.normalize_position(final_pos)); + LibMatrix::vec2 anchor(pos_); + LibMatrix::vec2 ll(pos_ - anchor); + LibMatrix::vec2 ur(pos_ + size_ - anchor); + /* Calculate new position according to rotation value */ GLfloat position[2 * 4] = { - ll.x(), ll.y(), - ur.x(), ll.y(), - ll.x(), ur.y(), - ur.x(), ur.y(), + rotate_x(ll.x(), ll.y()) + anchor.x(), rotate_y(ll.x(), ll.y()) + anchor.y(), + rotate_x(ur.x(), ll.y()) + anchor.x(), rotate_y(ur.x(), ll.y()) + anchor.y(), + rotate_x(ll.x(), ur.y()) + anchor.x(), rotate_y(ll.x(), ur.y()) + anchor.y(), + rotate_x(ur.x(), ur.y()) + anchor.x(), rotate_y(ur.x(), ur.y()) + anchor.y(), }; + /* Normalize position and write back to array */ + for (int i = 0; i < 4; i++) { + const LibMatrix::vec2& v2( + target.normalize_position( + LibMatrix::vec2(position[2 * i], position[2 * i + 1]) + ) + ); + position[2 * i] = v2.x(); + position[2 * i + 1] = v2.y(); + } + static const GLfloat texcoord[2 * 4] = { 0.0, 0.0, 1.0, 0.0, @@ -251,7 +263,7 @@ /** * Normalizes a position from [0, size] to [-1.0, 1.0] */ - LibMatrix::vec2 normalize_position(LibMatrix::vec2& pos) + LibMatrix::vec2 normalize_position(const LibMatrix::vec2& pos) { return pos * 2.0 / size_ - 1.0; } @@ -259,11 +271,15 @@ /** * Normalizes a position from [0, size] to [0.0, 1.0] */ - LibMatrix::vec2 normalize_texcoord(LibMatrix::vec2& pos) + LibMatrix::vec2 normalize_texcoord(const LibMatrix::vec2& pos) { return pos / size_; } + void rotation(float degrees) + { + rotation_rad_ = (M_PI * degrees / 180.0); + } protected: void draw_quad_with_program(const GLfloat *position, const GLfloat *texcoord, @@ -298,6 +314,17 @@ GLuint fbo_; private: + float rotate_x(float x, float y) + { + return x * cos(rotation_rad_) - y * sin(rotation_rad_); + } + + float rotate_y(float x, float y) + { + return x * sin(rotation_rad_) + y * cos(rotation_rad_); + } + + float rotation_rad_; static int use_count; }; @@ -550,8 +577,138 @@ }; +/** + * A RenderObject that draws a drop shadow around the window. + */ +class RenderWindowShadow : public RenderObject +{ +public: + using RenderObject::size; + + RenderWindowShadow(unsigned int shadow_size, bool draw_contents = true) : + RenderObject(), shadow_size_(shadow_size), draw_contents_(draw_contents) {} + + virtual void init() + { + RenderObject::init(); + + /* + * Only have one instance of the resources. + * This works only if all windows have the same size, which + * is currently the case for this scene. If this condition + * ceases to be true we will need to create the resources per + * object. + */ + if (RenderWindowShadow::use_count == 0) { + shadow_h_.init(); + shadow_v_.init(); + shadow_corner_.init(); + if (draw_contents_) + window_contents_.init(); + } + + RenderWindowShadow::use_count++; + } + + virtual void release() + { + RenderWindowShadow::use_count--; + + /* Only have one instance of the data */ + if (RenderWindowShadow::use_count == 0) { + shadow_h_.release(); + shadow_v_.release(); + shadow_corner_.release(); + if (draw_contents_) + if (draw_contents_) + window_contents_.release(); + } + + RenderObject::release(); + } + + virtual void size(const LibMatrix::vec2& size) + { + RenderObject::size(size); + shadow_h_.size(LibMatrix::vec2(size.x() - shadow_size_, + static_cast(shadow_size_))); + shadow_v_.size(LibMatrix::vec2(size.y() - shadow_size_, + static_cast(shadow_size_))); + shadow_corner_.size(LibMatrix::vec2(static_cast(shadow_size_), + static_cast(shadow_size_))); + if (draw_contents_) + window_contents_.size(size); + } + + virtual void render_to(RenderObject& target, Program& program) + { + (void)program; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + /* Bottom shadow */ + shadow_h_.rotation(0.0); + shadow_h_.position(position() + + LibMatrix::vec2(shadow_size_, + -shadow_h_.size().y())); + shadow_h_.render_to(target); + + /* Right shadow */ + shadow_v_.rotation(90.0); + shadow_v_.position(position() + + LibMatrix::vec2(size().x() + shadow_v_.size().y(), 0.0)); + shadow_v_.render_to(target); + + /* Bottom right shadow */ + shadow_corner_.rotation(0.0); + shadow_corner_.position(position() + + LibMatrix::vec2(size().x(), + -shadow_corner_.size().y())); + shadow_corner_.render_to(target); + + /* Top right shadow */ + shadow_corner_.rotation(90.0); + shadow_corner_.position(position() + size() + + LibMatrix::vec2(shadow_corner_.size().x(), + -shadow_corner_.size().y())); + shadow_corner_.render_to(target); + + /* Bottom left shadow */ + shadow_corner_.rotation(-90.0); + shadow_corner_.position(position()); + shadow_corner_.render_to(target); + + /* + * Blend the window contents with the target texture. + */ + if (draw_contents_) { + window_contents_.position(position()); + window_contents_.render_to(target); + } + + glDisable(GL_BLEND); + } + +private: + unsigned int shadow_size_; + bool draw_contents_; + + static int use_count; + static RenderClearImage window_contents_; + static RenderClearImage shadow_h_; + static RenderClearImage shadow_v_; + static RenderClearImage shadow_corner_; + +}; + int RenderWindowBlur::use_count = 0; RenderClearImage RenderWindowBlur::window_contents_(GLMARK_DATA_PATH"/textures/desktop-window.png"); +int RenderWindowShadow::use_count = 0; +RenderClearImage RenderWindowShadow::window_contents_(GLMARK_DATA_PATH"/textures/desktop-window.png"); +RenderClearImage RenderWindowShadow::shadow_h_(GLMARK_DATA_PATH"/textures/desktop-shadow.png"); +RenderClearImage RenderWindowShadow::shadow_v_(GLMARK_DATA_PATH"/textures/desktop-shadow.png"); +RenderClearImage RenderWindowShadow::shadow_corner_(GLMARK_DATA_PATH"/textures/desktop-shadow-corner.png"); /******************************* * SceneDesktop implementation * @@ -591,6 +748,8 @@ "the blur effect radius (in pixels)"); mOptions["separable"] = Scene::Option("separable", "true", "use separable convolution for the blur effect"); + mOptions["shadow-size"] = Scene::Option("shadow-size", "20", + "the size of the shadow (in pixels)"); } SceneDesktop::~SceneDesktop() @@ -619,6 +778,7 @@ unsigned int passes(0); unsigned int blur_radius(0); float window_size_factor(0.0); + unsigned int shadow_size(0); bool separable(mOptions["separable"].value == "true"); ss << mOptions["windows"].value; @@ -632,6 +792,9 @@ ss.clear(); ss << mOptions["blur-radius"].value; ss >> blur_radius; + ss.clear(); + ss << mOptions["shadow-size"].value; + ss >> shadow_size; /* Ensure we get a transparent clear color for all following operations */ glClearColor(0.0, 0.0, 0.0, 0.0); @@ -654,7 +817,11 @@ for (unsigned int i = 0; i < windows; i++) { LibMatrix::vec2 center(mCanvas.width() * (0.5 + 0.25 * cos(i * angular_step)), mCanvas.height() * (0.5 + 0.25 * sin(i * angular_step))); - RenderObject* win(new RenderWindowBlur(passes, blur_radius, separable)); + RenderObject* win; + if (mOptions["effect"].value == "shadow") + win = new RenderWindowShadow(shadow_size); + else + win = new RenderWindowBlur(passes, blur_radius, separable); (void)angular_step; win->init();