Skip to content

Commit 8afee89

Browse files
committed
Add GetAverageColor to RageTexture
a neat little graphics utility function
1 parent 376d140 commit 8afee89

8 files changed

Lines changed: 105 additions & 1 deletion

File tree

src/RageUtil/Graphics/RageBitmapTexture.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,21 @@ RageBitmapTexture::Create()
358358
}
359359
}
360360

361+
// Precalculate the average color of the texture if needed at any point
362+
// we can't construct it from the texhandle (or can we?)
363+
RageColor rc(0, 0, 0, 1);
364+
if (pImg != nullptr) {
365+
uint8_t r = 0, g = 0, b = 0;
366+
RageSurfaceUtils::GetAverageRGB(pImg, r, g, b);
367+
float rF = r / 255.F;
368+
float gF = g / 255.F;
369+
float bF = b / 255.F;
370+
rc.r = rF;
371+
rc.g = gF;
372+
rc.b = bF;
373+
}
374+
averageColor = rc;
375+
361376
delete pImg;
362377

363378
// Check for hints that override the apparent "size".

src/RageUtil/Graphics/RageBitmapTexture.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* RageBitmapTexture - Loads a static texture. */
1+
/* RageBitmapTexture - Loads a static texture. */
22

33
#ifndef RAGEBITMAPTEXTURE_H
44
#define RAGEBITMAPTEXTURE_H
@@ -18,10 +18,16 @@ class RageBitmapTexture : public RageTexture
1818
return m_uTexHandle;
1919
}; // accessed by RageDisplay
2020

21+
auto GetAverageColor() const -> const RageColor override
22+
{
23+
return averageColor;
24+
}
25+
2126
private:
2227
void Create(); // called by constructor and Reload
2328
void Destroy();
2429
intptr_t m_uTexHandle; // treat as unsigned in OpenGL, ID3D8Texture* for D3D
30+
RageColor averageColor{ 0, 0, 0, 1 };
2531
};
2632

2733
#endif

src/RageUtil/Graphics/RageSurfaceUtils.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,50 @@ RageSurfaceUtils::ConvertSurface(RageSurface*& image,
200200
image = ret_image;
201201
}
202202

203+
void
204+
RageSurfaceUtils::GetAverageRGB(const RageSurface* img, uint8_t& r, uint8_t& g, uint8_t& b)
205+
{
206+
uint64_t rt = 0;
207+
uint64_t gt = 0;
208+
uint64_t bt = 0;
209+
210+
uint8_t tempR = 0;
211+
uint8_t tempG = 0;
212+
uint8_t tempB = 0;
213+
214+
uint64_t pixelCount = 0;
215+
216+
for (auto y = 0; y < img->h; ++y) {
217+
auto row = static_cast<uint8_t*>(img->pixels) + img->pitch * y;
218+
219+
for (auto x = 0; x < img->w; ++x) {
220+
const auto val = decodepixel(row, img->fmt.BytesPerPixel);
221+
if (img->fmt.BitsPerPixel == 8) {
222+
if (img->fmt.palette->colors[val].a) {
223+
// This color isn't fully transparent, so grab it.
224+
rt += img->fmt.palette->colors[val].r;
225+
gt += img->fmt.palette->colors[val].g;
226+
bt += img->fmt.palette->colors[val].b;
227+
}
228+
} else {
229+
if (val & img->fmt.Amask) {
230+
// This color isn't fully transparent, so grab it.
231+
img->fmt.GetRGB(val, &tempR, &tempG, &tempB);
232+
rt += tempR;
233+
gt += tempG;
234+
bt += tempB;
235+
}
236+
}
237+
238+
row += img->fmt.BytesPerPixel;
239+
pixelCount++;
240+
}
241+
}
242+
r = rt / pixelCount;
243+
g = gt / pixelCount;
244+
b = gt / pixelCount;
245+
}
246+
203247
// Local helper for FixHiddenAlpha.
204248
static void
205249
FindAlphaRGB(const RageSurface* img,

src/RageUtil/Graphics/RageSurfaceUtils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ ConvertSurface(RageSurface*& image,
5959
uint32_t B,
6060
uint32_t A);
6161

62+
void
63+
GetAverageRGB(const RageSurface* img,
64+
uint8_t& r,
65+
uint8_t& g,
66+
uint8_t& b);
67+
6268
void
6369
FixHiddenAlpha(RageSurface* img);
6470

src/RageUtil/Graphics/RageTexture.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ class LunaRageTexture : public Luna<RageTexture>
137137
p->Reload();
138138
COMMON_RETURN_SELF;
139139
}
140+
static int GetAverageColor(T* p, lua_State* L)
141+
{
142+
// will return the average color of the texture independent of diffuse
143+
p->GetAverageColor().PushTable(L);
144+
return 1;
145+
}
140146
DEFINE_METHOD(GetSourceWidth, GetSourceWidth());
141147
DEFINE_METHOD(GetSourceHeight, GetSourceHeight());
142148
DEFINE_METHOD(GetTextureWidth, GetTextureWidth());
@@ -160,6 +166,7 @@ class LunaRageTexture : public Luna<RageTexture>
160166
ADD_METHOD(GetImageWidth);
161167
ADD_METHOD(GetImageHeight);
162168
ADD_METHOD(GetPath);
169+
ADD_METHOD(GetAverageColor);
163170
}
164171
};
165172

src/RageUtil/Graphics/RageTexture.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ class RageTexture
123123
int source_width = 0,
124124
int source_height = 0);
125125

126+
virtual auto GetAverageColor() const -> const RageColor
127+
{
128+
return RageColor(0, 0, 0, 1);
129+
}
130+
126131
// Lua
127132
virtual void PushSelf(lua_State* L);
128133

src/arch/MovieTexture/MovieTexture_Generic.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Etterna/Globals/global.h"
22
#include "MovieTexture_Generic.h"
3+
#include "RageUtil/Graphics/RageSurfaceUtils.h"
34
#include "Etterna/Singletons/PrefsManager.h"
45
#include "RageUtil/Graphics/RageDisplay.h"
56
#include "Core/Services/Locator.hpp"
@@ -531,3 +532,20 @@ MovieTexture_Generic::GetTexHandle() const
531532

532533
return m_uTexHandle;
533534
}
535+
536+
auto
537+
MovieTexture_Generic::GetAverageColor() const -> const RageColor
538+
{
539+
RageColor rc(0,0,0,1);
540+
if (m_pSurface != nullptr) {
541+
uint8_t r = 0, g = 0, b = 0;
542+
RageSurfaceUtils::GetAverageRGB(m_pSurface, r, g, b);
543+
float rF = r / 255.F;
544+
float gF = g / 255.F;
545+
float bF = b / 255.F;
546+
rc.r = rF;
547+
rc.g = gF;
548+
rc.b = bF;
549+
}
550+
return rc;
551+
}

src/arch/MovieTexture/MovieTexture_Generic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ class MovieTexture_Generic : public RageMovieTexture
9999

100100
static EffectMode GetEffectMode(MovieDecoderPixelFormatYCbCr fmt);
101101

102+
auto GetAverageColor() const -> const RageColor override;
103+
104+
102105
private:
103106
MovieDecoder* m_pDecoder;
104107

0 commit comments

Comments
 (0)