• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

milligram


Commit MetaInfo

修訂99edffefaceb71e9bdd6c1b36e81cf31bea1992e (tree)
時間2011-03-18 10:12:48
作者beru <berupon@gmai...>
Commiterberu

Log Message

Alpha Channelを含んだ32bit Bitmapの描画実装

Change Summary

差異

--- a/main_plus.cpp
+++ b/main_plus.cpp
@@ -30,11 +30,38 @@ MG::Container mg(elements, 128);
3030 MG::Button button1;
3131 MG::Button button2;
3232
33-std::vector<uint8_t> imageBuffer;
34-MG::Bitmap bmpContent;
33+MG::Bitmap bmp24Content;
34+std::vector<uint8_t> image24Buffer;
35+
36+MG::Bitmap bmp32Content;
37+std::vector<uint8_t> image32Buffer;
38+
3539 MG::Element pic1;
3640 MG::Element pic2;
3741
42+bool ReadImage(const char* filename, MG::Bitmap& bmp, std::vector<uint8_t>& buffer)
43+{
44+ FILE* file = fopen(filename, "r");
45+ if (!file) {
46+ return false;
47+ }
48+ File fileProxy(file);
49+ ImageInfo imageInfo;
50+ ReadImageInfo(fileProxy, imageInfo);
51+ assert(imageInfo.bitsPerSample == 8);
52+ assert(imageInfo.samplesPerPixel == 3 || imageInfo.samplesPerPixel == 4);
53+ buffer.resize(imageInfo.width * imageInfo.height * imageInfo.samplesPerPixel);
54+ int lineOffsetBytes = imageInfo.width * imageInfo.samplesPerPixel;
55+ ReadImageData(fileProxy, &buffer[0], lineOffsetBytes, 0);
56+ fclose(file);
57+ bmp.bitsPerPixel = imageInfo.bitsPerSample * imageInfo.samplesPerPixel;
58+ bmp.width = imageInfo.width;
59+ bmp.height = imageInfo.height;
60+ bmp.lineOffsetBytes = lineOffsetBytes;
61+ bmp.pBits = &buffer[0];
62+ return true;
63+}
64+
3865 } // anonymous namespace
3966
4067 void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
@@ -91,49 +118,38 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
91118 rect.h = 50;
92119 button2.rect = rect;
93120 mg.Add(button2);
94-
95- // read content
96- {
97- FILE* file = fopen("test.bmp", "r");
98- assert(file);
99- if (!file) {
100- return;
101- }
102- File fileProxy(file);
103- ImageInfo imageInfo;
104- ReadImageInfo(fileProxy, imageInfo);
105- assert(imageInfo.bitsPerSample == 8 && imageInfo.samplesPerPixel == 3);
106- imageBuffer.resize(imageInfo.width * imageInfo.height * imageInfo.samplesPerPixel);
107- int lineOffsetBytes = imageInfo.width * imageInfo.samplesPerPixel;
108- ReadImageData(fileProxy, &imageBuffer[0], lineOffsetBytes, 0);
109- fclose(file);
110- bmpContent.bitsPerPixel = imageInfo.bitsPerSample * imageInfo.samplesPerPixel;
111- bmpContent.width = imageInfo.width;
112- bmpContent.height = imageInfo.height;
113- bmpContent.lineOffsetBytes = lineOffsetBytes;
114- bmpContent.pBits = &imageBuffer[0];
121+
122+ if (!ReadImage("test24.bmp", bmp24Content, image24Buffer)) {
123+ return;
124+ }
125+ if (!ReadImage("test32.bmp", bmp32Content, image32Buffer)) {
126+ return;
115127 }
128+
116129 rect.x = 100;
117130 rect.y = 300;
118131 pic1.rect = rect;
119132 MG::Rectangle irec;
120- irec.x = irec.y = 0;
133+ irec.x = 510;
134+ irec.y = 340;
121135 irec.w = 400;
122136 irec.h = 400;
123137 pic1.bg.image.rect = irec;
124- pic1.bg.image.pBitmap = &bmpContent;
138+ pic1.bg.image.pBitmap = &bmp24Content;
125139 pic1.needsToDraw = true;
126140 mg.Add(pic1);
127141
128142 rect.x = 300;
129143 rect.y = 200;
130- rect.w = 300;
144+ rect.w = 336;
131145 rect.h = 300;
132146 pic2.rect = rect;
133- pic2.bg = pic1.bg;
134- irec.x = 510;
135- irec.y = 340;
147+ irec.x = 0;
148+ irec.y = 0;
149+ irec.w = 336;
150+ irec.h = 24;
136151 pic2.bg.image.rect = irec;
152+ pic2.bg.image.pBitmap = &bmp32Content;
137153 pic2.needsToDraw = true;
138154 mg.Add(pic2);
139155
--- a/mg/bitmap.cpp
+++ b/mg/bitmap.cpp
@@ -3,6 +3,27 @@
33 #include "bitmap.h"
44 #include "arrayutil.h"
55
6+namespace {
7+
8+// http://www.virtualdub.org/blog/pivot/entry.php?id=117
9+__forceinline
10+void blendColor_Phaeron(uint32_t fc, uint8_t fca, uint32_t& bc)
11+{
12+ uint32_t bc2 = bc;
13+ uint32_t srb = fc & 0xff00ff;
14+ uint32_t sg = fc & 0x00ff00;
15+ uint32_t drb = bc2 & 0xff00ff;
16+ uint32_t dg = bc2 & 0x00ff00;
17+ uint32_t alpha = fca;
18+ alpha += (alpha > 0);
19+ uint32_t orb = (drb + (((srb - drb) * alpha + 0x800080) >> 8)) & 0xff00ff;
20+ uint32_t og = (dg + (((sg - dg ) * alpha + 0x008000) >> 8)) & 0x00ff00;
21+
22+ bc = orb+og;
23+}
24+
25+} // namespace anonymous
26+
627 namespace MG {
728
829 Rectangle Bitmap::GetRect() const
@@ -63,6 +84,27 @@ void BitBlt_Src32_Dst24(
6384 Bitmap& dst, const Rectangle& dstRect
6485 )
6586 {
87+ const uint32_t* pSrc = (const uint32_t*) src.pBits;
88+ OffsetPtr(pSrc, src.lineOffsetBytes * srcRect.y);
89+ pSrc += srcRect.x;
90+
91+ uint8_t* pDst = (uint8_t*) dst.pBits;
92+ OffsetPtr(pDst, dst.lineOffsetBytes * dstRect.y);
93+ pDst += 3 * dstRect.x;
94+
95+ for (size_t y=0; y<dstRect.h; ++y) {
96+ for (size_t x=0; x<dstRect.w; ++x) {
97+ uint32_t fc = pSrc[x];
98+ uint8_t fca = fc >> 24;
99+ uint32_t bc = (pDst[x*3+0] << 0) | (pDst[x*3+1] << 8) | (pDst[x*3+2] << 16);
100+ blendColor_Phaeron(fc, fca, bc);
101+ pDst[x*3+0] = (bc >> 0) & 0xff;
102+ pDst[x*3+1] = (bc >> 8) & 0xff;
103+ pDst[x*3+2] = (bc >> 16) & 0xff;
104+ }
105+ OffsetPtr(pSrc, src.lineOffsetBytes);
106+ OffsetPtr(pDst, dst.lineOffsetBytes);
107+ }
66108 }
67109
68110 void BitBlt_Src32_Dst32(