]> icculus.org git repositories - dana/openbox.git/blob - render2/texture.c
only enable blend when needed
[dana/openbox.git] / render2 / texture.c
1 #include "instance.h"
2 #include "texture.h"
3 #include "surface.h"
4 #include "font.h"
5 #include "glft/glft.h"
6 #include <stdlib.h>
7 #include <assert.h>
8 #include <string.h>
9
10 void RrTextureFreeContents(struct RrTexture *tex)
11 {
12     switch (tex->type) {
13     case RR_TEXTURE_NONE:
14         break;
15     case RR_TEXTURE_TEXT:
16         free(tex->data.text.string);
17         break;
18     case RR_TEXTURE_RGBA:
19         glDeleteTextures(1, &tex->data.rgba.texid);
20         break;
21     }
22     tex->type = RR_TEXTURE_NONE;
23 }
24
25 void RrTextureSetRGBA(struct RrSurface *sur,
26                       int texnum,
27                       RrData32 *data,
28                       int x,
29                       int y,
30                       int w,
31                       int h)
32 {
33     int i;
34     unsigned char *padbuf;
35     unsigned int num;
36     struct RrTexture *tex = RrSurfaceTexture(sur, texnum);
37     if (!tex) return;
38     RrTextureFreeContents(tex);
39     tex->type = RR_TEXTURE_RGBA;
40     tex->data.rgba.x = x;
41     tex->data.rgba.y = y;
42     tex->data.rgba.w = w;
43     tex->data.rgba.h = h;
44     tex->data.rgba.padw = 1;
45     tex->data.rgba.padh = 1;
46
47     while (tex->data.rgba.padw < w)
48         tex->data.rgba.padw <<= 1;
49
50     while (tex->data.rgba.padh < h)
51         tex->data.rgba.padh <<= 1;
52
53     padbuf = malloc(sizeof(RrData32)
54            * tex->data.rgba.padh * tex->data.rgba.padw);
55     memset(padbuf, 0, sizeof(RrData32) * tex->data.rgba.padh * 
56            tex->data.rgba.padw);
57
58     for (i = 0; i < h; i++)
59         memcpy(padbuf + i*tex->data.rgba.padw,
60                data + i*w,
61                w);
62
63     glGenTextures(1, &num);
64     tex->data.rgba.texid = num;
65     glBindTexture(GL_TEXTURE_2D, num);
66     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
67     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
68     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
69     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
70     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
71     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
72     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
73                  tex->data.rgba.padw, tex->data.rgba.padh,
74                  0, GL_RGBA, GL_UNSIGNED_BYTE, padbuf);
75     free(padbuf);
76 }
77
78 void RrTextureSetText(struct RrSurface *sur,
79                       int texnum,
80                       struct RrFont *font,
81                       enum RrLayout layout,
82                       struct RrColor *color,
83                       const char *text)
84 {
85     struct RrTexture *tex = RrSurfaceTexture(sur, texnum);
86     int l;
87
88     if (!tex) return;
89     RrTextureFreeContents(tex);
90     tex->type = RR_TEXTURE_TEXT;
91     tex->data.text.font = font;
92     tex->data.text.layout = layout;
93     tex->data.text.color = *color;
94
95     l = strlen(text) + 1;
96     tex->data.text.string = malloc(l);
97     memcpy(tex->data.text.string, text, l);
98 }
99
100 void RrTextureSetNone(struct RrSurface *sur,
101                       int texnum)
102 {
103     struct RrTexture *tex = RrSurfaceTexture(sur, texnum);
104
105     if (!tex) return;
106     RrTextureFreeContents(tex);
107 }
108
109 void RrTexturePaint(struct RrSurface *sur, struct RrTexture *tex,
110                     int x, int y, int w, int h)
111 {
112     glEnable(GL_TEXTURE_2D);
113     
114     switch (tex->type) {
115     case RR_TEXTURE_NONE:
116         break;
117     case RR_TEXTURE_TEXT:
118 glEnable(GL_BLEND);
119         RrFontRenderString(sur, tex->data.text.font, &tex->data.text.color,
120                            tex->data.text.layout, tex->data.text.string,
121                            x, y, w, h);
122 glDisable(GL_BLEND);
123         break;
124     case RR_TEXTURE_RGBA:
125 glDisable(GL_BLEND);
126         glColor3f(1.0, 1.0, 1.0);
127         glBindTexture(GL_TEXTURE_2D, tex->data.rgba.texid);
128         glBegin(GL_TRIANGLES);
129         glTexCoord2f(0, 0);
130         glVertex2i(x, y);
131         glTexCoord2f(w/(float)tex->data.rgba.padw, 0);
132         glVertex2i(x+w, y); 
133         glTexCoord2f(w/(float)tex->data.rgba.padw,
134                      h/(float)tex->data.rgba.padh);
135         glVertex2i(x+w, y+h);
136
137         glVertex2i(x+w, y+h);
138         glTexCoord2f(0, h/(float)tex->data.rgba.padh);
139         glVertex2i(x, y+h);
140         glTexCoord2f(0, 0);
141         glVertex2i(x, y);
142         glEnd();
143
144         break;
145     }
146     glDisable(GL_TEXTURE_2D);
147 }