1 /* DreamChess
2 **
3 ** DreamChess is the legal property of its developers, whose names are too
4 ** numerous to list here. Please refer to the AUTHORS.txt file distributed
5 ** with this source distribution.
6 **
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, either version 3 of the License, or
10 ** (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "ui_sdlgl.h"
22
23 /* This function loads the image upside-down. Meaning that texture
24 * coordinate (0,0) corresponds to the top-left corner of the image.
25 */
SDL_GL_LoadTexture(SDL_Surface * surface,SDL_Rect * area,int alpha,int clamp)26 texture_t SDL_GL_LoadTexture(SDL_Surface *surface, SDL_Rect *area, int alpha, int clamp) {
27 texture_t texture;
28 int w, h;
29 SDL_Surface *image;
30 SDL_Rect dest;
31 Uint32 saved_flags;
32 Uint8 saved_alpha;
33
34 /* Use the surface width and height expanded to powers of 2 */
35 w = power_of_two(area->w);
36 h = power_of_two(area->h);
37
38 image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
39 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
40 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
41 #else
42 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
43 #endif
44 );
45 if (image == NULL) {
46 exit(0);
47 }
48
49 /* Copy the surface into the GL texture image */
50 dest.x = 0;
51 dest.y = 0;
52 dest.w = area->w;
53 dest.h = area->h;
54 SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
55 SDL_BlitSurface(surface, area, image, &dest);
56
57 /* Create an OpenGL texture for the image */
58 glGenTextures(1, &texture.id);
59 glBindTexture(GL_TEXTURE_2D, texture.id);
60 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
61 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
62
63 if (clamp) {
64 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
65 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
66 }
67
68 glTexImage2D(GL_TEXTURE_2D, 0, (alpha ? 4 : 3), w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
69 SDL_FreeSurface(image); /* No longer needed */
70
71 glEnable(GL_TEXTURE_2D);
72 glGenerateMipmap(GL_TEXTURE_2D);
73
74 texture.u1 = 0;
75 texture.v1 = 0;
76 texture.u2 = area->w / (float)w;
77 texture.v2 = area->h / (float)h;
78 texture.width = area->w;
79 texture.height = area->h;
80
81 return texture;
82 }
83
84 /** @brief Renders a textured quad.
85 *
86 * @param texture The texture to use.
87 * @param xpos The leftmost x-coordinate.
88 * @param ypos The lowermost y-coordinate.
89 * @param width The width in pixels.
90 * @param height The height in pixels.
91 * @param zpos The z-coordinate.
92 * @param col The colour to render with.
93 */
draw_texture(texture_t * texture,float xpos,float ypos,float width,float height,float zpos,gg_colour_t * col)94 void draw_texture(texture_t *texture, float xpos, float ypos, float width, float height, float zpos, gg_colour_t *col) {
95 glEnable(GL_TEXTURE_2D);
96
97 glColor4f(col->r, col->g, col->b, col->a);
98 glBindTexture(GL_TEXTURE_2D, texture->id);
99
100 glBegin(GL_QUADS);
101 glTexCoord2f(texture->u1, texture->v1);
102 glVertex3f(xpos, ypos + height, zpos);
103 glTexCoord2f(texture->u2, texture->v1);
104 glVertex3f(xpos + width, ypos + height, zpos);
105 glTexCoord2f(texture->u2, texture->v2);
106 glVertex3f(xpos + width, ypos, zpos);
107 glTexCoord2f(texture->u1, texture->v2);
108 glVertex3f(xpos, ypos, zpos);
109 glEnd();
110
111 glDisable(GL_TEXTURE_2D);
112 }
113
draw_texture_uv(texture_t * texture,float xpos,float ypos,float width,float height,float zpos,gg_colour_t * col,float u1,float v1,float u2,float v2,GLenum mode_h,GLenum mode_v)114 void draw_texture_uv(texture_t *texture, float xpos, float ypos, float width, float height, float zpos,
115 gg_colour_t *col, float u1, float v1, float u2, float v2, GLenum mode_h, GLenum mode_v) {
116 glEnable(GL_TEXTURE_2D);
117
118 glColor4f(col->r, col->g, col->b, col->a);
119 glBindTexture(GL_TEXTURE_2D, texture->id);
120
121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mode_h);
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mode_v);
123
124 glBegin(GL_QUADS);
125 glTexCoord2f(u1, v1);
126 glVertex3f(xpos, ypos + height, zpos);
127 glTexCoord2f(u2, v1);
128 glVertex3f(xpos + width, ypos + height, zpos);
129 glTexCoord2f(u2, v2);
130 glVertex3f(xpos + width, ypos, zpos);
131 glTexCoord2f(u1, v2);
132 glVertex3f(xpos, ypos, zpos);
133 glEnd();
134
135 glDisable(GL_TEXTURE_2D);
136 }
137
draw_texture_fullscreen(texture_t * texture,float zpos)138 void draw_texture_fullscreen(texture_t *texture, float zpos) {
139 glEnable(GL_TEXTURE_2D);
140
141 glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
142 glBindTexture(GL_TEXTURE_2D, texture->id);
143
144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
146
147 float hor_visible = texture->height * get_screen_width() / (float)get_screen_height() / texture->width;
148
149 // If the image isn't wide enough, we stretch it
150 if (hor_visible >= 1.0f)
151 hor_visible = 1.0f;
152
153 float u_skip = (1.0f - hor_visible) / 2 * (texture->u2 - texture->u1);
154
155 glBegin(GL_QUADS);
156 glTexCoord2f(texture->u1 + u_skip, texture->v1);
157 glVertex3f(0, get_gl_height(), zpos);
158 glTexCoord2f(texture->u2 - u_skip, texture->v1);
159 glVertex3f(get_gl_width(), get_gl_height(), zpos);
160 glTexCoord2f(texture->u2 - u_skip, texture->v2);
161 glVertex3f(get_gl_width(), 0, zpos);
162 glTexCoord2f(texture->u1 + u_skip, texture->v2);
163 glVertex3f(0, 0, zpos);
164 glEnd();
165
166 glDisable(GL_TEXTURE_2D);
167 }
168
169 /** @brief Loads a PNG file and turns it into a texture.
170 *
171 * @param texture Texture to write to.
172 * @param filename The PNG file to load.
173 * @param alpha 1 = Create texture with alpha channel (taken from image),
174 * 0 = Create texture without alpha channel.
175 */
load_texture_png(texture_t * texture,char * filename,int alpha,int clamp)176 void load_texture_png(texture_t *texture, char *filename, int alpha, int clamp) {
177 /* Create storage space for the texture */
178 SDL_Surface *texture_image;
179
180 DBG_LOG("Loading texture: %s", filename);
181
182 /* Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit */
183 if ((texture_image = IMG_Load(filename))) {
184 SDL_Rect area;
185 area.x = 0;
186 area.y = 0;
187 area.w = texture_image->w;
188 area.h = texture_image->h;
189 *texture = SDL_GL_LoadTexture(texture_image, &area, alpha, clamp);
190 } else {
191 DBG_ERROR("Could not load texture: %s", filename);
192 exit(1);
193 }
194
195 /* Free up any memory we may have used */
196 if (texture_image)
197 SDL_FreeSurface(texture_image);
198 }
199