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