author | nemo |
Sat, 19 Nov 2011 15:34:38 -0500 | |
branch | 0.9.17 |
changeset 6402 | 4670f003f91b |
parent 6394 | f0a9042e7387 |
child 6467 | 090269e528df |
permissions | -rw-r--r-- |
4976 | 1 |
(* |
2 |
* Hedgewars, a free turn based strategy game |
|
3 |
* Copyright (c) 2004-2011 Andrey Korotaev <unC0Rr@gmail.com> |
|
4 |
* |
|
5 |
* This program is free software; you can redistribute it and/or modify |
|
6 |
* it under the terms of the GNU General Public License as published by |
|
7 |
* the Free Software Foundation; version 2 of the License |
|
8 |
* |
|
9 |
* This program is distributed in the hope that it will be useful, |
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
* GNU General Public License for more details. |
|
13 |
* |
|
14 |
* You should have received a copy of the GNU General Public License |
|
15 |
* along with this program; if not, write to the Free Software |
|
16 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
*) |
|
18 |
||
4375 | 19 |
{$INCLUDE "options.inc"} |
20 |
||
21 |
unit uTextures; |
|
22 |
interface |
|
23 |
uses SDLh, uTypes; |
|
24 |
||
25 |
function NewTexture(width, height: Longword; buf: Pointer): PTexture; |
|
6303 | 26 |
procedure Surface2GrayScale(surf: PSDL_Surface); |
4375 | 27 |
function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; |
28 |
procedure FreeTexture(tex: PTexture); |
|
29 |
||
30 |
procedure initModule; |
|
31 |
procedure freeModule; |
|
32 |
||
33 |
implementation |
|
6394
f0a9042e7387
yay, finally osx (and likely windows) fullscreen switch works like on linux! ALL textures had to be destroyed and recreated only after the new window got created. In other news, the new window must be cleaned with glClear to skip a first frame of garbage and AddProgress is only called the first time.
koda
parents:
6390
diff
changeset
|
34 |
uses GLunit, uUtils, uVariables, uConsts, uDebug, uConsole; |
4375 | 35 |
|
36 |
var TextureList: PTexture; |
|
37 |
||
38 |
||
39 |
procedure SetTextureParameters(enableClamp: Boolean); |
|
40 |
begin |
|
41 |
if enableClamp and ((cReducedQuality and rqClampLess) = 0) then |
|
42 |
begin |
|
43 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
|
44 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) |
|
45 |
end; |
|
46 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
|
47 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) |
|
48 |
end; |
|
49 |
||
50 |
procedure ResetVertexArrays(texture: PTexture); |
|
51 |
begin |
|
52 |
with texture^ do |
|
53 |
begin |
|
54 |
vb[0].X:= 0; |
|
55 |
vb[0].Y:= 0; |
|
56 |
vb[1].X:= w; |
|
57 |
vb[1].Y:= 0; |
|
58 |
vb[2].X:= w; |
|
59 |
vb[2].Y:= h; |
|
60 |
vb[3].X:= 0; |
|
61 |
vb[3].Y:= h; |
|
62 |
||
63 |
tb[0].X:= 0; |
|
64 |
tb[0].Y:= 0; |
|
65 |
tb[1].X:= rx; |
|
66 |
tb[1].Y:= 0; |
|
67 |
tb[2].X:= rx; |
|
68 |
tb[2].Y:= ry; |
|
69 |
tb[3].X:= 0; |
|
70 |
tb[3].Y:= ry |
|
71 |
end; |
|
72 |
end; |
|
73 |
||
74 |
function NewTexture(width, height: Longword; buf: Pointer): PTexture; |
|
75 |
begin |
|
76 |
new(NewTexture); |
|
77 |
NewTexture^.PrevTexture:= nil; |
|
78 |
NewTexture^.NextTexture:= nil; |
|
79 |
NewTexture^.Scale:= 1; |
|
80 |
if TextureList <> nil then |
|
81 |
begin |
|
82 |
TextureList^.PrevTexture:= NewTexture; |
|
83 |
NewTexture^.NextTexture:= TextureList |
|
84 |
end; |
|
85 |
TextureList:= NewTexture; |
|
86 |
||
87 |
NewTexture^.w:= width; |
|
88 |
NewTexture^.h:= height; |
|
89 |
NewTexture^.rx:= 1.0; |
|
90 |
NewTexture^.ry:= 1.0; |
|
91 |
||
92 |
ResetVertexArrays(NewTexture); |
|
93 |
||
94 |
glGenTextures(1, @NewTexture^.id); |
|
95 |
||
96 |
glBindTexture(GL_TEXTURE_2D, NewTexture^.id); |
|
97 |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); |
|
98 |
||
99 |
SetTextureParameters(true); |
|
100 |
end; |
|
101 |
||
6303 | 102 |
procedure Surface2GrayScale(surf: PSDL_Surface); |
6305
5f7480c2a08d
Set default water colours in greyscale mode in case the theme does not define them, decrement piano weapon on use
nemo
parents:
6303
diff
changeset
|
103 |
var tw, x, y: Longword; |
6303 | 104 |
fromP4: PLongWordArray; |
105 |
begin |
|
106 |
fromP4:= Surf^.pixels; |
|
107 |
for y:= 0 to Pred(Surf^.h) do |
|
108 |
begin |
|
109 |
for x:= 0 to Pred(Surf^.w) do |
|
110 |
begin |
|
111 |
tw:= fromP4^[x]; |
|
112 |
tw:= round((tw shr RShift and $FF) * RGB_LUMINANCE_RED + |
|
113 |
(tw shr GShift and $FF) * RGB_LUMINANCE_GREEN + |
|
114 |
(tw shr BShift and $FF) * RGB_LUMINANCE_BLUE); |
|
115 |
if tw > 255 then tw:= 255; |
|
116 |
tw:= (tw and $FF shl RShift) or (tw and $FF shl BShift) or (tw and $FF shl GShift) or (fromP4^[x] and AMask); |
|
117 |
fromP4^[x]:= tw; |
|
118 |
end; |
|
119 |
fromP4:= @(fromP4^[Surf^.pitch div 4]) |
|
120 |
end; |
|
121 |
end; |
|
4375 | 122 |
function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; |
123 |
var tw, th, x, y: Longword; |
|
124 |
tmpp: pointer; |
|
125 |
fromP4, toP4: PLongWordArray; |
|
126 |
begin |
|
127 |
new(Surface2Tex); |
|
128 |
Surface2Tex^.PrevTexture:= nil; |
|
129 |
Surface2Tex^.NextTexture:= nil; |
|
130 |
if TextureList <> nil then |
|
131 |
begin |
|
132 |
TextureList^.PrevTexture:= Surface2Tex; |
|
133 |
Surface2Tex^.NextTexture:= TextureList |
|
134 |
end; |
|
135 |
TextureList:= Surface2Tex; |
|
136 |
||
137 |
Surface2Tex^.w:= surf^.w; |
|
138 |
Surface2Tex^.h:= surf^.h; |
|
139 |
||
140 |
if (surf^.format^.BytesPerPixel <> 4) then |
|
141 |
begin |
|
142 |
TryDo(false, 'Surface2Tex failed, expecting 32 bit surface', true); |
|
143 |
Surface2Tex^.id:= 0; |
|
144 |
exit |
|
145 |
end; |
|
146 |
||
147 |
||
148 |
glGenTextures(1, @Surface2Tex^.id); |
|
149 |
||
150 |
glBindTexture(GL_TEXTURE_2D, Surface2Tex^.id); |
|
151 |
||
152 |
if SDL_MustLock(surf) then |
|
153 |
SDLTry(SDL_LockSurface(surf) >= 0, true); |
|
154 |
||
5441
39962b855540
Add grayscale option for 3d, helps with colour clashing
nemo
parents:
4976
diff
changeset
|
155 |
fromP4:= Surf^.pixels; |
39962b855540
Add grayscale option for 3d, helps with colour clashing
nemo
parents:
4976
diff
changeset
|
156 |
|
6303 | 157 |
if cGrayScale then Surface2GrayScale(Surf); |
158 |
||
4375 | 159 |
if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then |
160 |
begin |
|
161 |
tw:= toPowerOf2(Surf^.w); |
|
162 |
th:= toPowerOf2(Surf^.h); |
|
163 |
||
164 |
Surface2Tex^.rx:= Surf^.w / tw; |
|
165 |
Surface2Tex^.ry:= Surf^.h / th; |
|
166 |
||
167 |
GetMem(tmpp, tw * th * surf^.format^.BytesPerPixel); |
|
168 |
||
169 |
fromP4:= Surf^.pixels; |
|
170 |
toP4:= tmpp; |
|
171 |
||
172 |
for y:= 0 to Pred(Surf^.h) do |
|
173 |
begin |
|
174 |
for x:= 0 to Pred(Surf^.w) do toP4^[x]:= fromP4^[x]; |
|
175 |
for x:= Surf^.w to Pred(tw) do toP4^[x]:= 0; |
|
176 |
toP4:= @(toP4^[tw]); |
|
177 |
fromP4:= @(fromP4^[Surf^.pitch div 4]) |
|
178 |
end; |
|
179 |
||
180 |
for y:= Surf^.h to Pred(th) do |
|
181 |
begin |
|
182 |
for x:= 0 to Pred(tw) do toP4^[x]:= 0; |
|
183 |
toP4:= @(toP4^[tw]) |
|
184 |
end; |
|
185 |
||
186 |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpp); |
|
187 |
||
188 |
FreeMem(tmpp, tw * th * surf^.format^.BytesPerPixel) |
|
189 |
end |
|
190 |
else |
|
191 |
begin |
|
192 |
Surface2Tex^.rx:= 1.0; |
|
193 |
Surface2Tex^.ry:= 1.0; |
|
194 |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf^.w, surf^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf^.pixels); |
|
195 |
end; |
|
196 |
||
197 |
ResetVertexArrays(Surface2Tex); |
|
198 |
||
199 |
if SDL_MustLock(surf) then |
|
200 |
SDL_UnlockSurface(surf); |
|
201 |
||
202 |
SetTextureParameters(enableClamp); |
|
203 |
end; |
|
204 |
||
4901 | 205 |
// deletes texture and frees the memory allocated for it. |
206 |
// if nil is passed nothing is done |
|
4375 | 207 |
procedure FreeTexture(tex: PTexture); |
208 |
begin |
|
209 |
if tex <> nil then |
|
6380
1ff5ad1d771b
Remove a bunch of unnecessary nil checks. FreeTexture does its own nil check.
nemo
parents:
6305
diff
changeset
|
210 |
begin |
4375 | 211 |
if tex^.NextTexture <> nil then |
212 |
tex^.NextTexture^.PrevTexture:= tex^.PrevTexture; |
|
213 |
if tex^.PrevTexture <> nil then |
|
214 |
tex^.PrevTexture^.NextTexture:= tex^.NextTexture |
|
215 |
else |
|
216 |
TextureList:= tex^.NextTexture; |
|
217 |
glDeleteTextures(1, @tex^.id); |
|
218 |
Dispose(tex); |
|
6380
1ff5ad1d771b
Remove a bunch of unnecessary nil checks. FreeTexture does its own nil check.
nemo
parents:
6305
diff
changeset
|
219 |
end |
4375 | 220 |
end; |
221 |
||
222 |
procedure initModule; |
|
223 |
begin |
|
224 |
TextureList:= nil; |
|
225 |
end; |
|
226 |
||
227 |
procedure freeModule; |
|
228 |
begin |
|
6394
f0a9042e7387
yay, finally osx (and likely windows) fullscreen switch works like on linux! ALL textures had to be destroyed and recreated only after the new window got created. In other news, the new window must be cleaned with glClear to skip a first frame of garbage and AddProgress is only called the first time.
koda
parents:
6390
diff
changeset
|
229 |
if TextureList <> nil then WriteToConsole('FIXME FIXME FIXME. App shutdown without full cleanup of texture list; read game0.log and please report this problem'); |
6390
3807d4cad077
This should have been added before. add log spew if this ever happens. We should hopefully identify the various circumstances and make sure it is all cleaned up so the list becomes unnecessary.
nemo
parents:
6380
diff
changeset
|
230 |
while TextureList <> nil do |
3807d4cad077
This should have been added before. add log spew if this ever happens. We should hopefully identify the various circumstances and make sure it is all cleaned up so the list becomes unnecessary.
nemo
parents:
6380
diff
changeset
|
231 |
begin |
3807d4cad077
This should have been added before. add log spew if this ever happens. We should hopefully identify the various circumstances and make sure it is all cleaned up so the list becomes unnecessary.
nemo
parents:
6380
diff
changeset
|
232 |
AddFileLog('Texture not freed: width='+inttostr(LongInt(TextureList^.w))+' height='+inttostr(LongInt(TextureList^.h))+' priority='+inttostr(round(TextureList^.priority*1000))); |
3807d4cad077
This should have been added before. add log spew if this ever happens. We should hopefully identify the various circumstances and make sure it is all cleaned up so the list becomes unnecessary.
nemo
parents:
6380
diff
changeset
|
233 |
FreeTexture(TextureList); |
3807d4cad077
This should have been added before. add log spew if this ever happens. We should hopefully identify the various circumstances and make sure it is all cleaned up so the list becomes unnecessary.
nemo
parents:
6380
diff
changeset
|
234 |
end |
4375 | 235 |
end; |
236 |
||
4901 | 237 |
end. |