OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4FoW.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2014-2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #include "C4Include.h"
18 #include "landscape/fow/C4FoW.h"
19 #include "graphics/C4Draw.h"
20 
21 #include <cfloat>
22 
23 
24 C4FoW::C4FoW() = default;
25 
27 {
28  if (deleted_lights)
29  {
32  }
33 }
34 
36 {
37 #ifndef USE_CONSOLE
38  // Kill any dead lights
39  while (deleted_lights)
40  {
41  C4FoWLight *light = deleted_lights;
42  deleted_lights = deleted_lights->getNext();
43  delete light;
44  }
45 #endif
46 }
47 
49 {
50 #ifndef USE_CONSOLE
51  // Not created yet?
52  if (!FramebufShader.Initialised())
53  {
54  // Create the frame buffer shader. The details are in C4FoWRegion, but
55  // this is about how to utilise old frame buffer data in the lights texture.
56  // Or put in other words: This shader is responsible for fading lights out.
57  const char* FramebufVertexShader =
58  "in vec2 oc_Position;\n"
59  "in vec2 oc_TexCoord;\n"
60  "out vec2 texcoord;\n"
61  "uniform mat4 projectionMatrix;\n"
62  "\n"
63  "slice(position)\n"
64  "{\n"
65  " gl_Position = projectionMatrix * vec4(oc_Position, 0.0, 1.0);\n"
66  "}\n"
67  "\n"
68  "slice(texcoord)\n"
69  "{\n"
70  " texcoord = oc_TexCoord;\n"
71  "}";
72 
73  const char* FramebufFragmentShader =
74  "in vec2 texcoord;\n"
75  "uniform sampler2D tex;\n"
76  "out vec4 fragColor;\n"
77  "\n"
78  "slice(color)\n"
79  "{\n"
80  " fragColor = texture(tex, texcoord);\n"
81  "}";
82 
83  FramebufShader.AddVertexSlices("built-in FoW framebuf shader", FramebufVertexShader);
84  FramebufShader.AddFragmentSlices("built-in FoW framebuf shader", FramebufFragmentShader);
85 
86  const char *szUniforms[C4FoWFSU_Count + 1];
87  szUniforms[C4FoWFSU_ProjectionMatrix] = "projectionMatrix";
88  szUniforms[C4FoWFSU_Texture] = "tex";
89  szUniforms[C4FoWFSU_Count] = nullptr;
90 
91  const char *szAttributes[C4FoWFSA_Count + 1];
92  szAttributes[C4FoWFSA_Position] = "oc_Position";
93  szAttributes[C4FoWFSA_TexCoord] = "oc_TexCoord";
94  szAttributes[C4FoWFSA_Count] = nullptr;
95 
96  if (!FramebufShader.Init("framebuf", szUniforms, szAttributes)) {
97  FramebufShader.ClearSlices();
98  return nullptr;
99  }
100  }
101  return &FramebufShader;
102 #else
103  return nullptr;
104 #endif
105 }
106 
108 {
109 #ifndef USE_CONSOLE
110  // Not created yet?
111  if (!RenderShader.Initialised())
112  {
113  // Create the render shader. Fairly simple pass-through.
114  const char* RenderVertexShader =
115  "in vec2 oc_Position;\n"
116  "in vec4 oc_Color;\n"
117  "out vec4 vtxColor;\n"
118  "uniform mat4 projectionMatrix;\n"
119  "uniform vec2 vertexOffset;\n"
120  "\n"
121  "slice(position)\n"
122  "{\n"
123  " gl_Position = projectionMatrix * vec4(oc_Position + vertexOffset, 0.0, 1.0);\n"
124  "}\n"
125  "\n"
126  "slice(color)\n"
127  "{\n"
128  " vtxColor = oc_Color;\n"
129  "}";
130 
131  const char* RenderFragmentShader =
132  "in vec4 vtxColor;\n"
133  "out vec4 fragColor;\n"
134  "\n"
135  "slice(color)\n"
136  "{\n"
137  " fragColor = vtxColor;\n"
138  "}";
139 
140  RenderShader.AddVertexSlices("built-in FoW render shader", RenderVertexShader);
141  RenderShader.AddFragmentSlices("built-in FoW render shader", RenderFragmentShader);
142 
143  const char* szUniforms[C4FoWRSU_Count + 1];
144  szUniforms[C4FoWRSU_ProjectionMatrix] = "projectionMatrix";
145  szUniforms[C4FoWRSU_VertexOffset] = "vertexOffset";
146  szUniforms[C4FoWRSU_Count] = nullptr;
147 
148  const char* szAttributes[C4FoWRSA_Count + 1];
149  szAttributes[C4FoWRSA_Position] = "oc_Position";
150  szAttributes[C4FoWRSA_Color] = "oc_Color";
151  szAttributes[C4FoWRSA_Count] = nullptr;
152 
153  if (!RenderShader.Init("fowRender", szUniforms, szAttributes)) {
154  RenderShader.ClearSlices();
155  return nullptr;
156  }
157 
158  }
159  return &RenderShader;
160 #else
161  return nullptr;
162 #endif
163 }
164 
165 
166 void C4FoW::Add(C4Object *pObj)
167 {
168 #ifndef USE_CONSOLE
169  // No view range? Probably want to remove instead
170  if(!pObj->lightRange && !pObj->lightFadeoutRange)
171  {
172  Remove(pObj);
173  return;
174  }
175 
176  // Safety
177  if (!pObj->Status) return;
178 
179  // Look for matching light
180  C4FoWLight *pLight;
181  for (pLight = pLights; pLight; pLight = pLight->getNext())
182  if (pLight->getObj() == pObj)
183  break;
184 
185  if (pLight)
186  {
187 
188  // Update reach and light color
189  pLight->SetReach(pObj->lightRange, pObj->lightFadeoutRange);
190  pLight->SetColor(pObj->lightColor);
191  }
192  else
193  {
194  // Create new light otherwise
195  pLight = new C4FoWLight(pObj);
196  pLight->pNext = pLights;
197  pLights = pLight;
198  }
199 #endif
200 }
201 
203 {
204 #ifndef USE_CONSOLE
205  // Look for matching light
206  C4FoWLight *pPrev = nullptr, *pLight;
207  for (pLight = pLights; pLight; pPrev = pLight, pLight = pLight->getNext())
208  if (pLight->getObj() == pObj)
209  break;
210  if (!pLight)
211  return;
212 
213  // Remove from list
214  (pPrev ? pPrev->pNext : pLights) = pLight->getNext();
215 
216  // Delete on next render pass
217  pLight->pNext = deleted_lights;
218  deleted_lights = pLight;
219 #endif
220 }
221 
223 {
224 #ifndef USE_CONSOLE
225  for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
226  pLight->Invalidate(r);
227 #endif
228 }
229 
231 {
232 #ifndef USE_CONSOLE
233  for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
234  if (pLight->IsVisibleForPlayer(pPlr))
235  pLight->Update(r);
236 #endif
237 }
238 
239 void C4FoW::Render(C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr, const StdProjectionMatrix& projectionMatrix)
240 {
241 #ifndef USE_CONSOLE
242  // Delete any dead lights
244  // Set up shader. If this one doesn't work, we're really in trouble.
245  C4Shader *pShader = GetRenderShader();
246  assert(pShader);
247  if (!pShader) return;
248 
249  C4ShaderCall Call(pShader);
250  Call.Start();
251  Call.SetUniformMatrix4x4(C4FoWRSU_ProjectionMatrix, projectionMatrix);
252 
253  for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
254  if (pLight->IsVisibleForPlayer(pPlr))
255  pLight->Render(pRegion, pOnScreen, Call);
256 
257  Call.Finish();
258 #endif
259 }
void AddFragmentSlices(const char *szWhat, const char *szText, const char *szSource="", int iFileTime=0)
Definition: C4Shader.cpp:85
void SetColor(uint32_t iValue)
Definition: C4FoWLight.cpp:81
void Invalidate(C4Rect r)
Definition: C4FoW.cpp:222
C4Object * getObj() const
Definition: C4FoWLight.h:72
void AddVertexSlices(const char *szWhat, const char *szText, const char *szSource="", int iFileTime=0)
Definition: C4Shader.cpp:80
C4Shader * GetFramebufShader()
Definition: C4FoW.cpp:48
Definition: C4Rect.h:27
void ClearSlices()
Definition: C4Shader.cpp:322
C4FoWLight * getNext() const
Definition: C4FoWLight.h:71
int32_t lightFadeoutRange
Definition: C4Object.h:123
~C4FoW()
Definition: C4FoW.cpp:26
void ClearDeletedLights()
Definition: C4FoW.cpp:35
int32_t lightRange
Definition: C4Object.h:122
void Update(C4Rect r, C4Player *player)
Definition: C4FoW.cpp:230
void Add(C4Object *pObj)
Definition: C4FoW.cpp:166
void Finish()
Definition: C4Shader.cpp:703
C4Draw * pDraw
Definition: C4Draw.cpp:42
int32_t Status
Definition: C4PropList.h:168
void Remove(C4Object *pObj)
Definition: C4FoW.cpp:202
bool Initialised() const
Definition: C4Shader.h:106
bool Init(const char *szWhat, const char **szUniforms, const char **szAttributes)
Definition: C4Shader.cpp:346
void SetUniformMatrix4x4(int iUniform, const StdMeshMatrix &matrix)
Definition: C4Shader.h:351
C4Shader * GetRenderShader()
Definition: C4FoW.cpp:107
void Render(class C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr, const StdProjectionMatrix &projectionMatrix)
Definition: C4FoW.cpp:239
void Start()
Definition: C4Shader.cpp:689
void SetReach(int32_t iReach, int32_t iFadeout)
Definition: C4FoWLight.cpp:58
uint32_t lightColor
Definition: C4Object.h:124
virtual bool EnsureMainContextSelected()=0