46 Create(iWdt, iHgt, iFlags);
99 if (!psfcFrom)
return;
102 dbg_idx = psfcFrom->dbg_idx;
165 if (!iWdt || !iHgt)
return false;
168 if (!
pDraw)
return false;
177 texture = std::make_unique<C4TexRef>(iWdt, iHgt, iFlags);
194 {
Clear();
return false; }
208 WORD Rdelta,Gdelta,Bdelta;
214 cMax = std::max<int>(std::max<int>(R,G),B);
215 cMin = std::min<int>(std::min<int>(R,G),B);
228 S = ( ((cMax-cMin)*
HLSMAX) + ((cMax+cMin)/2) ) / (cMax+cMin);
233 Rdelta = ( ((cMax-R)*(
HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);
234 Gdelta = ( ((cMax-G)*(
HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);
235 Bdelta = ( ((cMax-B)*(
HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);
239 H = (
HLSMAX/3) + Rdelta - Bdelta;
241 H = ((2*
HLSMAX)/3) + Gdelta - Rdelta;
248 if (!(
Inside(H, 145, 175) && (S > 100)))
return false;
251 dwClr =
RGBA(
b,
b,
b, 0) | (dwClr & 0xff000000);
258 if (!pBySurface)
return false;
259 if (!pBySurface->
texture)
return false;
261 if (!
Create(pBySurface->
Wdt, pBySurface->
Hgt))
return false;
270 for (
int iY=0; iY<
Hgt; ++iY)
271 for (
int iX=0; iX<
Wdt; ++iX)
292 if (!pOfSurface)
return false;
306 this->
Wdt = wdt; this->
Hgt = hgt;
328 if (!hGroup.
Read(&BitmapInfo,
sizeof(
C4BMPInfo)))
return false;
333 std::min(
sizeof(BitmapInfo)-
sizeof(
C4BMPInfo),
sizeof(BitmapInfo)-
sizeof(
C4BMPInfo)+BitmapInfo.FileBitsOffset())))
335 if (!hGroup.
Advance(BitmapInfo.FileBitsOffset()))
return false;
341 if (!hGroup.
Advance(((
C4BMPInfo) BitmapInfo).FileBitsOffset()))
return false;
352 for (lcnt=
Hgt-1; lcnt>=0; lcnt--)
354 if (!hGroup.
Read(pBuf, iBufSize))
355 {
Clear();
delete [] pBuf;
return false; }
381 bool C4Surface::SavePNG(
const char *szFilename,
bool fSaveAlpha,
bool fSaveOverlayOnly,
bool use_background_thread)
384 if (!
Lock())
return false;
387 std::unique_ptr<CPNGFile> png(
new CPNGFile());
388 if (!png->Create(
Wdt,
Hgt, fSaveAlpha)) {
Unlock();
return false; }
398 for (
int y = 0; y <
Hgt; ++y)
399 glReadPixels(0,
Hgt - y - 1,
Wdt, 1, fSaveAlpha ? GL_BGRA : GL_BGR, GL_UNSIGNED_BYTE, png->GetRow(y));
405 for (
int y=0; y<
Hgt; ++y)
406 for (
int x=0; x<
Wdt; ++x)
409 png->SetPix(x, y, dwClr);
414 if (fSaveOverlayOnly)
pMainSfc=pMainSfcBackup;
420 if (use_background_thread)
426 if (!png->Save(szFilename))
return false;
441 return (
double) (
Abs(bpRGB1[0]-bpRGB2[0]) +
Abs(bpRGB1[1]-bpRGB2[1]) +
Abs(bpRGB1[2]-bpRGB2[2])) / 6.0;
469 if (!
Locked)
return false;
493 BYTE *pBuf =
nullptr;
int iPitch = 0;
495 int iX2=iX;
int iY2=iY;
503 glPixelStorei(GL_PACK_ALIGNMENT, 1);
533 if (fApplyModulation)
548 BltAlpha(dwMainPix, dwPix); dwPix=dwMainPix;
573 return (dwPix>>24) < 128;
584 if (dwClr>>24 == 0x00) dwClr=0x00000000;
586 texture->SetPix(iX, iY, dwClr);
621 if (iX<0) { iWdt+=iX; iX=0; }
622 if (iY<0) { iHgt+=iY; iY=0; }
624 iOver=
Wdt-(iX+iWdt);
if (iOver<0) iWdt+=iOver;
625 iOver=
Hgt-(iY+iHgt);
if (iOver<0) iHgt+=iOver;
626 C4Rect rtClear{ iX, iY, iWdt, iHgt };
681 void C4TexRef::CreateTexture()
690 glBindTexture(GL_TEXTURE_2D,
texName);
691 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, fTileable ? GL_REPEAT : GL_CLAMP_TO_EDGE);
692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, fTileable ? GL_REPEAT : GL_CLAMP_TO_EDGE);
693 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
694 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, fMipMap ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
695 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
iSizeX,
iSizeY, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
nullptr);
696 if (fMipMap) glGenerateMipmap(GL_TEXTURE_2D);
742 glBindTexture(GL_TEXTURE_2D,
texName);
743 glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
texLock.
pBits.get());
768 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
771 glBindTexture(GL_TEXTURE_2D,
texName);
772 glTexSubImage2D(GL_TEXTURE_2D, 0,
774 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
texLock.
pBits.get());
777 if (fMipMap) glGenerateMipmap(GL_TEXTURE_2D);
787 for (y = rtClear.
y; y < rtClear.
y + rtClear.
Hgt; ++y)
789 for (
int x = rtClear.
x; x < rtClear.
x + rtClear.
Wdt; ++x)
799 if (!
Lock())
return false;
804 for (
int x = 0; x <
iSizeX; ++x)
843 for (std::list<C4TexRef *>::iterator i=
Textures.begin(); j--; ++i)
855 glDeleteTextures(1, &pRef->
texName);
867 for (std::list<C4TexRef *>::iterator i=
Textures.begin(); j--; ++i)
873 pRef->CreateTexture();
bool ClrByOwner(DWORD &dwClr)
double ColorDistance(BYTE *bpRGB1, BYTE *bpRGB2)
std::unique_ptr< unsigned char[]> pBits
#define C4GFXBLIT_CLRSFC_OWNCLR
#define C4GFXBLIT_ADDITIVE
#define C4GFXBLIT_CLRSFC_MOD2
int DWordAligned(int val)
T Clamp(T bval, T lbound, T rbound)
bool Inside(T ival, U lbound, V rbound)
uint32_t RGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
void ModulateClrMOD2(DWORD &dwDst, DWORD dwMod)
void ModulateClr(DWORD &dwDst, DWORD dwMod)
void BltAlpha(DWORD &dwDst, DWORD dwSrc)
#define GetGreenValue(rgb)
#define GetBlueValue(rgb)
void BltAlphaAdd(DWORD &dwDst, DWORD dwSrc)
static constexpr int COLOR_DEPTH_BYTES
bool BlitSurface(C4Surface *sfcSurface, C4Surface *sfcTarget, int tx, int ty, bool fBlitBase)
virtual bool DeviceReady()=0
bool CreateColorByOwner(C4Surface *pBySurface)
bool Copy(C4Surface &fromSfc)
bool SetPixDw(int iX, int iY, DWORD dwCol)
bool UpdateSize(int wdt, int hgt)
DWORD GetPixDw(int iX, int iY, bool fApplyModulation)
std::unique_ptr< C4TexRef > texture
bool GetSurfaceSize(int &irX, int &irY)
bool ReadBMP(CStdStream &hGroup, int iFlags)
BYTE * PrimarySurfaceLockBits
int PrimarySurfaceLockPitch
bool IsPixTransparent(int iX, int iY)
bool Create(int iWdt, int iHgt, int iFlags=0)
bool SetAsClrByOwnerOf(C4Surface *pOfSurface)
void MoveFrom(C4Surface *psfcFrom)
bool BltPix(int iX, int iY, C4Surface *sfcSource, int iSrcX, int iSrcY, bool fTransparency)
bool PageFlip(C4Rect *pSrcRt=nullptr, C4Rect *pDstRt=nullptr)
void ClearBoxDw(int iX, int iY, int iWdt, int iHgt)
void Clip(int iX, int iY, int iX2, int iY2)
bool SavePNG(C4Group &hGroup, const char *szFilename, bool fSaveAlpha=true, bool fSaveOverlayOnly=false)
void RegTex(C4TexRef *pTex)
std::list< C4TexRef * > Textures
void UnregTex(C4TexRef *pTex)
bool LockForUpdate(C4Rect &rtUpdate)
C4TexRef(int iSizeX, int iSizeY, int iFlags)
void SetPix(int iX, int iY, DWORD v)
bool ClearRect(C4Rect &rtClear)
static void ScheduleSaving(CPNGFile *png, const char *filename)
virtual bool Select(bool verbose=false)
CStdGLCtx * CreateContext(C4Window *pWindow, C4AbstractApp *pApp) override
virtual bool Read(void *pBuffer, size_t iSize)=0
virtual bool Advance(int iOffset)=0