xoreos  0.0.5
portrait.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <cassert>
26 
27 #include "src/common/util.h"
28 #include "src/common/maths.h"
29 #include "src/common/ustring.h"
30 
31 #include "glm/gtc/matrix_transform.hpp"
32 
33 #include "src/graphics/graphics.h"
34 
40 
42 
43 static const char * const kSuffix[] = {"h" , "l" , "m" , "s" , "t" , "i" };
44 static const float kWidth [] = {256.0f, 128.0f, 64.0f, 32.0f, 16.0f, 32.0f};
45 static const float kHeight[] = {400.0f, 200.0f, 100.0f, 50.0f, 25.0f, 32.0f};
46 
47 namespace Engines {
48 
49 namespace NWN {
50 
52  float border, float bR, float bG, float bB, float bA) :
53  Graphics::GUIElement(Graphics::GUIElement::kGUIElementFront),
54  _size(size), _border(border), _bR(bR), _bG(bG), _bB(bB), _bA(bA) {
55 
56  assert((_size >= kSizeHuge) && (_size < kSizeMAX));
57 
58  if (GfxMan.isRendererExperimental()) {
60  ShaderMan.getShaderObject("default/textureMatrix.vert", Graphics::Shader::SHADER_VERTEX), "portrait"));
61 
63  ShaderMan.getShaderObject("default/texture.frag", Graphics::Shader::SHADER_FRAGMENT), "portrait"));
64 
65  // Sampler should be changed when the portrait texture is changed.
67  _surface.get(), _material.get(), MeshMan.getMesh("defaultMeshQuad")));
68 
70  ShaderMan.getShaderObject("default/colour.frag", Graphics::Shader::SHADER_FRAGMENT), "portraitborder"));
71 
73  SurfaceMan.getSurface("defaultSurface"), _borderMaterial.get(), MeshMan.getMesh("defaultMeshQuad")));
74  }
75 
76  setSize();
77  setPortrait(name);
78 
79  setPosition(0.0f, 0.0f, -FLT_MAX);
80 }
81 
83 }
84 
86  if (_border <= 0.0f)
87  return;
88 
89  _qBorder.clear();
90  _qBorder.resize(4);
91 
92  _qBorder[0].vX[0] = _x - _border; _qBorder[0].vY[0] = _y - _border;
93  _qBorder[0].vX[1] = _x + _width + _border; _qBorder[0].vY[1] = _y - _border;
94  _qBorder[0].vX[2] = _x + _width + _border; _qBorder[0].vY[2] = _y;
95  _qBorder[0].vX[3] = _x - _border; _qBorder[0].vY[3] = _y;
96 
97  _qBorder[1].vX[0] = _x - _border; _qBorder[1].vY[0] = _y + _height;
98  _qBorder[1].vX[1] = _x + _width + _border; _qBorder[1].vY[1] = _y + _height;
99  _qBorder[1].vX[2] = _x + _width + _border; _qBorder[1].vY[2] = _y + _height + _border;
100  _qBorder[1].vX[3] = _x - _border; _qBorder[1].vY[3] = _y + _height + _border;
101 
102  _qBorder[2].vX[0] = _x - _border; _qBorder[2].vY[0] = _y - _border;
103  _qBorder[2].vX[1] = _x; _qBorder[2].vY[1] = _y - _border;
104  _qBorder[2].vX[2] = _x; _qBorder[2].vY[2] = _y + _height + _border;
105  _qBorder[2].vX[3] = _x - _border; _qBorder[2].vY[3] = _y + _height + _border;
106 
107  _qBorder[3].vX[0] = _x + _width; _qBorder[3].vY[0] = _y - _border;
108  _qBorder[3].vX[1] = _x + _width + _border; _qBorder[3].vY[1] = _y - _border;
109  _qBorder[3].vX[2] = _x + _width + _border; _qBorder[3].vY[2] = _y + _height + _border;
110  _qBorder[3].vX[3] = _x + _width; _qBorder[3].vY[3] = _y + _height + _border;
111 }
112 
113 float Portrait::getWidth() const {
114  return _width + _border + _border;
115 }
116 
117 float Portrait::getHeight() const {
118  return _height + _border + _border;
119 }
120 
121 void Portrait::setPosition(float x, float y, float z) {
122  GfxMan.lockFrame();
123 
124  _x = x + _border;
125  _y = y + _border;
126 
127  _qPortrait.vX[0] = _x; _qPortrait.vY[0] = _y;
128  _qPortrait.vX[1] = _x + _width; _qPortrait.vY[1] = _y;
129  _qPortrait.vX[2] = _x + _width; _qPortrait.vY[2] = _y + _height;
130  _qPortrait.vX[3] = _x; _qPortrait.vY[3] = _y + _height;
131 
132  createBorder();
133 
134  _distance = z;
135  resort();
136 
137  GfxMan.unlockFrame();
138 }
139 
140 void Portrait::getPosition(float &x, float &y, float &z) const {
141  x = _x;
142  y = _y;
143  z = _distance;
144 }
145 
146 bool Portrait::isIn(float x, float y) const {
147  float x1 = _x;
148  float x2 = _x + getWidth();
149  float y1 = _y;
150  float y2 = _y + getHeight();
151 
152  if ((x < x1) || (x > x2))
153  return false;
154  if ((y < y1) || (y > y2))
155  return false;
156 
157  return true;
158 }
159 
161 }
162 
164  bool isTransparent = (_bA < 1.0f) ||
166  if (((pass == Graphics::kRenderPassOpaque) && isTransparent) ||
167  ((pass == Graphics::kRenderPassTransparent) && !isTransparent))
168  return;
169 
170 
171  // Border
172 
173  TextureMan.set();
174  glColor4f(_bR, _bG, _bB, _bA);
175 
176  glBegin(GL_QUADS);
177  for (std::vector<Quad>::const_iterator b = _qBorder.begin(); b != _qBorder.end(); ++b)
178  for (int i = 0; i < 4; i++)
179  glVertex2f(b->vX[i], b->vY[i]);
180  glEnd();
181 
182 
183  // Portrait
184 
185  TextureMan.set(_texture);
186  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
187 
188  glBegin(GL_QUADS);
189  for (int i = 0; i < 4; i++) {
190  glTexCoord2f(_qPortrait.tX[i], _qPortrait.tY[i]);
191  glVertex2f (_qPortrait.vX[i], _qPortrait.vY[i]);
192  }
193  glEnd();
194 }
195 
196 void Portrait::renderImmediate(const glm::mat4 &parentTransform) {
206  if (_border > 0.0f) {
207  float *color = static_cast<float *>(_borderMaterial->getVariableData("_colour"));
208  color[0] = _bR;
209  color[1] = _bG;
210  color[2] = _bB;
211  color[3] = _bA;
212 
213  glm::mat4 btform = glm::translate(glm::mat4(), glm::vec3(_x - _border, _y - _border, -10.0f));
214  btform = glm::scale(btform, glm::vec3(_width + 2.0f * _border,
215  _height + 2.0f * _border,
216  1.0f));
217  _borderRenderable->renderImmediate(parentTransform * btform);
218  }
219 
220  glm::mat4 tform = glm::translate(glm::mat4(), glm::vec3(_x, _y, -10.0f));
221  tform = glm::scale(tform, glm::vec3(_width, _height, 1.0f));
222  _renderable->renderImmediate(parentTransform * tform);
223 }
224 
226  Size curSize = _size;
227 
228  _texture.clear();
229  while (_texture.empty() && (curSize < kSizeMAX)) {
230  try {
231  _texture = TextureMan.get(name + kSuffix[curSize]);
232  } catch (...) {
233  _texture.clear();
234  }
235 
236  curSize = (Size) (curSize + 1);
237  }
238 
239  if (_texture.empty()) {
240  try {
241  _texture = TextureMan.get(name);
242  } catch (...) {
243  _texture.clear();
244  }
245  }
246 
247  if (GfxMan.isRendererExperimental()) {
249  sampler = (Graphics::Shader::ShaderSampler *)(_material->getVariableData("sampler_0_id"));
250  sampler->handle = _texture;
251  }
252 }
253 
254 void Portrait::setBorderColor(float bR, float bG, float bB, float bA) {
255  GfxMan.lockFrame();
256  _bR = bR;
257  _bG = bG;
258  _bB = bB;
259  _bA = bA;
260  GfxMan.unlockFrame();
261 }
262 
264  _width = kWidth[_size];
265  _height = kHeight[_size];
266 
267  _qPortrait.vX[0] = 0.0f; _qPortrait.vY[0] = 0.0f;
268  _qPortrait.vX[1] = 0.0f + _width; _qPortrait.vY[1] = 0.0f;
269  _qPortrait.vX[2] = 0.0f + _width; _qPortrait.vY[2] = 0.0f + _height;
270  _qPortrait.vX[3] = 0.0f; _qPortrait.vY[3] = 0.0f + _height;
271 
272  // Part of the texture(the bottom) is cut for portraits but not for icons.
273  float portraitCutRatio;
274  if (_size != kSizeIcon) {
275  portraitCutRatio = 112.0f / 512.0f;
276  } else {
277  portraitCutRatio = 0.0f;
278  }
279 
280  _qPortrait.tX[0] = 0.0f; _qPortrait.tY[0] = portraitCutRatio;
281  _qPortrait.tX[1] = 1.0f; _qPortrait.tY[1] = portraitCutRatio;
282  _qPortrait.tX[2] = 1.0f; _qPortrait.tY[2] = 1.0f;
283  _qPortrait.tX[3] = 0.0f; _qPortrait.tY[3] = 1.0f;
284 
285  if (GfxMan.isRendererExperimental()) {
286  glm::mat4 tmatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, portraitCutRatio, 0.0f));
287  tmatrix = glm::scale(tmatrix, glm::vec3(1.0f, 1.0f - portraitCutRatio, 1.0f));
288  memcpy(_surface->getVariableData("_uv0Matrix"), &tmatrix[0], 16 * sizeof(float));
289  }
290 }
291 
292 
294  const Common::UString &name, Portrait::Size size, float border,
295  float bR, float bG, float bB, float bA) : NWNWidget(gui, tag),
296  _portrait(name, size, border, bR, bG, bB, bA) {
297 
298  _portrait.setTag(tag);
299  _portrait.setClickable(true);
300 }
301 
303 }
304 
306  if (isVisible())
307  return;
308 
309  if (!isInvisible())
310  _portrait.show();
311 
312  NWNWidget::show();
313 }
314 
316  if (!isVisible())
317  return;
318 
319  _portrait.hide();
320  NWNWidget::hide();
321 }
322 
323 void PortraitWidget::mouseDown(uint8 state, float x, float y) {
324  if (_owner)
325  _owner->mouseDown(state, x, y);
326 }
327 
328 void PortraitWidget::mouseWheel(uint8 state, int x, int y) {
329  if (_owner)
330  _owner->mouseWheel(state, x, y);
331 }
332 
333 void PortraitWidget::setPosition(float x, float y, float z) {
334  NWNWidget::setPosition(x, y, z);
335 
336  getPosition(x, y, z);
337  _portrait.setPosition(x, y, z);
338 }
339 
341  _portrait.setPortrait(name);
342 }
343 
344 void PortraitWidget::setBorderColor(float bR, float bG, float bB, float bA) {
345  _portrait.setBorderColor(bR, bG, bB, bA);
346 }
347 
349  return _portrait.getWidth();
350 }
351 
353  return _portrait.getHeight();
354 }
355 
357  NWNWidget::setTag(tag);
358 
360 }
361 
362 } // End of namespace NWN
363 
364 } // End of namespace Engines
Graphics::Aurora::TextureHandle _texture
Definition: portrait.h:92
void setBorderColor(float bR, float bG, float bB, float bA)
Definition: portrait.cpp:344
virtual void show()
Show the object.
Definition: renderable.cpp:114
bool hasAlpha() const
Definition: texture.cpp:84
Only render transparent parts.
Definition: types.h:99
The global graphics manager.
virtual void hide()
Hide the object.
Definition: renderable.cpp:123
Widget * _owner
The widget&#39;s owner, if any.
Definition: widget.h:113
virtual void setTag(const Common::UString &tag)
Set the widget&#39;s tag.
Definition: widget.cpp:49
A class holding an UTF-8 string.
Definition: ustring.h:48
#define TextureMan
Shortcut for accessing the texture manager.
Definition: textureman.h:127
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
double _distance
The distance of the object from the viewer.
Definition: renderable.h:101
#define SurfaceMan
Shortcut for accessing the shader manager.
Definition: surfaceman.h:74
uint8_t uint8
Definition: types.h:200
The Aurora texture manager.
Mathematical helpers.
virtual void getPosition(float &x, float &y, float &z) const
Get the widget&#39;s position.
Definition: widget.cpp:140
float getWidth() const
Get the scrollbar&#39;s width.
Definition: portrait.cpp:113
Base class for all widgets in NWN.
Definition: nwnwidget.h:45
static const char *const kSuffix[]
Definition: portrait.cpp:43
bool isVisible() const
Is the widget visible?
Definition: widget.cpp:59
float getHeight() const
Get the widget&#39;s height.
Definition: portrait.cpp:352
Common::ScopedPtr< Graphics::Shader::ShaderRenderable > _borderRenderable
Definition: portrait.h:114
void calculateDistance()
Calculate the object&#39;s distance.
Definition: portrait.cpp:160
PortraitWidget(::Engines::GUI &gui, const Common::UString &tag, const Common::UString &name, Portrait::Size size, float border=0.0f, float bR=1.0f, float bG=1.0f, float bB=1.0f, float bA=1.0f)
Definition: portrait.cpp:293
std::vector< Quad > _qBorder
Definition: portrait.h:108
void getPosition(float &x, float &y, float &z) const
Get the current position of the portrait.
Definition: portrait.cpp:140
void hide()
Hide the widget.
Definition: nwnwidget.cpp:40
Portrait(const Common::UString &name, Size size, float border=0.0f, float bR=1.0f, float bG=1.0f, float bB=1.0f, float bA=1.0f)
Definition: portrait.cpp:51
void renderImmediate(const glm::mat4 &parentTransform)
For shader based systems, don&#39;t sort anything, render this right_now.
Definition: portrait.cpp:196
A GUI.
Definition: gui.h:43
bool isInvisible() const
Is the widget invisible (never visible)?
Definition: widget.cpp:67
Common::ScopedPtr< Graphics::Shader::ShaderMaterial > _borderMaterial
Definition: portrait.h:112
virtual void mouseDown(uint8 state, float x, float y)
A mouse button was pressed on the widget.
Definition: widget.cpp:191
RenderPass
Definition: types.h:97
void setClickable(bool clickable)
Set the object&#39;s clickable state.
Definition: renderable.cpp:94
Graphics::Aurora::TextureHandle handle
Definition: shader.h:176
Utility templates and functions.
void setPosition(float x, float y, float z)
Set the current position of the portrait.
Definition: portrait.cpp:121
const Common::UString & getTag() const
Get the widget&#39;s tag.
Definition: widget.cpp:45
static const float kHeight[]
Definition: portrait.cpp:45
void show()
Show the widget.
Definition: portrait.cpp:305
Common::ScopedPtr< Graphics::Shader::ShaderRenderable > _renderable
Definition: portrait.h:113
The global shader material manager.
The global shader surface manager.
void render(Graphics::RenderPass pass)
Render the object.
Definition: portrait.cpp:163
The global mesh manager.
void setPosition(float x, float y, float z)
Set the widget&#39;s position.
Definition: nwnwidget.cpp:60
void setPortrait(const Common::UString &name)
Definition: portrait.cpp:340
float getHeight() const
Get the scrollbar&#39;s height.
Definition: portrait.cpp:117
Unicode string handling.
#define MeshMan
Shortcut for accessing the shader manager.
Definition: meshman.h:74
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
Shader sampler is used to bind a texture to a texture unit.
Definition: shader.h:174
void setBorderColor(float bR, float bG, float bB, float bA)
Set border color.
Definition: portrait.cpp:254
virtual void mouseWheel(uint8 state, int x, int y)
A mouse wheel was used on the widget.
Definition: widget.cpp:197
void mouseWheel(uint8 state, int x, int y)
A mouse wheel was used on the widget.
Definition: portrait.cpp:328
Common::ScopedPtr< Graphics::Shader::ShaderMaterial > _material
Definition: portrait.h:111
A texture as used in the Aurora engines.
void setPosition(float x, float y, float z)
Set the widget&#39;s position.
Definition: portrait.cpp:333
virtual void show()
Show the widget.
Definition: widget.cpp:71
void setTag(const Common::UString &tag)
Set the widget&#39;s tag.
Definition: portrait.cpp:356
#define ShaderMan
Shortcut for accessing the shader manager.
Definition: shader.h:293
void setTag(const Common::UString &tag)
Set the object&#39;s tag.
Definition: renderable.cpp:102
A portrait model and widget.
void hide()
Hide the widget.
Definition: portrait.cpp:315
void setPortrait(const Common::UString &name)
Set the current portrait.
Definition: portrait.cpp:225
static const float kWidth[]
Definition: portrait.cpp:44
bool isIn(float x, float y) const
Is the point within the portrait?
Definition: portrait.cpp:146
#define pass
Definition: fft.cpp:257
Common::ScopedPtr< Graphics::Shader::ShaderSurface > _surface
Definition: portrait.h:110
float getWidth() const
Get the widget&#39;s width.
Definition: portrait.cpp:348
void mouseDown(uint8 state, float x, float y)
A mouse button was pressed on the widget.
Definition: portrait.cpp:323
#define FLT_MAX
Definition: maths.h:47
#define GfxMan
Shortcut for accessing the graphics manager.
Definition: graphics.h:299
Only render opaque parts.
Definition: types.h:98