SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLBackground.cpp
Go to the documentation of this file.
1 /**
2  * \file SLBackground.cpp
3  * \date August 2015
4  * \authors Marcus Hudritsch
5  * \copyright http://opensource.org/licenses/GPL-3.0
6  * \remarks Please use clangformat to format the code. See more code style on
7  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
8 */
9 
10 #include <SLBackground.h>
11 #include <SLGLProgram.h>
12 #include <SLGLTexture.h>
13 #include <SLScene.h>
14 
15 //-----------------------------------------------------------------------------
16 //! The constructor initializes to a uniform BLACK background color
18  : SLObject("Background")
19 {
20  _colors.push_back(SLCol4f::BLACK); // bottom left
21  _colors.push_back(SLCol4f::BLACK); // bottom right
22  _colors.push_back(SLCol4f::BLACK); // top right
23  _colors.push_back(SLCol4f::BLACK); // top left
25  _isUniform = true;
26  _texture = nullptr;
27  _textureError = nullptr;
28  _resX = -1;
29  _resY = -1;
30 
32  shaderDir + "TextureOnly.vert",
33  shaderDir + "TextureOnly.frag");
34 
36  shaderDir + "ColorAttribute.vert",
37  shaderDir + "Color.frag");
38  _deletePrograms = true;
39 }
40 //-----------------------------------------------------------------------------
41 //! The constructor initializes to a uniform gray background color
43  SLGLProgram* colorAttributeProgram)
44  : SLObject("Background"),
45  _textureOnlyProgram(textureOnlyProgram),
46  _colorAttributeProgram(colorAttributeProgram),
47  _deletePrograms(false)
48 {
49  _colors.push_back(SLCol4f::BLACK); // bottom left
50  _colors.push_back(SLCol4f::BLACK); // bottom right
51  _colors.push_back(SLCol4f::BLACK); // top right
52  _colors.push_back(SLCol4f::BLACK); // top left
54  _isUniform = true;
55  _texture = nullptr;
56  _textureError = nullptr;
57  _resX = -1;
58  _resY = -1;
59 }
60 //-----------------------------------------------------------------------------
62 {
63  if (_deletePrograms)
64  {
65  delete _textureOnlyProgram;
67  }
68 }
69 //-----------------------------------------------------------------------------
70 //! Sets a uniform background color
71 void SLBackground::colors(const SLCol4f& uniformColor)
72 {
73  _colors[0].set(uniformColor);
74  _colors[1].set(uniformColor);
75  _colors[2].set(uniformColor);
76  _colors[3].set(uniformColor);
77  _avgColor = uniformColor;
78  _isUniform = true;
79  _texture = nullptr;
81 }
82 //-----------------------------------------------------------------------------
83 //! Sets a gradient top-down background color
84 void SLBackground::colors(const SLCol4f& topColor,
85  const SLCol4f& bottomColor)
86 {
87  _colors[0].set(topColor);
88  _colors[1].set(bottomColor);
89  _colors[2].set(topColor);
90  _colors[3].set(bottomColor);
91  _avgColor = (topColor + bottomColor) / 2.0f;
92  _isUniform = false;
93  _texture = nullptr;
94  //_vao.clearAttribs(); Not allowed here during assembly
95 }
96 //-----------------------------------------------------------------------------
97 //! Sets a gradient background color with a color per corner
98 void SLBackground::colors(const SLCol4f& topLeftColor,
99  const SLCol4f& bottomLeftColor,
100  const SLCol4f& topRightColor,
101  const SLCol4f& bottomRightColor)
102 {
103  _colors[0].set(topLeftColor);
104  _colors[1].set(bottomLeftColor);
105  _colors[2].set(topRightColor);
106  _colors[3].set(bottomRightColor);
107  _avgColor = (_colors[0] + _colors[1] + _colors[2] + _colors[3]) / 4.0f;
108  _isUniform = false;
109  _texture = nullptr;
110  _vao.clearAttribs();
111 }
112 //-----------------------------------------------------------------------------
113 //! Sets the background texture
114 void SLBackground::texture(SLGLTexture* backgroundTexture, bool fixAspectRatio)
115 {
116  _texture = backgroundTexture;
118  _isUniform = false;
120 
121  _vao.clearAttribs();
122 }
123 //-----------------------------------------------------------------------------
124 //! Draws the background as 2D rectangle with OpenGL buffers
125 /*! Draws the background as a flat 2D rectangle with a height and a width on two
126 triangles with zero in the bottom left corner: <br>
127  w
128  +-----+
129  | /|
130  | / |
131  h | / |
132  | / |
133  |/ |
134  0 +-----+
135  0
136 
137 We render the quad as a triangle strip: <br>
138  0 2
139  +-----+
140  | /|
141  | / |
142  | / |
143  | / |
144  |/ |
145  +-----+
146  1 3
147 */
148 void SLBackground::render(SLint widthPX, SLint heightPX)
149 {
150  SLGLState* stateGL = SLGLState::instance();
151 
152  // Set orthographic projection
153  stateGL->projectionMatrix.ortho(0.0f, (SLfloat)widthPX, 0.0f, (SLfloat)heightPX, 0.0f, 1.0f);
154  stateGL->modelMatrix.identity();
155  stateGL->viewMatrix.identity();
156  stateGL->depthTest(false);
157  stateGL->multiSample(false);
158 
159  // Get shader program
161  sp->useProgram();
162  sp->uniformMatrix4fv("u_mMatrix", 1, (SLfloat*)&stateGL->modelMatrix);
163  sp->uniformMatrix4fv("u_vMatrix", 1, (SLfloat*)&stateGL->viewMatrix);
164  sp->uniformMatrix4fv("u_pMatrix", 1, (SLfloat*)&stateGL->projectionMatrix);
165  sp->uniform1f("u_oneOverGamma", SLLight::oneOverGamma());
166 
167  // Create or update buffer for vertex position and indices
168  if (!_vao.vaoID() || _resX != widthPX || _resY != heightPX)
169  {
170  // texture width and height not yet valid on first call
171  _resX = widthPX;
172  _resY = heightPX;
173  _vao.clearAttribs();
174 
175  SLfloat left = 0, right = (float)_resX, bottom = 0, top = (float)_resY;
176 
177  // the background is centered and stretched to the screen boarders while keeping the textures aspect ratio
178  if (_texture && _fixAspectRatio)
179  {
180  SLfloat backgroundW, backgroundH;
182  {
183  // screen is wider than texture -> adjust background width
184  backgroundH = (float)_resY;
185  backgroundW = (float)_resY / (SLfloat)_texture->height() * (SLfloat)_texture->width();
186  }
187  else
188  {
189  // screen is more narrow than texture -> adjust background height
190  backgroundW = (float)_resX;
191  backgroundH = (float)_resX / (SLfloat)_texture->width() * (SLfloat)_texture->height();
192  }
193 
194  left = (_resX - backgroundW) * 0.5f;
195  right = backgroundW + left;
196  bottom = (_resY - backgroundH) * 0.5f;
197  top = backgroundH + bottom;
198 
199  _rect.set(left, bottom, backgroundW, backgroundH);
200  SL_LOG("SLBackground: width:%f height:%f left:%f bottom:%f", rect().width, rect().height, rect().x, rect().x);
201  }
202  else
203  _rect.set(0, 0, (float)widthPX, (float)heightPX);
204 
205  // Float array with vertex X & Y of corners
206  SLVVec2f P = {{left, top},
207  {left, bottom},
208  {right, top},
209  {right, bottom}};
210 
212 
213  // Indexes for a triangle strip
214  SLVushort I = {0, 1, 2, 3};
215  _vao.setIndices(&I, nullptr);
216 
217  if (_texture)
218  { // Float array of texture coordinates
219  SLVVec2f T = {{0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}};
220  _vao.setAttrib(AT_uv1, AT_uv1, &T);
221  _vao.generate(4);
222  }
223  else
224  { // Float array of colors of corners
225  SLVVec3f C = {{_colors[0].r, _colors[0].g, _colors[0].b},
226  {_colors[1].r, _colors[1].g, _colors[1].b},
227  {_colors[2].r, _colors[2].g, _colors[2].b},
228  {_colors[3].r, _colors[3].g, _colors[3].b}};
230  _vao.generate(4);
231  }
232  }
233 
234  // draw a textured or colored quad
235  if (_texture)
236  {
237  _texture->bindActive(0);
238  sp->uniform1i("u_matTexture0", 0);
239  }
240 
241  //////////////////////////////////////
243  //////////////////////////////////////
244 }
245 //-----------------------------------------------------------------------------
246 //! Draws the background as a quad on the far clipping plane
247 /*! We render the quad as a triangle strip: <br>
248  LT RT
249  +-----+
250  | /|
251  | / |
252  | / |
253  | / |
254  |/ |
255  +-----+
256  LB RB
257 */
259  const SLVec3f& LT,
260  const SLVec3f& LB,
261  const SLVec3f& RT,
262  const SLVec3f& RB)
263 {
264  SLGLState* stateGL = SLGLState::instance();
265 
266  // Get shader program
267  SLGLProgram* sp = _texture
270  sp->useProgram();
271  sp->uniformMatrix4fv("u_mMatrix", 1, (const SLfloat*)&wm);
272  sp->uniformMatrix4fv("u_vMatrix", 1, (const SLfloat*)&stateGL->viewMatrix);
273  sp->uniformMatrix4fv("u_pMatrix", 1, (const SLfloat*)&stateGL->projectionMatrix);
274 
275  // Create or update buffer for vertex position and indices
276  _vao.clearAttribs();
277 
278  // Float array with vertices
279  SLVVec3f P = {LT, LB, RT, RB};
281 
282  // Indexes for a triangle strip
283  SLVushort I = {0, 1, 2, 3};
284  _vao.setIndices(&I);
285 
286  if (_texture)
287  { // Float array of texture coordinates
288  SLVVec2f T = {{0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}};
289  _vao.setAttrib(AT_uv1, AT_uv1, &T);
290  _vao.generate(4);
291  }
292  else
293  { // Float array of colors of corners
294  SLVVec3f C = {{_colors[0].r, _colors[0].g, _colors[0].b},
295  {_colors[1].r, _colors[1].g, _colors[1].b},
296  {_colors[2].r, _colors[2].g, _colors[2].b},
297  {_colors[3].r, _colors[3].g, _colors[3].b}};
299  _vao.generate(4);
300  }
301 
302  // draw a textured or colored quad
303  if (_texture)
304  {
305  _texture->bindActive(0);
306  sp->uniform1i("u_matTexture0", 0);
307  }
308 
309  ///////////////////////////////////////
311  ///////////////////////////////////////
312 }
313 //-----------------------------------------------------------------------------
314 //! Returns the interpolated color at the pixel position p[x,y] used in raytracing.
315 /*! Returns the interpolated color at the pixel position p[x,y] for ray tracing.
316  x is expected to be between 0 and width of the RT-frame.
317  y is expected to be between 0 and height of the RT-frame.
318  width is the width of the RT-frame
319  height is the height of the RT-frame
320 
321  C w B
322  +-----+
323  | p /|
324  | * / |
325  h | / |
326  | / |
327  |/ |
328  0 +-----+
329  A 0
330 */
332  SLfloat y,
333  SLfloat width,
334  SLfloat height)
335 {
336  if (_isUniform)
337  return _colors[0];
338 
339  if (_texture)
340  return _texture->getTexelf(x / width, y / height);
341 
342  // top-down gradient
343  if (_colors[0] == _colors[2] && _colors[1] == _colors[3])
344  {
345  SLfloat f = y / height;
346  return f * _colors[0] + (1 - f) * _colors[1];
347  }
348  // left-right gradient
349  if (_colors[0] == _colors[1] && _colors[2] == _colors[3])
350  {
351  SLfloat f = x / width;
352  return f * _colors[0] + (1 - f) * _colors[2];
353  }
354 
355  // Quadrilateral interpolation
356  // First check with barycentric coords if p is in the upper left triangle
357  SLVec2f p(x, y);
358  SLVec3f bc(p.barycentricCoords(SLVec2f(0, 0),
359  SLVec2f(width, height),
360  SLVec2f(0, height)));
361  SLfloat u = bc.x;
362  SLfloat v = bc.y;
363  SLfloat w = 1 - bc.x - bc.y;
364 
365  SLCol4f color;
366 
367  if (u > 0 && v > 0 && u + v <= 1)
368  color = w * _colors[0] + u * _colors[1] + v * _colors[2]; // upper left triangle
369  else
370  {
371  u = 1 - u;
372  v = 1 - v;
373  w = 1 - u - v;
374  color = w * _colors[3] + v * _colors[1] + u * _colors[2]; // lower right triangle
375  }
376 
377  return color;
378 }
379 //-----------------------------------------------------------------------------
static SLbool fixAspectRatio
Flag if wnd aspect ratio should be fixed.
Definition: AppGLFW.cpp:42
float SLfloat
Definition: SL.h:173
#define SL_LOG(...)
Definition: SL.h:233
vector< SLushort > SLVushort
Definition: SL.h:195
string SLstring
Definition: SL.h:158
int SLint
Definition: SL.h:170
@ AT_position
Vertex position as a 2, 3 or 4 component vectors.
Definition: SLGLEnums.h:58
@ AT_color
Vertex color as 3 or 4 component vector.
Definition: SLGLEnums.h:62
@ AT_uv1
Vertex 1st texture coordinate as 2 component vector.
Definition: SLGLEnums.h:60
@ PT_triangleStrip
Definition: SLGLEnums.h:36
vector< SLVec2f > SLVVec2f
Definition: SLVec2.h:143
SLVec2< SLfloat > SLVec2f
Definition: SLVec2.h:141
vector< SLVec3f > SLVVec3f
Definition: SLVec3.h:325
SLint _resY
Background resolution in y-dir.
Definition: SLBackground.h:68
SLCol4f _avgColor
Average color of all 4 corner colors.
Definition: SLBackground.h:64
SLGLProgram * _colorAttributeProgram
Definition: SLBackground.h:73
SLVCol4f _colors
Vector of 4 corner colors {TL,BL,TR,BR}.
Definition: SLBackground.h:63
SLBackground(SLstring shaderDir)
The constructor initializes to a uniform BLACK background color.
SLVCol4f colors()
Definition: SLBackground.h:55
SLGLProgram * _textureOnlyProgram
Definition: SLBackground.h:72
SLGLTexture * _texture
Pointer to a background texture.
Definition: SLBackground.h:65
const SLRectf & rect() const
Definition: SLBackground.h:59
SLGLTexture * texture()
Definition: SLBackground.h:58
SLGLVertexArray _vao
OpenGL Vertex Array Object for drawing.
Definition: SLBackground.h:70
void render(SLint widthPX, SLint heightPX)
Draws the background as 2D rectangle with OpenGL buffers.
SLRectf _rect
Background rect (it may be different to viewport size)
Definition: SLBackground.h:69
SLCol4f colorAtPos(SLfloat x, SLfloat y, SLfloat width, SLfloat height)
Returns the interpolated color at the pixel position p[x,y] used in raytracing.
bool _fixAspectRatio
if true, the background is centered and stretched to the screen boarders while keeping the textures a...
Definition: SLBackground.h:76
SLGLTexture * _textureError
Pointer to a error texture if background texture is not available.
Definition: SLBackground.h:66
bool _deletePrograms
Definition: SLBackground.h:74
SLbool _isUniform
Flag if background has uniform color.
Definition: SLBackground.h:62
SLint _resX
Background resolution in x-dir.
Definition: SLBackground.h:67
void renderInScene(const SLMat4f &wm, const SLVec3f &LT, const SLVec3f &LB, const SLVec3f &RT, const SLVec3f &RB)
Draws the background as a quad on the far clipping plane.
Generic Shader Program class inherited from SLGLProgram.
Encapsulation of an OpenGL shader program object.
Definition: SLGLProgram.h:56
SLint uniformMatrix4fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 4x4 float matrix values py pointer to the uniform variable "name".
SLint uniform1f(const SLchar *name, SLfloat v0) const
Passes the float value v0 to the uniform variable "name".
void useProgram()
SLint uniform1i(const SLchar *name, SLint v0) const
Passes the int values v0 to the uniform variable "name".
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
SLMat4f modelMatrix
Init all states.
Definition: SLGLState.h:89
void multiSample(SLbool state)
Definition: SLGLState.cpp:267
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
SLMat4f viewMatrix
matrix for the active cameras view transform
Definition: SLGLState.h:91
SLMat4f projectionMatrix
matrix for projection transform
Definition: SLGLState.h:90
void depthTest(SLbool state)
Definition: SLGLState.cpp:172
Texture object for OpenGL texturing.
Definition: SLGLTexture.h:110
SLuint height()
Definition: SLGLTexture.h:219
SLuint width()
Definition: SLGLTexture.h:218
void bindActive(SLuint texUnit=0)
SLCol4f getTexelf(SLfloat u, SLfloat v, SLuint imgIndex=0)
SLGLTexture::getTexelf returns a pixel color from u & v texture coordinates.
void clearAttribs()
Clears the attribute definition.
void drawElementsAs(SLGLPrimitiveType primitiveType, SLuint numIndexes=0, SLuint indexOffsetBytes=0)
Draws the VAO by element indices with a primitive type.
void setAttrib(SLGLAttributeType type, SLint elementSize, SLint location, void *dataPointer, SLGLBufferType dataType=BT_float)
Adds a vertex attribute with data pointer and an element size.
SLuint vaoID() const
Returns either the VAO id or the VBO id.
void setIndices(SLuint numIndicesElements, SLGLBufferType indexDataType, void *indexDataElements, SLuint numIndicesEdges=0, void *indexDataEdges=nullptr)
Adds the index array for indexed element drawing.
void generate(SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true, SLuint divisor=0)
Generates the VA & VB objects for a NO. of vertices.
static SLfloat oneOverGamma()
Definition: SLLight.h:203
void ortho(T l, T r, T b, T t, T n, T f)
Defines a orthographic projection matrix with a field of view angle.
Definition: SLMat4.h:911
void identity()
Sets the identity matrix.
Definition: SLMat4.h:1333
Base class for all other classes.
Definition: SLObject.h:23
void set(const T X, const T Y, const T WIDTH, const T HEIGHT)
Definition: SLRect.h:42
SLVec2 barycentricCoords(SLVec2 A, SLVec2 B, SLVec2 C)
Calculate the barycentric coordinate uv of the point within a triangle ABC.
Definition: SLVec2.h:105
T y
Definition: SLVec3.h:43
T x
Definition: SLVec3.h:43
static SLVec4 BLACK
Definition: SLVec4.h:213