ecere/gfx/newFonts: Bug fix: Vertex/texcoord GL type should be GL_SHORT, not GL_UNSIG...
[sdk] / ecere / src / gfx / newFonts / fontRenderer.ec
1 /* *****************************************************************************
2  * Original Version Copyright (c) 2007-2014 Alexis Naveros.
3  *
4  * Ecere Corporation has unlimited/unrestricted rights.
5  * *****************************************************************************/
6 import "Color"
7
8 #include <math.h>
9
10 #if defined(_GLES)
11    #define ES1_1
12 #else
13    #define SHADERS
14 #endif
15
16 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
17 #  if defined(SHADERS)
18 //#     include "gl_core_3_3.h"
19 #     include "gl_compat_4_4.h"     // FIXME: no glPushAttrib() in core profile
20 #  else
21 #     include "gl_compat_4_4.h"
22 #  endif
23 #endif
24
25 #include "cc.h"
26 #include "mm.h"
27
28 import "fontManager"
29 import "textureManager"
30 import "drawManager"
31
32 public class FontRenderer : FontManagerRenderer
33 {
34    DrawManager dm;
35    Texture texture;
36    int textureWidth, textureHeight;
37    int channelcount;
38
39    int imagecount;
40    int imageAlloc;
41    DMImage *imageList;
42
43    ColorAlpha stateColor;
44    ColorAlpha stateCursorColor;
45    uint32 stateLayer;
46
47    imageAlloc = 512;
48    imageList = new DMImage[imageAlloc];
49
50    stateColor = white;
51    stateCursorColor = white;
52    stateLayer = DM_LAYER_ABOVE;
53
54 public:
55
56    property DrawManager drawManager { set { dm = value; } }
57
58    bool init(int channelCount)
59    {
60       this.channelcount = channelCount;
61       return true;
62    }
63
64    ~FontRenderer()
65    {
66       delete texture;
67       delete imageList;
68    }
69
70    bool createTexture( int width, int height )
71    {
72       IMGImage image
73       {
74          format = { width = width, height = height, type = grayScale, bytesPerPixel = channelcount, bytesPerLine = width };
75       };
76
77       delete texture;
78
79       texture = { 0 << DM_TEXTURE_ORDER_SHIFT };
80       texture.build(image, 0, 0.0, 0 );
81
82       textureWidth = width;
83       textureHeight = height;
84       return true;
85    }
86
87    int resizeTexture( int width, int height )
88    {
89      int retval;
90
91      // Reuse create to resize too.
92      delete imageList;
93      imagecount = 0;
94      imageAlloc = 512;
95      imageList = new DMImage[imageAlloc];
96
97      retval = createTexture( width, height );
98      return retval;
99    }
100
101    void updateTexture( int *rect, const byte* data )
102    {
103      if(texture)
104      {
105         int glformat = GL_RED;
106         int w = rect[2] - rect[0];
107         int h = rect[3] - rect[1];
108
109         if( channelcount == 1 )
110           glformat = GL_RED;
111         else if( channelcount == 2 )
112           glformat = GL_RG;
113         else if( channelcount == 3 )
114           glformat = GL_RGB;
115         else if( channelcount == 4 )
116           glformat = GL_RGBA;
117
118         // FIXME: no glPushAttrib() in core profile
119 //#ifndef SHADERS
120         glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
121         glPushAttrib( GL_TEXTURE_BIT );
122 //#endif
123         glBindTexture( GL_TEXTURE_2D, texture.glTex );
124         glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
125         glPixelStorei( GL_UNPACK_ROW_LENGTH, textureWidth );
126         glPixelStorei( GL_UNPACK_SKIP_PIXELS, rect[0] );
127         glPixelStorei( GL_UNPACK_SKIP_ROWS, rect[1] );
128         glTexSubImage2D( GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, glformat, GL_UNSIGNED_BYTE, data );
129 //#ifndef SHADERS
130         glPopAttrib();
131         glPopClientAttrib();
132 //#endif
133
134       #if 0
135         IMGImage image;
136         image.format.width = textureWidth;
137         image.format.height = textureHeight;
138         image.format.type = channelcount == 4 ? IMG_FORMAT_TYPE_RGBA32 : IMG_FORMAT_TYPE_GRAYSCALE;
139         image.format.bytesPerPixel = channelcount;
140         image.format.bytesPerLine = image.format.width * image.format.bytesPerPixel;
141         image.data = data;
142         imgWritePngFile( "zzz2.png", &image, 1.0 );
143       #endif
144      }
145    }
146
147    void flush( )
148    {
149       dm.flushImages( );
150    }
151
152    int registerImage( int offsetx, int offsety, int width, int height )
153    {
154       int imageindex = imagecount;
155       DMImage *image;
156
157       if( imagecount >= imageAlloc )
158       {
159          imageAlloc <<= 1;
160          imageList = renew imageList DMImage[imageAlloc];
161       }
162       imagecount++;
163
164       image = &imageList[ imageindex ];
165    #if 1
166       image->defineImage( texture, offsetx, offsety, width, height, 1, DM_PROGRAM_ALPHABLEND_INTENSITY, stateLayer );
167    #elif 1
168       image->defineImage( texture, offsetx, offsety, width, height, 1, DM_PROGRAM_ALPHABLEND, stateLayer );
169    #else
170       image->defineImage( texture, offsetx, offsety, width, height, 1, DM_PROGRAM_NORMAL, stateLayer );
171    #endif
172
173       return imageindex;
174    }
175
176    void drawImage( int targetx, int targety, int imageindex )
177    {
178       DMImage *image = &imageList[ imageindex ];
179       dm.drawImage( image, targetx, targety, image->sizex, image->sizey, stateColor );
180    }
181
182    void drawImageCursor( int targetx, int targety, int imageindex )
183    {
184       DMImage *image = &imageList[ imageindex ];
185       dm.drawImage( image, targetx, targety, image->sizex, image->sizey, stateCursorColor );
186    }
187
188    void drawImageAlt( byte *texdata, int targetx, int targety, int offsetx, int offsety, int width, int height )
189    {
190
191    }
192
193    void drawImageFloat( float targetx, float targety, float angsin, float angcos, int imageindex )
194    {
195       DMImage *image = &imageList[ imageindex ];
196
197       /* 0.2588190451, 0.965925826289 */
198
199       dm.drawImageFloat( image, targetx, targety, (float)image->sizex, (float)image->sizey, angsin, angcos, stateColor );
200    }
201
202    void resetImages( )
203    {
204       imagecount = 0;
205    }
206
207    void setColor( ColorAlpha color )
208    {
209       stateColor = { color.a, { color.color.b, color.color.g, color.color.r } };
210    }
211
212    void setCursorColor( ColorAlpha color )
213    {
214       stateCursorColor = { color.a, { color.color.b, color.color.g, color.color.r } };
215    }
216
217    void setLayer( uint32 layerIndex )
218    {
219       stateLayer = layerIndex;
220    }
221 }