line rasterizer test
Revision | afe595564995bffbc0c9f44e1b7e3a4e30f70c38 (tree) |
---|---|
Zeit | 2011-02-14 00:37:03 |
Autor | beru <berupon@gmai...> |
Commiter | beru |
shift line rasterize algorithm
@@ -0,0 +1,129 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +#include <math.h> | |
4 | +#include <algorithm> | |
5 | +#include "buffer2d.h" | |
6 | +#include "arrayutil.h" | |
7 | + | |
8 | +#include "ILineDrawer.h" | |
9 | + | |
10 | +namespace gl | |
11 | +{ | |
12 | + | |
13 | +template <typename NumericT, size_t slopeCorrectionTableSize = 256> | |
14 | +class LineDrawer8_Shift : public IBufferLineDrawer<NumericT, uint8_t> | |
15 | +{ | |
16 | +private: | |
17 | + Buffer2D<uint8_t>* pBuff_; | |
18 | + | |
19 | + const NumericT* slopeCorrectionTable_; | |
20 | + | |
21 | + inline | |
22 | + void blend( | |
23 | + uint8_t* p, | |
24 | + NumericT v | |
25 | + ) | |
26 | + { | |
27 | + uint8_t old = *p; | |
28 | + if (old != 0xff) { | |
29 | + NumericT nv = NumericT(old) + v; | |
30 | + *p = (nv >= NumericT(255.0)) ? 255 : halfAdjust(nv); | |
31 | + } | |
32 | + } | |
33 | + | |
34 | +public: | |
35 | + | |
36 | + LineDrawer8_Shift() | |
37 | + : | |
38 | + slopeCorrectionTable_(NULL), | |
39 | + pBuff_(NULL) | |
40 | + { | |
41 | + } | |
42 | + | |
43 | + void SetSlopeCorrectionTable(const NumericT* slopeCorrectionTable) { slopeCorrectionTable_ = slopeCorrectionTable; } | |
44 | + | |
45 | + void SetBuffer(Buffer2D<uint8_t>* pBuff) | |
46 | + { | |
47 | + pBuff_ = pBuff; | |
48 | + } | |
49 | + | |
50 | + void shift(const uint8_t* src, uint8_t* dst, size_t len, float offset) | |
51 | + { | |
52 | + assert(offset >= 0.0f); | |
53 | + float inversed = 1.0f - offset; | |
54 | + uint8_t part; | |
55 | + uint8_t remain = 0; | |
56 | + for (size_t i=0; i<len; ++i) { | |
57 | + part = src[i] * inversed; | |
58 | + dst[i] = part + remain; | |
59 | + remain = src[i] - part; | |
60 | + } | |
61 | + dst[len] = remain; | |
62 | + } | |
63 | + | |
64 | + void DrawLine(uint8_t intensity, NumericT x1, NumericT y1, NumericT x2, NumericT y2) | |
65 | + { | |
66 | + NumericT width = abs(x2 - x1); | |
67 | + NumericT height = abs(y2 - y1); | |
68 | + if (width + height == NumericT(0)) | |
69 | + return; | |
70 | + assert(2 <= slopeCorrectionTableSize); | |
71 | + const int lineOffset = pBuff_->GetLineOffset(); | |
72 | + | |
73 | + NumericT alpha = NumericT(intensity); | |
74 | + | |
75 | +// if (height < width) { | |
76 | + if (1) { | |
77 | + if (x2 < x1) { // left; | |
78 | + std::swap(x2, x1); | |
79 | + std::swap(y2, y1); | |
80 | + } | |
81 | + const NumericT dy = y2 - y1; | |
82 | + const NumericT gradient = dy / width; | |
83 | + float rotation = abs(width / dy); | |
84 | + | |
85 | + alpha *= slopeCorrectionTable_[ ToInt(mul<slopeCorrectionTableSize - 1>(abs(gradient))) ]; | |
86 | + | |
87 | + uint8_t pat1[512] = {0}; | |
88 | + uint8_t pat2[512+1]; | |
89 | + | |
90 | + float patLen = rotation * 1.28; | |
91 | + patLen = std::min(256.0f, patLen); | |
92 | + int iPatLen = ceil(patLen); | |
93 | + for (size_t i=0; i<iPatLen; ++i) { | |
94 | + float x = (i * 2) / patLen; | |
95 | + float v = exp(- x * x); | |
96 | + pat1[iPatLen-i] = pat1[iPatLen+i] = (v * 255 + 0.5); | |
97 | + } | |
98 | + | |
99 | + uint8_t* ptr = (uint8_t*)pBuff_->GetPixelPtr(ToInt(x1)-2, ToInt(y1)); | |
100 | + | |
101 | + const float offset = rotation; | |
102 | + float curOffset = 0; | |
103 | + float ylen = height; | |
104 | + for (size_t y=0; y<ylen; ++y) { | |
105 | + int io = (int) curOffset; | |
106 | + bool isMinus = curOffset < 0.0f; | |
107 | + float fracOffset = curOffset - io; | |
108 | + if (isMinus) { | |
109 | + fracOffset += 1.0f; | |
110 | + --io; | |
111 | + } | |
112 | + const size_t w = iPatLen * 2; | |
113 | + shift(pat1, pat2, w, fracOffset); | |
114 | + for (size_t x=0; x<w; ++x) { | |
115 | + ptr[io+x] = pat2[x]; | |
116 | + } | |
117 | + OffsetPtr(ptr, lineOffset); | |
118 | + curOffset += offset; | |
119 | + } | |
120 | + | |
121 | + | |
122 | + | |
123 | + } | |
124 | + } | |
125 | + | |
126 | +}; | |
127 | + | |
128 | +} // namespace gl | |
129 | + |
@@ -177,10 +177,6 @@ | ||
177 | 177 | > |
178 | 178 | </File> |
179 | 179 | <File |
180 | - RelativePath=".\shift.cpp" | |
181 | - > | |
182 | - </File> | |
183 | - <File | |
184 | 180 | RelativePath=".\stdafx.cpp" |
185 | 181 | > |
186 | 182 | <FileConfiguration |
@@ -329,6 +325,10 @@ | ||
329 | 325 | > |
330 | 326 | </File> |
331 | 327 | <File |
328 | + RelativePath=".\gl\lineDrawer8_Shift.h" | |
329 | + > | |
330 | + </File> | |
331 | + <File | |
332 | 332 | RelativePath=".\gl\lineDrawer8_Wu.h" |
333 | 333 | > |
334 | 334 | </File> |
@@ -7,6 +7,7 @@ | ||
7 | 7 | #include "gl/lineDrawer8_DDA.h" |
8 | 8 | #include "gl/lineDrawer8_Wu.h" |
9 | 9 | #include "gl/lineDrawer8_Nelson.h" |
10 | +#include "gl/lineDrawer8_Shift.h" | |
10 | 11 | |
11 | 12 | #include "shift.h" |
12 | 13 |
@@ -22,8 +23,11 @@ gl::LineDrawer8_Bresenham<float> lineDrawer_Bresenham; | ||
22 | 23 | gl::LineDrawer8_DDA<float> lineDrawer_DDA; |
23 | 24 | gl::LineDrawer8_Wu<float> lineDrawer_Wu; |
24 | 25 | gl::LineDrawer8_Nelson<float> lineDrawer_Nelson; |
25 | -float shiftX = 128; | |
26 | -float shiftY = 1024; | |
26 | + | |
27 | +gl::LineDrawer8_Shift<float> lineDrawer_Shift; | |
28 | + | |
29 | +float shiftX = 512; | |
30 | +float shiftY = 512; | |
27 | 31 | |
28 | 32 | void renderLines(gl::IBufferLineDrawer<float, uint8_t>& ld, float x) |
29 | 33 | { |
@@ -31,11 +35,11 @@ void renderLines(gl::IBufferLineDrawer<float, uint8_t>& ld, float x) | ||
31 | 35 | float offset = 0; |
32 | 36 | for (int s=0; s<16; ++s) { |
33 | 37 | int slide = s * 120; |
34 | - int ei = 25; | |
38 | + int ei = 21- s / 4; | |
35 | 39 | for (int i=0; i<ei; ++i) { |
36 | 40 | int y = 30 + 40 * i; |
37 | 41 | ld.DrawLine( |
38 | - 220, | |
42 | + 0xff, | |
39 | 43 | x+slide, y, |
40 | 44 | x+100+slide, y+offset |
41 | 45 | ); |
@@ -48,7 +52,7 @@ void renderLines(gl::IBufferLineDrawer<float, uint8_t>& ld, float x) | ||
48 | 52 | rec.bottom = rec.top + 20; |
49 | 53 | _stprintf(str, _T("%.1f"), offset); |
50 | 54 | ::DrawText(hMemDC, str, -1, &rec, DT_LEFT); |
51 | - offset += 0.1; | |
55 | + offset += 1.0; | |
52 | 56 | } |
53 | 57 | } |
54 | 58 | } |
@@ -72,6 +76,9 @@ void render(UINT vk, uint16_t repeatCount) | ||
72 | 76 | case 'N': |
73 | 77 | renderLines(lineDrawer_Nelson, 10); |
74 | 78 | break; |
79 | + case 'S': | |
80 | + renderLines(lineDrawer_Shift, 10); | |
81 | + break; | |
75 | 82 | case '1': |
76 | 83 | case VK_LEFT: |
77 | 84 | case VK_RIGHT: |
@@ -100,7 +107,8 @@ void render(UINT vk, uint16_t repeatCount) | ||
100 | 107 | shiftY += offset; |
101 | 108 | break; |
102 | 109 | } |
103 | - shiftTest(buff, shiftX, shiftY); | |
110 | + lineDrawer_Shift.SetBuffer(&buff); | |
111 | + lineDrawer_Shift.DrawLine(0xff, 400, 400, shiftX, shiftY); | |
104 | 112 | } |
105 | 113 | break; |
106 | 114 | } |
@@ -113,6 +121,7 @@ void OnKeyDown(WPARAM vk, LPARAM lparam) | ||
113 | 121 | case 'D': |
114 | 122 | case 'W': |
115 | 123 | case 'N': |
124 | + case 'S': | |
116 | 125 | case '1': |
117 | 126 | case VK_LEFT: |
118 | 127 | case VK_RIGHT: |
@@ -211,6 +220,8 @@ void SetupDIB(HWND hWnd) | ||
211 | 220 | lineDrawer_Nelson.SetSlopeCorrectionTable(slopeCorrectionTable); |
212 | 221 | lineDrawer_Nelson.SetFilterTable(filterTable); |
213 | 222 | |
223 | + lineDrawer_Shift.SetSlopeCorrectionTable(slopeCorrectionTable); | |
224 | + | |
214 | 225 | #else |
215 | 226 | hBMP = CreateDIB32(width, -height, bmi, pBits); |
216 | 227 | #endif |
@@ -1,56 +0,0 @@ | ||
1 | -#include "stdafx.h" | |
2 | - | |
3 | -#include "shift.h" | |
4 | - | |
5 | -#include "gl/fixed.h" | |
6 | - | |
7 | -void shift(const uint8_t* src, uint8_t* dst, size_t len, float offset) | |
8 | -{ | |
9 | - assert(offset >= 0.0f); | |
10 | - float inversed = 1.0f - offset; | |
11 | - uint8_t part; | |
12 | - uint8_t remain = 0; | |
13 | - for (size_t i=0; i<len; ++i) { | |
14 | - part = src[i] * inversed; | |
15 | - dst[i] = part + remain; | |
16 | - remain = src[i] - part; | |
17 | - } | |
18 | - dst[len] = remain; | |
19 | -} | |
20 | - | |
21 | -void shiftTest(gl::Buffer2D<uint8_t>& buff, float shiftX, float shiftY) | |
22 | -{ | |
23 | - uint8_t pat1[256] = {0}; | |
24 | - uint8_t pat2[256+1]; | |
25 | - | |
26 | - float patLen = abs(shiftX / shiftY) * 2; | |
27 | - patLen = std::max(2.0f, patLen); | |
28 | - patLen = patLen * 2 + 1; | |
29 | - patLen = std::min(256.0f, patLen); | |
30 | - int iPatLen = patLen + 0.5; | |
31 | - for (size_t i=0; i<iPatLen/2; ++i) { | |
32 | - float x = i / (float)(iPatLen/4); | |
33 | - float v = exp(- x * x); | |
34 | - pat1[iPatLen/2-i] = pat1[iPatLen/2+i] = v * 255; | |
35 | - } | |
36 | - | |
37 | - const float offset = shiftX / shiftY; | |
38 | - float curOffset = 0; | |
39 | - float ylen = shiftY; | |
40 | - for (size_t y=0; y<ylen; ++y) { | |
41 | - int io = (int) curOffset; | |
42 | - bool isMinus = curOffset < 0.0f; | |
43 | - float fracOffset = curOffset - io; | |
44 | - if (isMinus) { | |
45 | - fracOffset += 1.0f; | |
46 | - --io; | |
47 | - } | |
48 | - shift(pat1, pat2, patLen, fracOffset); | |
49 | - for (size_t x=0; x<patLen; ++x) { | |
50 | - buff.SetPixel(600+x+io, 10+y, pat2[x]); | |
51 | - } | |
52 | - curOffset += offset; | |
53 | - } | |
54 | - | |
55 | -} | |
56 | - |