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