OpenClonk
C4FoWRegion Class Reference

#include <C4FoWRegion.h>

Public Member Functions

 C4FoWRegion (C4FoW *pFoW, C4Player *pPlayer)
 
 ~C4FoWRegion ()
 
const C4FoWgetFoW () const
 
const C4RectgetRegion () const
 
const FLOAT_RECTgetViewportRegion () const
 
int32_t getSurfaceHeight () const
 
int32_t getSurfaceWidth () const
 
GLuint getSurfaceName () const
 
void Update (C4Rect r, const FLOAT_RECT &vp)
 
bool Render (const C4TargetFacet *pOnScreen=nullptr)
 
void GetFragTransform (const C4Rect &clipRect, const C4Rect &outRect, float lightTransform[6]) const
 

Detailed Description

Definition at line 30 of file C4FoWRegion.h.

Constructor & Destructor Documentation

◆ C4FoWRegion()

C4FoWRegion::C4FoWRegion ( C4FoW pFoW,
C4Player pPlayer 
)

Definition at line 21 of file C4FoWRegion.cpp.

22  : pFoW(pFoW)
23 #ifndef USE_CONSOLE
24  , pPlayer(pPlayer)
25  , hFrameBufDraw(0), hFrameBufRead(0), hVBO(0), vaoid(0)
26 #endif
27  , Region(0,0,0,0), OldRegion(0,0,0,0)
28  , pSurface(new C4Surface), pBackSurface(new C4Surface)
29 {
30  ViewportRegion.left = ViewportRegion.right = ViewportRegion.top = ViewportRegion.bottom = 0.0f;
31 }
float bottom
Definition: C4Rect.h:25
float top
Definition: C4Rect.h:25
float right
Definition: C4Rect.h:25
float left
Definition: C4Rect.h:25

References FLOAT_RECT::bottom, FLOAT_RECT::left, FLOAT_RECT::right, and FLOAT_RECT::top.

◆ ~C4FoWRegion()

C4FoWRegion::~C4FoWRegion ( )

Definition at line 33 of file C4FoWRegion.cpp.

34 {
35 #ifndef USE_CONSOLE
36  if (hFrameBufDraw) {
37  glDeleteFramebuffers(1, &hFrameBufDraw);
38  glDeleteFramebuffers(1, &hFrameBufRead);
39  }
40 
41  if (hVBO) {
42  glDeleteBuffers(1, &hVBO);
43  }
44 
45  if (vaoid) {
46  pGL->FreeVAOID(vaoid);
47  }
48 #endif
49 }
CStdGL * pGL
Definition: C4DrawGL.cpp:907
void FreeVAOID(unsigned int vaoid)
Definition: C4DrawGL.cpp:969

References CStdGL::FreeVAOID(), and pGL.

Here is the call graph for this function:

Member Function Documentation

◆ getFoW()

const C4FoW* C4FoWRegion::getFoW ( ) const
inline

Definition at line 52 of file C4FoWRegion.h.

52 { return pFoW; }

Referenced by C4LandscapeRenderGL::Draw(), and CStdGL::SetupMultiBlt().

Here is the caller graph for this function:

◆ GetFragTransform()

void C4FoWRegion::GetFragTransform ( const C4Rect clipRect,
const C4Rect outRect,
float  lightTransform[6] 
) const

Definition at line 342 of file C4FoWRegion.cpp.

343 {
344  const C4Rect& lightRect = getRegion();
345  const FLOAT_RECT& vpRect = ViewportRegion;
346 
347  C4FragTransform trans;
348  // Clip offset
349  assert(outRect.Hgt >= clipRect.y + clipRect.Hgt);
350  trans.Translate(-clipRect.x, -(outRect.Hgt - clipRect.y - clipRect.Hgt));
351  // Clip normalization (0,0 -> 1,1)
352  trans.Scale(1.0f / clipRect.Wdt, 1.0f / clipRect.Hgt);
353  // Viewport/Landscape normalization
354  trans.Scale(vpRect.right - vpRect.left, vpRect.bottom - vpRect.top);
355  // Offset between viewport and light texture
356  trans.Translate(vpRect.left - lightRect.x, vpRect.top - lightRect.y);
357  // Light surface normalization
358  trans.Scale(1.0f / pSurface->Wdt, 1.0f / pSurface->Hgt);
359  // Light surface Y offset
360  trans.Translate(0.0f, 1.0f - (float)(lightRect.Hgt) / (float)pSurface->Hgt);
361 
362  // Extract matrix
363  trans.Get2x3(lightTransform);
364 }
const C4Rect & getRegion() const
Definition: C4FoWRegion.h:53
void Scale(float sx, float sy)
Definition: C4FoW.h:45
void Get2x3(float transform[6])
Definition: C4FoW.h:54
void Translate(float dx, float dy)
Definition: C4FoW.h:38
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30

References FLOAT_RECT::bottom, C4FragTransform::Get2x3(), getRegion(), C4Rect::Hgt, FLOAT_RECT::left, FLOAT_RECT::right, C4FragTransform::Scale(), FLOAT_RECT::top, C4FragTransform::Translate(), C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by CStdGL::SetupMultiBlt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getRegion()

const C4Rect& C4FoWRegion::getRegion ( ) const
inline

Definition at line 53 of file C4FoWRegion.h.

53 { return Region; }

Referenced by C4FoWLightSection::CalculateTriangles(), C4LandscapeRenderGL::Draw(), and GetFragTransform().

Here is the caller graph for this function:

◆ getSurfaceHeight()

int32_t C4FoWRegion::getSurfaceHeight ( ) const

Definition at line 161 of file C4FoWRegion.cpp.

162 {
163  return pSurface->Hgt;
164 }

Referenced by C4LandscapeRenderGL::Draw(), and C4FoWDrawLightTextureStrategy::End().

Here is the caller graph for this function:

◆ getSurfaceName()

GLuint C4FoWRegion::getSurfaceName ( ) const

Definition at line 172 of file C4FoWRegion.cpp.

173 {
174  assert(pSurface->texture);
175  if (!pSurface->texture)
176  return 0;
177  return pSurface->texture->texName;
178 }

Referenced by C4LandscapeRenderGL::Draw(), and CStdGL::SetupMultiBlt().

Here is the caller graph for this function:

◆ getSurfaceWidth()

int32_t C4FoWRegion::getSurfaceWidth ( ) const

Definition at line 166 of file C4FoWRegion.cpp.

167 {
168  return pSurface->Wdt;
169 }

Referenced by C4LandscapeRenderGL::Draw(), and C4FoWDrawLightTextureStrategy::End().

Here is the caller graph for this function:

◆ getViewportRegion()

const FLOAT_RECT& C4FoWRegion::getViewportRegion ( ) const
inline

Definition at line 54 of file C4FoWRegion.h.

54 { return ViewportRegion; }

Referenced by C4LandscapeRenderGL::Draw(), and CStdGL::SetupMultiBlt().

Here is the caller graph for this function:

◆ Render()

bool C4FoWRegion::Render ( const C4TargetFacet pOnScreen = nullptr)

Definition at line 188 of file C4FoWRegion.cpp.

189 {
190 #ifndef USE_CONSOLE
191  GLint prev_fb;
192  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_fb);
193 
194  // Update FoW at interesting location
195  pFoW->Update(Region, pPlayer);
196 
197  // On screen? No need to set up frame buffer - simply shortcut
198  if (pOnScreen)
199  {
200  pFoW->Render(this, pOnScreen, pPlayer, pGL->GetProjectionMatrix());
201  return true;
202  }
203 
204  // Set up shader. If this one doesn't work, we're really in trouble.
205  C4Shader *pShader = pFoW->GetFramebufShader();
206  assert(pShader);
207  if (!pShader) return false;
208 
209  // Create & bind the frame buffer
211  if(!BindFramebuf(prev_fb))
212  {
214  return false;
215  }
216  assert(pSurface && hFrameBufDraw);
217  if (!pSurface || !hFrameBufDraw)
218  return false;
219 
220  // Set up a clean context
221  glViewport(0, 0, pSurface->Wdt, pSurface->Hgt);
222  const StdProjectionMatrix projectionMatrix = StdProjectionMatrix::Orthographic(0.0f, pSurface->Wdt, pSurface->Hgt, 0.0f);
223 
224  // Clear texture contents
225  assert(pSurface->Hgt % 2 == 0);
226  glScissor(0, pSurface->Hgt / 2, pSurface->Wdt, pSurface->Hgt / 2);
227  glClearColor(0.0f, 0.5f / 1.5f, 0.5f / 1.5f, 0.0f);
228  glEnable(GL_SCISSOR_TEST);
229  glClear(GL_COLOR_BUFFER_BIT);
230 
231  // clear lower half of texture
232  glScissor(0, 0, pSurface->Wdt, pSurface->Hgt / 2);
233  glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
234  glClear(GL_COLOR_BUFFER_BIT);
235  glDisable(GL_SCISSOR_TEST);
236 
237  // Render FoW to frame buffer object
238  glBlendFunc(GL_ONE, GL_ONE);
239  pFoW->Render(this, nullptr, pPlayer, projectionMatrix);
240 
241  // Copy over the old state
242  if (OldRegion.Wdt > 0)
243  {
244 
245  // How much the borders have moved
246  int dx0 = Region.x - OldRegion.x,
247  dy0 = Region.y - OldRegion.y,
248  dx1 = Region.x + Region.Wdt - OldRegion.x - OldRegion.Wdt,
249  dy1 = Region.y + Region.Hgt - OldRegion.y - OldRegion.Hgt;
250 
251  // Source and target rect coordinates (landscape coordinate system)
252  int sx0 = std::max(0, dx0), sy0 = std::max(0, dy0),
253  sx1 = OldRegion.Wdt - std::max(0, -dx1), sy1 = OldRegion.Hgt - std::max(0, -dy1),
254  tx0 = std::max(0, -dx0), ty0 = std::max(0, -dy0),
255  tx1 = Region.Wdt - std::max(0, dx1), ty1 = Region.Hgt - std::max(0, dy1);
256 
257  // Quad coordinates
258  float vtxData[16];
259  float* squad = &vtxData[0];
260  float* tquad = &vtxData[8];
261 
262  squad[0] = float(sx0);
263  squad[1] = float(sy0);
264  squad[2] = float(sx0);
265  squad[3] = float(sy1);
266  squad[4] = float(sx1);
267  squad[5] = float(sy0);
268  squad[6] = float(sx1);
269  squad[7] = float(sy1);
270 
271  tquad[0] = float(tx0);
272  tquad[1] = float(ty0);
273  tquad[2] = float(tx0);
274  tquad[3] = float(ty1);
275  tquad[4] = float(tx1);
276  tquad[5] = float(ty0);
277  tquad[6] = float(tx1);
278  tquad[7] = float(ty1);
279 
280  // Transform into texture coordinates
281  for (int i = 0; i < 4; i++)
282  {
283  squad[i*2] = squad[i*2] / pBackSurface->Wdt;
284  squad[i*2+1] = 1.0 - squad[i*2+1] / pBackSurface->Hgt;
285  }
286 
287  // Load coordinates into vertex buffer
288  if (hVBO == 0)
289  {
290  glGenBuffers(1, &hVBO);
291  glBindBuffer(GL_ARRAY_BUFFER, hVBO);
292  glBufferData(GL_ARRAY_BUFFER, sizeof(vtxData), vtxData, GL_STREAM_DRAW);
293 
294  assert(vaoid == 0);
295  vaoid = pGL->GenVAOID();
296  }
297  else
298  {
299  glBindBuffer(GL_ARRAY_BUFFER, hVBO);
300  glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vtxData), vtxData);
301  }
302 
303  // Copy using shader
304  C4ShaderCall Call(pShader);
305  Call.Start();
306  if (Call.AllocTexUnit(C4FoWFSU_Texture))
307  glBindTexture(GL_TEXTURE_2D, pBackSurface->texture->texName);
308  Call.SetUniformMatrix4x4(C4FoWFSU_ProjectionMatrix, projectionMatrix);
309  glBlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR);
310  float normalBlend = 1.0f / 4.0f, // Normals change quickly
311  brightBlend = 1.0f / 16.0f; // Intensity more slowly
312  glBlendColor(0.0f,normalBlend,normalBlend,brightBlend);
313 
314  GLuint vao;
315  const bool has_vao = pGL->GetVAO(vaoid, vao);
316  glBindVertexArray(vao);
317  if (!has_vao)
318  {
319  glEnableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_Position));
320  glEnableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_TexCoord));
321  glVertexAttribPointer(pShader->GetAttribute(C4FoWFSA_Position), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const uint8_t*>(8 * sizeof(float)));
322  glVertexAttribPointer(pShader->GetAttribute(C4FoWFSA_TexCoord), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const uint8_t*>(0));
323  }
324 
325  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
326 
327  glBindVertexArray(0);
328  glBindBuffer(GL_ARRAY_BUFFER, 0);
329 
330  Call.Finish();
331  }
332 
333  // Done!
334  glBindFramebuffer(GL_FRAMEBUFFER, prev_fb);
336 
337  OldRegion = Region;
338 #endif
339  return true;
340 }
C4Draw * pDraw
Definition: C4Draw.cpp:42
@ C4FoWFSU_Texture
Definition: C4FoW.h:71
@ C4FoWFSU_ProjectionMatrix
Definition: C4FoW.h:70
@ C4FoWFSA_Position
Definition: C4FoW.h:77
@ C4FoWFSA_TexCoord
Definition: C4FoW.h:78
bool RestorePrimaryClipper()
Definition: C4Draw.cpp:210
bool StorePrimaryClipper()
Definition: C4Draw.cpp:203
C4Shader * GetFramebufShader()
Definition: C4FoW.cpp:47
void Render(class C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr, const StdProjectionMatrix &projectionMatrix)
Definition: C4FoW.cpp:238
void Update(C4Rect r, C4Player *player)
Definition: C4FoW.cpp:229
GLint GetAttribute(int iAttribute) const
Definition: C4Shader.h:127
const StdProjectionMatrix & GetProjectionMatrix() const
Definition: C4DrawGL.h:254
unsigned int GenVAOID()
Definition: C4DrawGL.cpp:927
bool GetVAO(unsigned int vaoid, GLuint &vao)
Definition: C4DrawGL.cpp:1015
static StdProjectionMatrix Orthographic(float left, float right, float bottom, float top)

References C4FoWFSA_Position, C4FoWFSA_TexCoord, C4FoWFSU_ProjectionMatrix, C4FoWFSU_Texture, C4ScriptGuiWindowActionID::Call, CStdGL::GenVAOID(), C4Shader::GetAttribute(), C4FoW::GetFramebufShader(), CStdGL::GetProjectionMatrix(), CStdGL::GetVAO(), C4Rect::Hgt, StdProjectionMatrix::Orthographic(), pDraw, pGL, C4FoW::Render(), C4Draw::RestorePrimaryClipper(), C4Draw::StorePrimaryClipper(), C4FoW::Update(), C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by C4Viewport::Draw().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Update()

void C4FoWRegion::Update ( C4Rect  r,
const FLOAT_RECT vp 
)

Definition at line 181 of file C4FoWRegion.cpp.

182 {
183  // Set the new region
184  Region = r;
185  ViewportRegion = vp;
186 }

Referenced by C4Viewport::Draw().

Here is the caller graph for this function:

The documentation for this class was generated from the following files: