Otclient  14/8/2020
lightview.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "lightview.h"
24 #include "mapview.h"
29 
30 enum {
33 };
34 
36 {
37  m_lightbuffer = g_framebuffers.createFrameBuffer();
38  m_lightTexture = generateLightBubble(0.1f);
39  m_blendEquation = Painter::BlendEquation_Add;
40  reset();
41 }
42 
43 TexturePtr LightView::generateLightBubble(float centerFactor)
44 {
45  int bubbleRadius = 256;
46  int centerRadius = bubbleRadius * centerFactor;
47  int bubbleDiameter = bubbleRadius * 2;
48  ImagePtr lightImage = ImagePtr(new Image(Size(bubbleDiameter, bubbleDiameter)));
49 
50  for(int x = 0; x < bubbleDiameter; x++) {
51  for(int y = 0; y < bubbleDiameter; y++) {
52  float radius = std::sqrt((bubbleRadius - x)*(bubbleRadius - x) + (bubbleRadius - y)*(bubbleRadius - y));
53  float intensity = stdext::clamp<float>((bubbleRadius - radius) / (float)(bubbleRadius - centerRadius), 0.0f, 1.0f);
54 
55  // light intensity varies inversely with the square of the distance
56  intensity = intensity * intensity;
57  uint8_t colorByte = intensity * 0xff;
58 
59  uint8_t pixel[4] = {colorByte,colorByte,colorByte,0xff};
60  lightImage->setPixel(x, y, pixel);
61  }
62  }
63 
64  TexturePtr tex = TexturePtr(new Texture(lightImage, true));
65  tex->setSmooth(true);
66  return tex;
67 }
68 
70 {
71  m_lightMap.clear();
72 }
73 
74 void LightView::setGlobalLight(const Light& light)
75 {
76  m_globalLight = light;
77 }
78 
79 void LightView::addLightSource(const Point& center, float scaleFactor, const Light& light)
80 {
81  int intensity = std::min<int>(light.intensity, MAX_LIGHT_INTENSITY);
82  int radius = intensity * Otc::TILE_PIXELS * scaleFactor;
83 
84  Color color = Color::from8bit(light.color);
85  float brightness = 0.5f + (intensity/(float)MAX_LIGHT_INTENSITY)*0.5f;
86 
87  color.setRed(color.rF() * brightness);
88  color.setGreen(color.gF() * brightness);
89  color.setBlue(color.bF() * brightness);
90 
91  if(m_blendEquation == Painter::BlendEquation_Add && !m_lightMap.empty()) {
92  LightSource prevSource = m_lightMap.back();
93  if(prevSource.center == center && prevSource.color == color && prevSource.radius == radius)
94  return;
95  }
96 
97  LightSource source;
98  source.center = center;
99  source.color = color;
100  source.radius = radius;
101  m_lightMap.push_back(source);
102 }
103 
104 void LightView::drawGlobalLight(const Light& light)
105 {
106  Color color = Color::from8bit(light.color);
107  float brightness = light.intensity / (float)MAX_AMBIENT_LIGHT_INTENSITY;
108  color.setRed(color.rF() * brightness);
109  color.setGreen(color.gF() * brightness);
110  color.setBlue(color.bF() * brightness);
111  g_painter->setColor(color);
112  g_painter->drawFilledRect(Rect(0,0,m_lightbuffer->getSize()));
113 }
114 
115 void LightView::drawLightSource(const Point& center, const Color& color, int radius)
116 {
117  // debug draw
118  //radius /= 16;
119 
120  Rect dest = Rect(center - Point(radius, radius), Size(radius*2,radius*2));
121  g_painter->setColor(color);
122  g_painter->drawTexturedRect(dest, m_lightTexture);
123 }
124 
125 void LightView::resize(const Size& size)
126 {
127  m_lightbuffer->resize(size);
128 }
129 
130 void LightView::draw(const Rect& dest, const Rect& src)
131 {
133  m_lightbuffer->bind();
135  drawGlobalLight(m_globalLight);
136  g_painter->setBlendEquation(m_blendEquation);
138  for(const LightSource& source : m_lightMap)
139  drawLightSource(source.center, source.color, source.radius);
140  m_lightbuffer->release();
142  m_lightbuffer->draw(dest, src);
144 }
Painter::setColor
virtual void setColor(const Color &color)
Definition: painter.h:77
LightView::setGlobalLight
void setGlobalLight(const Light &light)
Definition: lightview.cpp:74
Painter::restoreSavedState
virtual void restoreSavedState()=0
Otc::TILE_PIXELS
@ TILE_PIXELS
Definition: const.h:29
lightview.h
Painter::BlendEquation_Add
@ BlendEquation_Add
Definition: painter.h:35
Color
Definition: color.h:32
LightView::resize
void resize(const Size &size)
Definition: lightview.cpp:125
Painter::CompositionMode_Add
@ CompositionMode_Add
Definition: painter.h:41
MAX_LIGHT_INTENSITY
@ MAX_LIGHT_INTENSITY
Definition: lightview.cpp:31
Painter::saveAndResetState
virtual void saveAndResetState()=0
Painter::setCompositionMode
virtual void setCompositionMode(CompositionMode compositionMode)=0
TRect< int >
Color::rF
float rF() const
Definition: color.h:52
Texture
Definition: texture.h:28
LightSource::color
Color color
Definition: lightview.h:32
LightView::addLightSource
void addLightSource(const Point &center, float scaleFactor, const Light &light)
Definition: lightview.cpp:79
Color::gF
float gF() const
Definition: color.h:51
Color::setRed
void setRed(int r)
Definition: color.h:56
Point
TPoint< int > Point
Definition: point.h:86
Color::setBlue
void setBlue(int b)
Definition: color.h:58
ImagePtr
stdext::shared_object_ptr< Image > ImagePtr
Definition: declarations.h:46
Painter::CompositionMode_Light
@ CompositionMode_Light
Definition: painter.h:44
framebuffermanager.h
Image
Definition: image.h:29
painter.h
Light::intensity
uint8 intensity
Definition: thingtype.h:119
Color::setGreen
void setGreen(int g)
Definition: color.h:57
LightSource::center
Point center
Definition: lightview.h:33
FrameBuffer::draw
void draw()
Definition: framebuffer.cpp:97
Painter::CompositionMode_Replace
@ CompositionMode_Replace
Definition: painter.h:42
FrameBuffer::release
void release()
Definition: framebuffer.cpp:91
mapview.h
LightView::LightView
LightView()
Definition: lightview.cpp:35
image.h
Size
TSize< int > Size
Definition: size.h:107
TexturePtr
stdext::shared_object_ptr< Texture > TexturePtr
Definition: declarations.h:49
LightSource
Definition: lightview.h:31
Rect
TRect< int > Rect
Definition: rect.h:319
FrameBuffer::bind
void bind()
Definition: framebuffer.cpp:84
FrameBufferManager::createFrameBuffer
FrameBufferPtr createFrameBuffer()
Definition: framebuffermanager.cpp:39
Color::bF
float bF() const
Definition: color.h:50
LightView::draw
void draw(const Rect &dest, const Rect &src)
Definition: lightview.cpp:130
stdext::shared_object_ptr
Definition: shared_object.h:39
g_painter
Painter * g_painter
Definition: painter.cpp:28
Light::color
uint8 color
Definition: thingtype.h:120
FrameBuffer::resize
void resize(const Size &size)
Definition: framebuffer.cpp:57
LightView::reset
void reset()
Definition: lightview.cpp:69
Light
Definition: thingtype.h:117
MAX_AMBIENT_LIGHT_INTENSITY
@ MAX_AMBIENT_LIGHT_INTENSITY
Definition: lightview.cpp:32
framebuffer.h
Painter::setBlendEquation
virtual void setBlendEquation(BlendEquation blendEquation)=0
TPoint< int >
FrameBuffer::getSize
Size getSize()
Definition: framebuffer.cpp:148
Color::from8bit
static Color from8bit(int color)
Definition: color.h:90
g_framebuffers
FrameBufferManager g_framebuffers
Definition: framebuffermanager.cpp:26
Painter::drawFilledRect
virtual void drawFilledRect(const Rect &dest)=0
TSize< int >
LightSource::radius
int radius
Definition: lightview.h:34
Painter::drawTexturedRect
virtual void drawTexturedRect(const Rect &dest, const TexturePtr &texture, const Rect &src)=0