Rev 6189 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5153 | IgorA | 1 | ; |
2 | ; Texture Manager |
||
3 | ; |
||
4 | |||
5 | align 4 |
||
6 | proc find_texture uses ebx ecx, context:dword, h:dword |
||
7 | mov ebx,[context] |
||
8 | mov ebx,[ebx+offs_cont_shared_state+4] ;ebx = &texture_hash_table |
||
9 | mov eax,[h] |
||
10 | and eax,0xff |
||
11 | shl eax,2 |
||
6108 | IgorA | 12 | add eax,ebx ;eax = &context.shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE] |
5153 | IgorA | 13 | |
14 | ; [eax] - указатель на текстуру, получаемую через хеш таблицу |
||
15 | mov ecx,[h] ; ecx - указатель на искомую текстуру |
||
16 | @@: |
||
17 | cmp dword[eax],0 |
||
18 | je .no_found |
||
19 | mov ebx,[eax] |
||
20 | cmp dword[ebx+offs_text_handle],ecx |
||
21 | je .found |
||
22 | mov eax,[ebx+offs_text_next] |
||
23 | jmp @b |
||
24 | .no_found: |
||
25 | xor eax,eax ;ret NULL |
||
26 | .found: |
||
27 | ret |
||
28 | endp |
||
29 | |||
6108 | IgorA | 30 | align 4 |
31 | proc free_texture uses eax ebx ecx edx, context:dword, h:dword |
||
32 | mov edx,[context] |
||
5153 | IgorA | 33 | |
6108 | IgorA | 34 | stdcall find_texture,edx,[h] ;t=find_texture(context,h) |
35 | cmp dword[eax+offs_text_prev],0 ;if (t.prev==NULL) |
||
36 | jne .else |
||
37 | mov edx,[edx+offs_cont_shared_state+4] ;edx = &context.shared_state.texture_hash_table[0] |
||
38 | mov ebx,[eax+offs_text_handle] |
||
39 | and ebx,0xff |
||
40 | shl ebx,2 |
||
41 | add edx,ebx ;edx = &context.shared_state.texture_hash_table[t.handle % TEXTURE_HASH_TABLE_SIZE] |
||
42 | mov ebx,[eax+offs_text_next] |
||
43 | mov [edx],ebx ;*ht=t.next |
||
44 | jmp @f |
||
45 | .else: |
||
46 | mov ebx,[eax+offs_text_prev] |
||
47 | mov ecx,[eax+offs_text_next] |
||
48 | mov [ebx+offs_text_next],ecx ;t.prev.next=t.next |
||
49 | @@: |
||
50 | cmp dword[eax+offs_text_next],0 ;if (t.next!=NULL) |
||
51 | je @f |
||
52 | mov ebx,[eax+offs_text_next] |
||
53 | mov ecx,[eax+offs_text_prev] |
||
54 | mov [ebx+offs_text_prev],ecx ;t.next.prev=t.prev |
||
55 | @@: |
||
56 | |||
57 | xor ebx,ebx |
||
58 | mov ecx,[eax+offs_text_images] ;im=&t.images[0] |
||
59 | .cycle_0: ;for(i=0;i |
||
60 | cmp ebx,MAX_TEXTURE_LEVELS |
||
61 | jge .cycle_0_end |
||
62 | cmp dword[ecx+offs_imag_pixmap],0 ;if (im.pixmap != NULL) |
||
63 | je @f |
||
64 | stdcall gl_free,[ecx+offs_imag_pixmap] |
||
65 | @@: |
||
66 | add ecx,sizeof.GLImage |
||
67 | inc ebx |
||
68 | jmp .cycle_0 |
||
69 | .cycle_0_end: |
||
70 | |||
71 | stdcall gl_free,eax |
||
72 | ret |
||
73 | endp |
||
74 | |||
5153 | IgorA | 75 | ;output: |
76 | ; eax - указатель на память |
||
77 | align 4 |
||
78 | proc alloc_texture uses ebx ecx, context:dword, h:dword |
||
79 | |||
80 | stdcall gl_zalloc,sizeof.GLTexture |
||
81 | |||
82 | mov ebx,[context] |
||
83 | mov ebx,[ebx+offs_cont_shared_state+4] ;ebx = &texture_hash_table |
||
84 | mov ecx,[h] |
||
85 | and ecx,0xff |
||
86 | shl ecx,2 |
||
6108 | IgorA | 87 | add ecx,ebx ;ecx = &context.shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE] |
5153 | IgorA | 88 | |
89 | mov ebx,[ecx] |
||
90 | mov [eax+offs_text_next],ebx |
||
91 | mov dword[eax+offs_text_prev],0 ;NULL |
||
92 | cmp dword[eax+offs_text_next],0 ;NULL |
||
93 | je @f |
||
94 | mov [eax+offs_text_prev],eax |
||
95 | @@: |
||
96 | mov [ecx],eax |
||
97 | |||
98 | mov ebx,[h] |
||
99 | mov [eax+offs_text_handle],ebx |
||
100 | |||
101 | ret |
||
102 | endp |
||
103 | |||
104 | align 4 |
||
105 | proc glInitTextures uses eax edx, context:dword |
||
106 | ; textures |
||
107 | mov edx,[context] |
||
108 | mov dword[edx+offs_cont_texture_2d_enabled],0 |
||
109 | stdcall find_texture,edx,0 |
||
110 | mov dword[edx+offs_cont_current_texture],eax |
||
111 | ret |
||
112 | endp |
||
113 | |||
6108 | IgorA | 114 | align 4 |
115 | proc glGenTextures uses eax ebx ecx edx esi, n:dword, textures:dword |
||
116 | ;edx - GLTexture *t |
||
117 | call gl_get_context |
||
118 | add eax,offs_cont_shared_state+4 ;offset texture_hash_table = 4 |
||
5153 | IgorA | 119 | |
6108 | IgorA | 120 | xor ebx,ebx ;max=0 |
121 | xor ecx,ecx ;i=0 |
||
122 | .cycle_0: ;for(i=0;i |
||
123 | cmp ecx,TEXTURE_HASH_TABLE_SIZE |
||
124 | jge .cycle_0_end |
||
125 | mov esi,ecx |
||
126 | shl esi,2 |
||
127 | add esi,[eax] |
||
128 | mov edx,dword[esi] ;t=context.shared_state.texture_hash_table[i] |
||
129 | .cycle_1: ;while (t!=NULL) |
||
130 | or edx,edx |
||
131 | jz .cycle_1_end |
||
132 | cmp [edx+offs_text_handle],ebx ;if (t.handle>max) |
||
133 | jle @f |
||
134 | mov ebx,[edx+offs_text_handle] ;max=t.handle |
||
135 | @@: |
||
136 | mov edx,[edx+offs_text_next] ;t=t.next |
||
137 | jmp .cycle_1 |
||
138 | .cycle_1_end: |
||
139 | inc ecx |
||
140 | jmp .cycle_0 |
||
141 | .cycle_0_end: |
||
142 | |||
143 | xor ecx,ecx ;i=0 |
||
144 | mov esi,[textures] |
||
145 | .cycle_2: ;for(i=0;i |
||
146 | cmp ecx,[n] |
||
147 | jge .cycle_2_end |
||
148 | inc ebx |
||
149 | mov [esi],ebx ;textures[i]=max+i+1 |
||
150 | add esi,4 |
||
151 | inc ecx |
||
152 | jmp .cycle_2 |
||
153 | .cycle_2_end: |
||
154 | ret |
||
155 | endp |
||
156 | |||
5153 | IgorA | 157 | align 4 |
6108 | IgorA | 158 | proc glDeleteTextures uses eax ebx ecx edx, n:dword, textures:dword |
159 | call gl_get_context |
||
160 | mov edx,eax |
||
161 | mov ecx,[textures] |
||
162 | |||
163 | xor ebx,ebx |
||
164 | .cycle_0: ;for(i=0;i |
||
165 | cmp ebx,[n] |
||
166 | jge .cycle_0_end |
||
167 | stdcall find_texture,edx,[ecx] ;t=find_texture(context,textures[i]) |
||
168 | or eax,eax ;if (t!=0) |
||
169 | jz @f |
||
170 | cmp eax,[edx+offs_cont_current_texture] ;if (t==context.current_texture) |
||
171 | jne .end_1 |
||
172 | stdcall glBindTexture,GL_TEXTURE_2D,0 |
||
173 | .end_1: |
||
174 | stdcall free_texture, edx,[ecx] |
||
175 | @@: |
||
176 | add ecx,4 |
||
177 | inc ebx |
||
178 | jmp .cycle_0 |
||
179 | .cycle_0_end: |
||
180 | ret |
||
181 | endp |
||
182 | |||
183 | align 4 |
||
5153 | IgorA | 184 | proc glopBindTexture uses eax ebx edx, context:dword, p:dword |
185 | mov ebx,[p] |
||
186 | mov edx,[context] |
||
187 | |||
6108 | IgorA | 188 | cmp dword[ebx+4],GL_TEXTURE_2D |
189 | je @f |
||
190 | ;jne .error |
||
191 | ;cmp dword[ebx+8],0 |
||
192 | ;jge @f |
||
193 | .error: |
||
194 | stdcall dbg_print,sz_glBindTexture,err_7 |
||
195 | @@: |
||
5153 | IgorA | 196 | |
6108 | IgorA | 197 | mov ebx,[ebx+8] ;ebx = p[2] |
198 | stdcall find_texture, edx,ebx |
||
199 | or eax,eax ;if(t==NULL) |
||
200 | jnz @f |
||
201 | stdcall alloc_texture, edx,ebx |
||
5153 | IgorA | 202 | @@: |
203 | mov [edx+offs_cont_current_texture],eax |
||
204 | ret |
||
205 | endp |
||
206 | |||
207 | align 4 |
||
208 | proc glopTexImage2D, context:dword, p:dword |
||
6108 | IgorA | 209 | locals |
210 | pixels1 dd ? |
||
211 | do_free dd ? |
||
6243 | IgorA | 212 | aligned_width dd ? |
213 | aligned_height dd ? |
||
6108 | IgorA | 214 | endl |
215 | pushad |
||
216 | mov edi,[p] |
||
217 | mov eax,[edi+4] ;target=p[1].i |
||
218 | mov ebx,[edi+8] ;level=p[2].i |
||
219 | mov ecx,[edi+12] ;components=p[3].i; |
||
220 | mov edx,[edi+16] ;width=p[4].i; |
||
221 | mov esi,[edi+20] ;height=p[5].i; |
||
222 | |||
223 | cmp eax,GL_TEXTURE_2D ;if (param != GL_TEXTURE_2D) |
||
224 | jne .error |
||
225 | or ebx,ebx ;if (level != 0) |
||
226 | jnz .error |
||
227 | cmp ecx,3 ;if (components != 3) |
||
228 | jne .error |
||
229 | cmp dword[edi+24],0 ;if (border != 0) |
||
230 | jne .error |
||
231 | cmp dword[edi+28],GL_RGB ;if (format != GL_RGB) |
||
232 | jne .error |
||
233 | cmp dword[edi+32],GL_UNSIGNED_BYTE ;if (type != GL_UNSIGNED_BYTE) |
||
234 | jne .error |
||
235 | |||
236 | jmp @f |
||
237 | .error: |
||
238 | stdcall dbg_print,sz_glTexImage2D,err_8 ;"glTexImage2D: combinaison of parameters not handled" |
||
239 | @@: |
||
240 | |||
6243 | IgorA | 241 | stdcall gl_getPervPowerOfTwo,edx |
242 | mov [aligned_width],eax |
||
243 | stdcall gl_getPervPowerOfTwo,esi |
||
244 | mov [aligned_height],eax |
||
245 | |||
6108 | IgorA | 246 | mov dword[do_free],0 |
6243 | IgorA | 247 | cmp edx,[aligned_width] |
6108 | IgorA | 248 | jne .else |
6243 | IgorA | 249 | cmp esi,[aligned_height] |
6108 | IgorA | 250 | jne .else |
251 | mov eax,[edi+36] |
||
252 | mov [pixels1],eax ;pixels1=pixels |
||
253 | jmp @f |
||
6243 | IgorA | 254 | align 4 |
255 | .else: ;if (width != aligned_width || height != aligned_height) |
||
256 | imul eax,[aligned_width] |
||
257 | imul eax,3 |
||
258 | stdcall gl_malloc, eax |
||
259 | mov [pixels1],eax ;pixels1 = gl_malloc(aligned_width * aligned_height * 3) |
||
6108 | IgorA | 260 | ; no interpolation is done here to respect the original image aliasing ! |
6243 | IgorA | 261 | stdcall gl_resizeImage, eax,[aligned_width],[aligned_height],[edi+36],edx,esi |
6108 | IgorA | 262 | mov dword[do_free],1 |
6243 | IgorA | 263 | mov edx,[aligned_width] |
264 | mov esi,[aligned_height] |
||
6108 | IgorA | 265 | @@: |
266 | |||
267 | mov ecx,[context] |
||
268 | mov ecx,[ecx+offs_cont_current_texture] |
||
269 | add ecx,offs_text_images |
||
270 | imul ebx,sizeof.GLTexture |
||
271 | add ecx,ebx ;ecx = &context.current_texture.images[level] |
||
6243 | IgorA | 272 | mov [ecx+offs_imag_xsize],edx ;im.xsize=width |
273 | mov [ecx+offs_imag_ysize],esi ;im.ysize=height |
||
274 | mov ebx,edx |
||
275 | dec ebx |
||
276 | shl ebx,ZB_POINT_TEXEL_SIZE |
||
277 | mov [ecx+offs_imag_s_bound],ebx ;im.s_bound = (unsigned int)(width-1) |
||
278 | shr ebx,ZB_POINT_TEXEL_SIZE |
||
279 | |||
280 | mov dword[ecx+offs_imag_xsize_log2],ZB_POINT_TEXEL_SIZE |
||
281 | or ebx,ebx |
||
282 | jz .set_l2 |
||
283 | @@: |
||
284 | dec dword[ecx+offs_imag_xsize_log2] |
||
285 | shr ebx,1 |
||
286 | or ebx,ebx |
||
287 | jnz @b |
||
288 | .set_l2: |
||
289 | ;im.xsize_log2 = ZB_POINT_TEXEL_SIZE-log_2(width) |
||
290 | dec esi |
||
291 | shl esi,ZB_POINT_TEXEL_SIZE |
||
292 | mov [ecx+offs_imag_t_bound],esi ;im.t_bound = (unsigned int)(height-1) |
||
293 | shr esi,ZB_POINT_TEXEL_SIZE |
||
294 | inc esi |
||
6108 | IgorA | 295 | cmp dword[ecx+offs_imag_pixmap],0 ;if (im.pixmap!=NULL) |
296 | je @f |
||
297 | stdcall gl_free, [ecx+offs_imag_pixmap] |
||
298 | @@: |
||
299 | if TGL_FEATURE_RENDER_BITS eq 24 |
||
300 | imul edx,esi |
||
301 | imul edx,3 |
||
302 | stdcall gl_malloc,edx |
||
303 | mov [ecx+offs_imag_pixmap],eax ;im.pixmap = gl_malloc(width*height*3) |
||
304 | or eax,eax ;if(im.pixmap) |
||
305 | jz @f |
||
306 | mov edi,eax |
||
307 | mov esi,[pixels1] |
||
308 | mov ecx,edx |
||
309 | rep movsb ;memcpy(im.pixmap,pixels1,width*height*3) |
||
310 | @@: |
||
311 | end if |
||
312 | if TGL_FEATURE_RENDER_BITS eq 32 |
||
313 | mov ebx,edx |
||
314 | imul edx,esi |
||
315 | shl edx,2 |
||
316 | stdcall gl_malloc,edx |
||
317 | mov [ecx+offs_imag_pixmap],eax ;im.pixmap = gl_malloc(width*height*4) |
||
318 | or eax,eax ;if(im.pixmap) |
||
319 | jz @f |
||
320 | ;gl_convertRGB_to_8A8R8G8B(eax,[pixels1],ebx,esi) |
||
321 | @@: |
||
322 | end if |
||
323 | cmp dword[do_free],0 ;if (do_free) |
||
324 | je @f |
||
325 | stdcall gl_free, [pixels1] |
||
326 | @@: |
||
327 | popad |
||
5153 | IgorA | 328 | ret |
329 | endp |
||
330 | |||
331 | ; TODO: not all tests are done |
||
332 | align 4 |
||
6108 | IgorA | 333 | proc glopTexEnv uses eax ebx ecx, context:dword, p:dword |
334 | mov ecx,[p] |
||
335 | mov eax,[ecx+4] ;target=p[1].i |
||
336 | mov ebx,[ecx+8] ;pname=p[2].i |
||
337 | mov ecx,[ecx+12] ;param=p[3].i |
||
5153 | IgorA | 338 | |
6108 | IgorA | 339 | cmp eax,GL_TEXTURE_ENV ;if (target != GL_TEXTURE_ENV) |
340 | jne .error |
||
341 | cmp ebx,GL_TEXTURE_ENV_MODE ;if (pname != GL_TEXTURE_ENV_MODE) |
||
342 | jne .error |
||
343 | cmp ecx,GL_DECAL ;if (param != GL_DECAL) |
||
344 | jne .error |
||
345 | |||
346 | jmp @f |
||
347 | .error: |
||
348 | stdcall dbg_print,sz_glTexParameteri,err_6 |
||
349 | @@: |
||
5153 | IgorA | 350 | ret |
351 | endp |
||
352 | |||
353 | ; TODO: not all tests are done |
||
354 | align 4 |
||
6108 | IgorA | 355 | proc glopTexParameter uses eax ebx ecx, context:dword, p:dword |
356 | mov ecx,[p] |
||
357 | mov eax,[ecx+4] ;target=p[1].i |
||
358 | mov ebx,[ecx+8] ;pname=p[2].i |
||
359 | mov ecx,[ecx+12] ;param=p[3].i |
||
5153 | IgorA | 360 | |
6108 | IgorA | 361 | cmp eax,GL_TEXTURE_2D ;if (target != GL_TEXTURE_2D) |
362 | jne .error |
||
363 | cmp ebx,GL_TEXTURE_WRAP_S |
||
364 | je @f |
||
365 | cmp ebx,GL_TEXTURE_WRAP_T |
||
366 | je @f |
||
367 | jmp .error |
||
368 | @@: |
||
369 | cmp ecx,GL_REPEAT ;if (param != GL_REPEAT) |
||
370 | jne .error |
||
371 | |||
372 | jmp @f |
||
373 | .error: |
||
374 | stdcall dbg_print,sz_glTexParameteri,err_6 |
||
375 | @@: |
||
5153 | IgorA | 376 | ret |
377 | endp |
||
378 | |||
379 | align 4 |
||
6108 | IgorA | 380 | proc glopPixelStore uses eax ebx, context:dword, p:dword |
381 | mov ebx,[p] |
||
382 | mov eax,[ebx+4] ;pname=p[1].i |
||
383 | mov ebx,[ebx+8] ;param=p[2].i |
||
5153 | IgorA | 384 | |
6108 | IgorA | 385 | cmp eax,GL_UNPACK_ALIGNMENT ;if (pname != GL_UNPACK_ALIGNMENT) |
386 | jne .error |
||
387 | cmp ebx,1 ;if (param != 1) |
||
388 | jne .error |
||
389 | |||
390 | jmp @f |
||
391 | .error: |
||
392 | stdcall dbg_print,sz_glPixelStorei,err_6 |
||
393 | @@: |
||
5153 | IgorA | 394 | ret |
395 | endp |