egra: fixed rasterizer bug in agg mini (wrong comparisons for negative coords)
[iv.d.git] / egra / gfx / backgl.d
blob29297b1aeb78cd5375366a10fc5c39b15ff80c5f
1 /*
2 * Simple Framebuffer Gfx/GUI lib
4 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
5 * Understanding is not required. Only obedience.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 3 of the License ONLY.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 module iv.egra.gfx.backgl /*is aliced*/;
20 private:
22 import arsd.simpledisplay;
24 import iv.alice;
25 import iv.cmdcon;
26 //import iv.glbinds : glTexParameterfv; // rdmd hack
28 import iv.egra.gfx.config;
29 import iv.egra.gfx.base;
30 import iv.egra.gfx.lowlevel;
33 // ////////////////////////////////////////////////////////////////////////// //
34 enum GLTexType = GL_BGRA; // GL_RGBA;
37 // ////////////////////////////////////////////////////////////////////////// //
38 public __gshared uint vglTexId; // OpenGL texture id
39 public __gshared uint vArrowTextureId = 0;
42 // ////////////////////////////////////////////////////////////////////////// //
43 shared static this () {
44 import core.stdc.stdlib : malloc;
45 egfxCheckCPU();
46 // always allocate additional 16 bytes for SSE routines
47 vglTexBuf = cast(uint*)malloc((cast(uint)VBufWidth*cast(uint)VBufHeight)*vglTexBuf[0].sizeof+16u);
48 if (vglTexBuf is null) { import core.exception : onOutOfMemoryErrorNoGC; onOutOfMemoryErrorNoGC(); }
49 vglTexBuf[0..VBufWidth*VBufHeight+4] = 0;
53 // ////////////////////////////////////////////////////////////////////////// //
54 public void vglCreateArrowTexture () {
55 //import iv.glbinds;
57 enum wrapOpt = GL_REPEAT;
58 enum filterOpt = GL_NEAREST; //GL_LINEAR;
59 enum ttype = GL_UNSIGNED_BYTE;
61 if (vArrowTextureId) glDeleteTextures(1, &vArrowTextureId);
62 vArrowTextureId = 0;
63 glGenTextures(1, &vArrowTextureId);
64 if (vArrowTextureId == 0) assert(0, "can't create arrow texture");
66 //GLint gltextbinding;
67 //glGetIntegerv(GL_TEXTURE_BINDING_2D, &gltextbinding);
68 //scope(exit) glBindTexture(GL_TEXTURE_2D, gltextbinding);
70 glBindTexture(GL_TEXTURE_2D, vArrowTextureId);
71 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapOpt);
72 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapOpt);
73 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterOpt);
74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterOpt);
75 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
76 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
78 //GLfloat[4] bclr = 0.0;
79 //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr);
81 uint[16*8] pmap = 0x00_000000U;
82 // sprite,sprite,mask,mask
83 static immutable ushort[$] spx = [
84 0b11111111_10000000, 0b00000000_01111111,
85 0b01000000_10000000, 0b10000000_01111111,
86 0b00100000_10000000, 0b11000000_01111111,
87 0b00010000_01100000, 0b11100000_00011111,
88 0b00001001_10011000, 0b11110000_00000111,
89 0b00000110_01100110, 0b11111001_10000001,
90 0b00000000_00011001, 0b11111111_11100000,
91 0b00000000_00000110, 0b11111111_11111001,
94 foreach (immutable dy; 0..8) {
95 ushort spr = spx[dy*2+0];
96 ushort msk = spx[dy*2+1];
97 foreach (immutable dx; 0..16) {
98 if ((msk&0x8000) == 0) {
99 pmap[dy*16+dx] = (spr&0x8000 ? 0xff_ffffffU : 0xff_000000U);
101 msk <<= 1;
102 spr <<= 1;
105 //pmap = 0xff_ff0000U;
106 //pmap[0] = 0;
108 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 8, 0, GLTexType, GL_UNSIGNED_BYTE, pmap.ptr);
112 // ////////////////////////////////////////////////////////////////////////// //
113 public void vglBlitArrow (int px, int py) {
114 if (vArrowTextureId != 0) {
115 glMatrixMode(GL_PROJECTION); // for ortho camera
116 glLoadIdentity();
117 // left, right, bottom, top, near, far
118 //glViewport(0, 0, w*vbufEffScale, h*vbufEffScale);
119 //glOrtho(0, w, h, 0, -1, 1); // top-to-bottom
120 glViewport(0, 0, VBufWidth*vbufEffScale, VBufHeight*vbufEffScale);
121 glOrtho(0, VBufWidth, VBufHeight, 0, -1, 1); // top-to-bottom
122 glMatrixMode(GL_MODELVIEW);
123 glLoadIdentity();
125 glEnable(GL_TEXTURE_2D);
126 glDisable(GL_LIGHTING);
127 glDisable(GL_DITHER);
128 glDisable(GL_DEPTH_TEST);
130 glEnable(GL_BLEND);
131 //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
132 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
133 //glColor4f(1, 1, 1, 1);
134 glBindTexture(GL_TEXTURE_2D, vArrowTextureId);
135 //scope(exit) glBindTexture(GL_TEXTURE_2D, 0);
136 glBegin(GL_QUADS);
137 glTexCoord2f(0.0f, 0.0f); glVertex2i(px, py); // top-left
138 glTexCoord2f(1.0f, 0.0f); glVertex2i(px+16*2, py); // top-right
139 glTexCoord2f(1.0f, 1.0f); glVertex2i(px+16*2, py+8*2); // bottom-right
140 glTexCoord2f(0.0f, 1.0f); glVertex2i(px, py+8*2); // bottom-left
141 glEnd();
146 // ////////////////////////////////////////////////////////////////////////// //
147 // resize buffer, reinitialize OpenGL texture
148 public void vglResizeBuffer (int wdt, int hgt, int ascale=1) {
149 //import iv.glbinds;
151 if (wdt < 1) wdt = 1;
152 if (hgt < 1) hgt = 1;
154 if (wdt > 8192) wdt = 8192;
155 if (hgt > 8192) hgt = 8192;
157 bool sizeChanged = (wdt != VBufWidth || hgt != VBufHeight);
158 VBufWidth = wdt;
159 VBufHeight = hgt;
161 if (vglTexBuf is null || sizeChanged) {
162 import core.stdc.stdlib : realloc;
163 // always allocate additional 16 bytes for SSE routines
164 vglTexBuf = cast(uint*)realloc(vglTexBuf, (cast(uint)VBufWidth*cast(uint)VBufHeight)*vglTexBuf[0].sizeof+16u);
165 if (vglTexBuf is null) { import core.exception : onOutOfMemoryErrorNoGC; onOutOfMemoryErrorNoGC(); }
166 vglTexBuf[0..VBufWidth*VBufHeight+4] = 0;
169 if (vglTexId == 0 || sizeChanged) {
170 enum wrapOpt = GL_REPEAT;
171 enum filterOpt = GL_NEAREST; //GL_LINEAR;
172 enum ttype = GL_UNSIGNED_BYTE;
174 if (vglTexId) glDeleteTextures(1, &vglTexId);
175 vglTexId = 0;
176 glGenTextures(1, &vglTexId);
177 if (vglTexId == 0) assert(0, "can't create OpenGL texture");
179 //GLint gltextbinding;
180 //glGetIntegerv(GL_TEXTURE_BINDING_2D, &gltextbinding);
181 //scope(exit) glBindTexture(GL_TEXTURE_2D, gltextbinding);
183 glBindTexture(GL_TEXTURE_2D, vglTexId);
184 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapOpt);
185 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapOpt);
186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterOpt);
187 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterOpt);
188 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
189 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
191 //GLfloat[4] bclr = 0.0;
192 //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr);
194 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VBufWidth, VBufHeight, 0, GLTexType, GL_UNSIGNED_BYTE, vglTexBuf);
197 if (ascale < 1) ascale = 1;
198 if (ascale > 32) ascale = 32;
199 vbufEffScale = cast(ubyte)ascale;
203 // ////////////////////////////////////////////////////////////////////////// //
204 public void vglUpdateTexture () {
205 if (vglTexId != 0) {
206 glBindTexture(GL_TEXTURE_2D, vglTexId);
207 glTexSubImage2D(GL_TEXTURE_2D, 0, 0/*x*/, 0/*y*/, VBufWidth, VBufHeight, GLTexType, GL_UNSIGNED_BYTE, vglTexBuf);
208 //glBindTexture(GL_TEXTURE_2D, 0);
213 // ////////////////////////////////////////////////////////////////////////// //
214 public void vglBlitTexture () {
215 if (vglTexId != 0) {
216 glMatrixMode(GL_PROJECTION); // for ortho camera
217 glLoadIdentity();
218 // left, right, bottom, top, near, far
219 //glViewport(0, 0, w*vbufEffScale, h*vbufEffScale);
220 //glOrtho(0, w, h, 0, -1, 1); // top-to-bottom
221 glViewport(0, 0, VBufWidth*vbufEffScale, VBufHeight*vbufEffScale);
222 glOrtho(0, VBufWidth, VBufHeight, 0, -1, 1); // top-to-bottom
223 glMatrixMode(GL_MODELVIEW);
224 glLoadIdentity();
226 glEnable(GL_TEXTURE_2D);
227 glDisable(GL_LIGHTING);
228 glDisable(GL_DITHER);
229 //glDisable(GL_BLEND);
230 glDisable(GL_DEPTH_TEST);
231 //glEnable(GL_BLEND);
232 //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
233 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
234 glDisable(GL_BLEND);
235 //glDisable(GL_STENCIL_TEST);
237 if (vglTexId) {
238 immutable w = VBufWidth;
239 immutable h = VBufHeight;
241 glColor4f(1, 1, 1, 1);
242 glBindTexture(GL_TEXTURE_2D, vglTexId);
243 //scope(exit) glBindTexture(GL_TEXTURE_2D, 0);
244 glBegin(GL_QUADS);
245 glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0); // top-left
246 glTexCoord2f(1.0f, 0.0f); glVertex2i(w, 0); // top-right
247 glTexCoord2f(1.0f, 1.0f); glVertex2i(w, h); // bottom-right
248 glTexCoord2f(0.0f, 1.0f); glVertex2i(0, h); // bottom-left
249 glEnd();