Otclient 1.0  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"
28 #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  m_redraw = true;
41  reset();
42 }
43 
44 TexturePtr LightView::generateLightBubble(float centerFactor)
45 {
46  const int bubbleRadius = 256;
47  const int centerRadius = bubbleRadius * centerFactor;
48  const int bubbleDiameter = bubbleRadius * 2;
49  ImagePtr lightImage = ImagePtr(new Image(Size(bubbleDiameter, bubbleDiameter)));
50 
51  for(int x = 0; x < bubbleDiameter; ++x) {
52  for(int y = 0; y < bubbleDiameter; ++y) {
53  const float radius = std::sqrt((bubbleRadius - x) * (bubbleRadius - x) + (bubbleRadius - y) * (bubbleRadius - y));
54  float intensity = stdext::clamp<float>((bubbleRadius - radius) / static_cast<float>(bubbleRadius - centerRadius), 0.0f, 1.0f);
55 
56  // light intensity varies inversely with the square of the distance
57  intensity *= intensity;
58  const uint8_t colorByte = intensity * 0xB4;
59 
60  uint8_t pixel[4] = { colorByte, colorByte, colorByte, 0xff };
61  lightImage->setPixel(x, y, pixel);
62  }
63  }
64 
65  TexturePtr tex = TexturePtr(new Texture(lightImage, true));
66  tex->setSmooth(true);
67  return tex;
68 }
69 
71 {
72  m_lightMap.clear();
73 }
74 
75 void LightView::setGlobalLight(const Light& light)
76 {
77  m_globalLight = light;
78 }
79 
80 void LightView::addLightSource(const Point& center, float scaleFactor, const Light& light)
81 {
82  const int intensity = light.intensity;
83  const int radius = (intensity * Otc::TILE_PIXELS * scaleFactor) * 1.25;
84 
85  Color color = Color::from8bit(light.color);
86 
87  const float brightnessLevel = light.intensity > 1 ? 0.7 : 0.2f;
88  const float brightness = brightnessLevel + (intensity / static_cast<float>(MAX_LIGHT_INTENSITY)) * brightnessLevel;
89 
90  color.setRed(color.rF() * brightness);
91  color.setGreen(color.gF() * brightness);
92  color.setBlue(color.bF() * brightness);
93 
94  if(m_blendEquation == Painter::BlendEquation_Add && !m_lightMap.empty()) {
95  const LightSource prevSource = m_lightMap.back();
96  if(prevSource.center == center && prevSource.color == color && prevSource.radius == radius)
97  return;
98  }
99 
100  LightSource source;
101  source.center = center;
102  source.color = color;
103  source.radius = radius;
104  m_lightMap.push_back(source);
105 }
106 
107 void LightView::drawGlobalLight(const Light& light)
108 {
109  Color color = Color::from8bit(light.color);
110  const float brightness = light.intensity / static_cast<float>(MAX_AMBIENT_LIGHT_INTENSITY);
111  color.setRed(color.rF() * brightness);
112  color.setGreen(color.gF() * brightness);
113  color.setBlue(color.bF() * brightness);
114 
115  g_painter->setColor(color);
116  g_painter->drawFilledRect(Rect(0, 0, m_lightbuffer->getSize()));
117 }
118 
119 void LightView::drawLightSource(const Point& center, const Color& color, int radius)
120 {
121  // debug draw
122  //radius /= 16;
123 
124  const Rect dest = Rect(center - Point(radius, radius), Size(radius * 2, radius * 2));
125  g_painter->setColor(color);
126  g_painter->drawTexturedRect(dest, m_lightTexture);
127 }
128 
129 void LightView::resize(const Size& size)
130 {
131  m_lightbuffer->resize(size);
132 }
133 
134 void LightView::draw(const Rect& dest, const Rect& src)
135 {
136  if(!isDark() || m_lightbuffer->getTexture() == nullptr) return;
137 
138  // draw light, only if there is darkness
140  if(m_redraw) {
141  m_lightbuffer->bind();
143 
144  drawGlobalLight(m_globalLight);
145 
146  g_painter->setBlendEquation(m_blendEquation);
148 
149  for(const LightSource& source : m_lightMap)
150  drawLightSource(source.center, source.color, source.radius);
151 
152  m_redraw = false;
153  m_lightbuffer->release();
154  m_minTimeRender.restart();
155  }
157 
158  m_lightbuffer->draw(dest, src);
160 }
Painter::setColor
virtual void setColor(const Color &color)
Definition: painter.h:77
LightView::setGlobalLight
void setGlobalLight(const Light &light)
Definition: lightview.cpp:75
Painter::restoreSavedState
virtual void restoreSavedState()=0
Otc::TILE_PIXELS
@ TILE_PIXELS
Definition: const.h:33
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:129
Painter::CompositionMode_Add
@ CompositionMode_Add
Definition: painter.h:41
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:80
Color::gF
float gF() const
Definition: color.h:51
LightView::isDark
bool isDark() const
Definition: lightview.h:51
MAX_LIGHT_INTENSITY
@ MAX_LIGHT_INTENSITY
Definition: lightview.cpp:31
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
MAX_AMBIENT_LIGHT_INTENSITY
@ MAX_AMBIENT_LIGHT_INTENSITY
Definition: lightview.cpp:32
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:122
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
Timer::restart
void restart()
Definition: timer.cpp:27
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:134
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:123
FrameBuffer::resize
void resize(const Size &size)
Definition: framebuffer.cpp:57
LightView::reset
void reset()
Definition: lightview.cpp:70
Light
Definition: thingtype.h:120
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
FrameBuffer::getTexture
TexturePtr getTexture()
Definition: framebuffer.h:49
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