25 , hFrameBufDraw(0), hFrameBufRead(0), hVBO(0), vaoid(0)
27 , Region(0,0,0,0), OldRegion(0,0,0,0)
30 ViewportRegion.
left = ViewportRegion.
right = ViewportRegion.
top = ViewportRegion.
bottom = 0.0f;
37 glDeleteFramebuffers(1, &hFrameBufDraw);
38 glDeleteFramebuffers(1, &hFrameBufRead);
42 glDeleteBuffers(1, &hVBO);
52 bool C4FoWRegion::BindFramebuf(GLuint prev_fb)
55 pSurface.swap(pBackSurface);
58 if (pSurface->Wdt < Region.
Wdt || (pSurface->Hgt / 2) < Region.
Hgt)
63 int iWdt = 1, iHgt = 1;
64 while (iWdt < Region.
Wdt) iWdt *= 2;
65 while (iHgt < Region.
Hgt) iHgt *= 2;
73 std::unique_ptr<C4Surface> pNewSurface(
new C4Surface);
74 std::unique_ptr<C4Surface> pNewBackSurface(
new C4Surface);
75 if (!pNewSurface->Create(iWdt, iHgt))
77 if (!pNewBackSurface->Create(iWdt, iHgt))
87 pNewBackSurface->Lock();
92 for (
int y = 0; y < iHgt / 2; ++y)
94 for (
int x = 0; x < iWdt; ++x)
96 if (y < pSurface->Hgt / 2 && x < pSurface->Wdt)
99 pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y - 1, pSurface->GetPixDw(x, pSurface->Hgt/2 - y - 1,
false));
100 pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y - 1, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y - 1,
false));
103 pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2 - 1, pSurface->GetPixDw(x, pSurface->Hgt/2 - y + pSurface->Hgt / 2 - 1,
false));
104 pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2 - 1, pBackSurface->GetPixDw(x, pBackSurface->Hgt/2 - y + pBackSurface->Hgt / 2 - 1,
false));
109 pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y - 1, 0x000000ff);
110 pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y - 1, 0x000000ff);
113 pNewSurface->SetPixDw(x, pNewSurface->Hgt/2 - y + iHgt / 2 - 1, 0x000000ff);
114 pNewBackSurface->SetPixDw(x, pNewBackSurface->Hgt/2 - y + iHgt / 2 - 1, 0x000000ff);
119 pSurface = std::move(pNewSurface);
120 pBackSurface = std::move(pNewBackSurface);
123 pBackSurface->Unlock();
127 if (!pSurface->iTexSize)
return false;
132 glGenFramebuffers(1, &hFrameBufDraw);
133 glGenFramebuffers(1, &hFrameBufRead);
137 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, hFrameBufDraw);
138 glBindFramebuffer(GL_READ_FRAMEBUFFER, hFrameBufRead);
139 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
140 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
141 pSurface->texture->texName, 0);
142 if (pBackSurface->texture)
143 glFramebufferTexture2D(GL_READ_FRAMEBUFFER,
144 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
145 pBackSurface->texture->texName, 0);
148 GLenum status1 = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER),
149 status2 = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
150 if (status1 != GL_FRAMEBUFFER_COMPLETE ||
151 (pBackSurface && status2 != GL_FRAMEBUFFER_COMPLETE))
153 glBindFramebuffer(GL_FRAMEBUFFER, prev_fb);
163 return pSurface->Hgt;
168 return pSurface->Wdt;
174 assert(pSurface->texture);
175 if (!pSurface->texture)
177 return pSurface->texture->texName;
192 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_fb);
195 pFoW->
Update(Region, pPlayer);
207 if (!pShader)
return false;
211 if(!BindFramebuf(prev_fb))
216 assert(pSurface && hFrameBufDraw);
217 if (!pSurface || !hFrameBufDraw)
221 glViewport(0, 0, pSurface->Wdt, pSurface->Hgt);
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);
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);
238 glBlendFunc(GL_ONE, GL_ONE);
239 pFoW->
Render(
this,
nullptr, pPlayer, projectionMatrix);
242 if (OldRegion.
Wdt > 0)
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;
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);
259 float* squad = &vtxData[0];
260 float* tquad = &vtxData[8];
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);
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);
281 for (
int i = 0; i < 4; i++)
283 squad[i*2] = squad[i*2] / pBackSurface->Wdt;
284 squad[i*2+1] = 1.0 - squad[i*2+1] / pBackSurface->Hgt;
290 glGenBuffers(1, &hVBO);
291 glBindBuffer(GL_ARRAY_BUFFER, hVBO);
292 glBufferData(GL_ARRAY_BUFFER,
sizeof(vtxData), vtxData, GL_STREAM_DRAW);
299 glBindBuffer(GL_ARRAY_BUFFER, hVBO);
300 glBufferSubData(GL_ARRAY_BUFFER, 0,
sizeof(vtxData), vtxData);
307 glBindTexture(GL_TEXTURE_2D, pBackSurface->texture->texName);
309 glBlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR);
310 float normalBlend = 1.0f / 4.0f,
311 brightBlend = 1.0f / 16.0f;
312 glBlendColor(0.0f,normalBlend,normalBlend,brightBlend);
315 const bool has_vao =
pGL->
GetVAO(vaoid, vao);
316 glBindVertexArray(vao);
321 glVertexAttribPointer(pShader->
GetAttribute(
C4FoWFSA_Position), 2, GL_FLOAT, GL_FALSE, 0,
reinterpret_cast<const uint8_t*
>(8 *
sizeof(
float)));
325 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
327 glBindVertexArray(0);
328 glBindBuffer(GL_ARRAY_BUFFER, 0);
334 glBindFramebuffer(GL_FRAMEBUFFER, prev_fb);
349 assert(outRect.
Hgt >= clipRect.
y + clipRect.
Hgt);
352 trans.
Scale(1.0f / clipRect.
Wdt, 1.0f / clipRect.
Hgt);
358 trans.
Scale(1.0f / pSurface->Wdt, 1.0f / pSurface->Hgt);
360 trans.
Translate(0.0f, 1.0f - (
float)(lightRect.
Hgt) / (
float)pSurface->Hgt);
363 trans.
Get2x3(lightTransform);
@ C4FoWFSU_ProjectionMatrix
bool RestorePrimaryClipper()
bool StorePrimaryClipper()
C4Shader * GetFramebufShader()
void Render(class C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr, const StdProjectionMatrix &projectionMatrix)
void Update(C4Rect r, C4Player *player)
GLuint getSurfaceName() const
int32_t getSurfaceHeight() const
const C4Rect & getRegion() const
C4FoWRegion(C4FoW *pFoW, C4Player *pPlayer)
void Update(C4Rect r, const FLOAT_RECT &vp)
int32_t getSurfaceWidth() const
void GetFragTransform(const C4Rect &clipRect, const C4Rect &outRect, float lightTransform[6]) const
bool Render(const C4TargetFacet *pOnScreen=nullptr)
GLint GetAttribute(int iAttribute) const
const StdProjectionMatrix & GetProjectionMatrix() const
void FreeVAOID(unsigned int vaoid)
bool GetVAO(unsigned int vaoid, GLuint &vao)
static StdProjectionMatrix Orthographic(float left, float right, float bottom, float top)