SHOW:
|
|
- or go back to the newest paste.
1 | #include <windows.h> | |
2 | #include <GL/gl.h> | |
3 | #include <GL/glu.h> | |
4 | #include <stdio.h> | |
5 | #include <time.h> | |
6 | ||
7 | #define GET_X_LPARAM(a) ((short)LOWORD(a)) | |
8 | #define GET_Y_LPARAM(a) ((short)HIWORD(a)) | |
9 | ||
10 | unsigned short PlaneB[0x1000/2]; | |
11 | ||
12 | POINT camera = {0,0}; | |
13 | POINT mouse; | |
14 | double zoom = 1; | |
15 | bool showgray = false; | |
16 | int state = 0; | |
17 | int drawtype = 0; | |
18 | ||
19 | struct Ground | |
20 | { | |
21 | int width; | |
22 | int height; | |
23 | double *data; | |
24 | Ground(int _width, int _height) | |
25 | { | |
26 | width = _width; | |
27 | height = _height; | |
28 | data = (double *)malloc(width*height*sizeof(double)); | |
29 | for (int x=0; x<width; ++x) | |
30 | for (int y=0; y<height; ++y) | |
31 | (*this)[x][y] = 0; | |
32 | } | |
33 | ||
34 | double *operator [](int x) | |
35 | { | |
36 | return data+x*height; | |
37 | } | |
38 | ||
39 | ~Ground() | |
40 | { | |
41 | if (data) | |
42 | free(data); | |
43 | } | |
44 | }; | |
45 | ||
46 | struct DuneGround | |
47 | { | |
48 | int width; | |
49 | int height; | |
50 | BYTE *data; | |
51 | DuneGround(int _width, int _height) | |
52 | { | |
53 | width = _width; | |
54 | height = _height; | |
55 | data = (BYTE *)malloc(width*height*sizeof(BYTE)); | |
56 | for (int x=0; x<width; ++x) | |
57 | for (int y=0; y<height; ++y) | |
58 | (*this)[x][y] = 0xB0; | |
59 | } | |
60 | ||
61 | BYTE *operator [](int x) | |
62 | { | |
63 | return data+x*height; | |
64 | } | |
65 | ||
66 | ~DuneGround() | |
67 | { | |
68 | if (data) | |
69 | free(data); | |
70 | } | |
71 | ||
72 | DuneGround(const DuneGround & g) | |
73 | { | |
74 | width = g.width; | |
75 | height = g.height; | |
76 | data = (BYTE *)malloc(width*height*sizeof(BYTE)); | |
77 | memcpy(data,g.data,width*height*sizeof(BYTE)); | |
78 | } | |
79 | ||
80 | const DuneGround & operator = (const DuneGround &g) | |
81 | { | |
82 | free(data); | |
83 | width = g.width; | |
84 | height = g.height; | |
85 | data = (BYTE *)malloc(width*height*sizeof(BYTE)); | |
86 | memcpy(data,g.data,width*height*sizeof(BYTE)); | |
87 | return (*this); | |
88 | } | |
89 | }; | |
90 | ||
91 | /*struct Point | |
92 | { | |
93 | double x,y; | |
94 | }*/ | |
95 | ||
96 | DuneGround duneGround(64,64); | |
97 | DuneGround duneGroundNew(64,64); | |
98 | ||
99 | Ground g(2*64+1,2*64+1); | |
100 | GLuint GroundTiles; | |
101 | GLuint GroundGrey; | |
102 | ||
103 | // Declarations ////////////////////////////////////////////////////// | |
104 | ||
105 | GLuint LoadTextureRAW( const char * filename, int wrap ); | |
106 | GLuint LoadVRAM( const char * vram, const char * pal); | |
107 | GLuint GenerateGround(); | |
108 | void ChangeState(int _state); | |
109 | - | void LocalPick(int x, int y); |
109 | + | |
110 | void LocalPick(int x, int y, int type); | |
111 | void LoadMap( const char * filename ); | |
112 | void SaveMap( const char * filename ); | |
113 | void FreeTexture( GLuint texture ); | |
114 | ||
115 | LRESULT CALLBACK WndProc( HWND hWnd, UINT message, | |
116 | WPARAM wParam, LPARAM lParam ); | |
117 | ||
118 | VOID EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC ); | |
119 | VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC ); | |
120 | void UpdateViewport(HWND hWnd); | |
121 | void Render(HWND hWnd, HDC hDC); | |
122 | ||
123 | ||
124 | ||
125 | // WinMain /////////////////////////////////////////////////////////// | |
126 | ||
127 | int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, | |
128 | LPSTR lpCmdLine, int iCmdShow ) | |
129 | { | |
130 | WNDCLASS wc; | |
131 | HWND hWnd; | |
132 | HDC hDC; | |
133 | HGLRC hRC; | |
134 | MSG msg; | |
135 | BOOL bQuit = FALSE; | |
136 | ||
137 | // register window class | |
138 | wc.style = CS_OWNDC; | |
139 | wc.lpfnWndProc = WndProc; | |
140 | wc.cbClsExtra = 0; | |
141 | wc.cbWndExtra = 0; | |
142 | wc.hInstance = hInstance; | |
143 | wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); | |
144 | wc.hCursor = LoadCursor( NULL, IDC_ARROW ); | |
145 | wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); | |
146 | wc.lpszMenuName = NULL; | |
147 | wc.lpszClassName = "GLSample"; | |
148 | RegisterClass( &wc ); | |
149 | ||
150 | // create main window | |
151 | hWnd = CreateWindow( | |
152 | "GLSample", "OpenGL Texture Sample", | |
153 | WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | WS_THICKFRAME, | |
154 | 0, 0, 800, 600, | |
155 | NULL, NULL, hInstance, NULL ); | |
156 | ||
157 | // enable OpenGL for the window | |
158 | EnableOpenGL( hWnd, &hDC, &hRC ); | |
159 | UpdateViewport( hWnd); | |
160 | ||
161 | // load our texture | |
162 | GroundTiles = LoadTextureRAW( "tex1.bmp", TRUE ); | |
163 | //LoadMap("map_18.bin"); | |
164 | ||
165 | srand(time(0)); | |
166 | GroundGrey = GenerateGround(); | |
167 | //texture = LoadVRAM( "vram.bin", "pal.bin" ); | |
168 | ||
169 | int startTime = GetTickCount(); | |
170 | int prevTime = startTime; | |
171 | ||
172 | // program main loop | |
173 | while ( !bQuit ) { | |
174 | ||
175 | // check for messages | |
176 | if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { | |
177 | ||
178 | // handle or dispatch messages | |
179 | if ( msg.message == WM_QUIT ) { | |
180 | bQuit = TRUE; | |
181 | } else { | |
182 | TranslateMessage( &msg ); | |
183 | DispatchMessage( &msg ); | |
184 | } | |
185 | ||
186 | } else { | |
187 | int n = GetTickCount(); | |
188 | if (n - prevTime > 1000/40) | |
189 | { | |
190 | Render(hWnd, hDC); | |
191 | prevTime = n; | |
192 | } | |
193 | else | |
194 | Sleep(1); | |
195 | } | |
196 | ||
197 | } | |
198 | ||
199 | // free the texture | |
200 | FreeTexture( GroundTiles ); | |
201 | FreeTexture( GroundGrey ); | |
202 | ||
203 | // shutdown OpenGL | |
204 | DisableOpenGL( hWnd, hDC, hRC ); | |
205 | ||
206 | // destroy the window explicitly | |
207 | DestroyWindow( hWnd ); | |
208 | ||
209 | return msg.wParam; | |
210 | ||
211 | } | |
212 | ||
213 | void Render(HWND hWnd, HDC hDC) | |
214 | { | |
215 | // OpenGL animation code goes here | |
216 | RECT rc; | |
217 | GetClientRect(hWnd,&rc); | |
218 | double cx = int((camera.x+mouse.x-(rc.right/2))/32.0/zoom); | |
219 | double cy = int((camera.y+mouse.y-(rc.bottom/2))/32.0/zoom); | |
220 | if (state == 1 | |
221 | && (int)(cx*2) <64*2+1 && (int)(cx*2)>=0 | |
222 | - | LocalPick(cx*2,cy*2);//RangeGround(g[(int)(cx*2)][(int)(cy*2)]);*/ |
222 | + | |
223 | LocalPick(cx*2,cy*2,drawtype);//RangeGround(g[(int)(cx*2)][(int)(cy*2)]);*/ | |
224 | ||
225 | glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); | |
226 | glClear( GL_COLOR_BUFFER_BIT ); | |
227 | ||
228 | // setup texture mapping | |
229 | glEnable( GL_TEXTURE_2D ); | |
230 | glBindTexture( GL_TEXTURE_2D, GroundTiles ); | |
231 | ||
232 | glPushMatrix(); | |
233 | glBegin( GL_QUADS ); | |
234 | ||
235 | // tiles | |
236 | /*double tw = 1.0/64; | |
237 | for (int i=0; i<32; ++i) | |
238 | { | |
239 | for (int j=0; j<64; ++j) | |
240 | { | |
241 | int id = PlaneB[i*64+j]&0x7FF; | |
242 | int idx = id&63; | |
243 | int idy = id>>6; | |
244 | glTexCoord2d(tw*(idx+0),tw*(idy+0)); glVertex2d(-1.0+tw*j,+1.0-tw*i); | |
245 | glTexCoord2d(tw*(idx+1),tw*(idy+0)); glVertex2d(-1.0+tw*(j+1),+1.0-tw*i); | |
246 | glTexCoord2d(tw*(idx+1),tw*(idy+1)); glVertex2d(-1.0+tw*(j+1),+1.0-tw*(i+1)); | |
247 | glTexCoord2d(tw*(idx+0),tw*(idy+1)); glVertex2d(-1.0+tw*j,+1.0-tw*(i+1)); | |
248 | } | |
249 | } | |
250 | glTexCoord2d(0.0,0.0); glVertex2d(-8.0,+8.0); | |
251 | glTexCoord2d(1.0,0.0); glVertex2d(+8.0,+8.0); | |
252 | glTexCoord2d(1.0,1.0); glVertex2d(+8.0,-8.0); | |
253 | glTexCoord2d(0.0,1.0); glVertex2d(-8.0,-8.0);*/ | |
254 | GetClientRect(hWnd, &rc); | |
255 | double tw = 1.0/16; | |
256 | for (int i=0; i<64; ++i) | |
257 | { | |
258 | for (int j=0; j<64; ++j) | |
259 | { | |
260 | int id; | |
261 | if (state == 1) | |
262 | id = duneGroundNew[j][i]; | |
263 | else | |
264 | id = duneGround[j][i]; | |
265 | int idx = id&15; | |
266 | int idy = (id>>4); | |
267 | glTexCoord2d(tw*(idx+0),1-tw*(idy+0)); glVertex2d(j,-i); | |
268 | glTexCoord2d(tw*(idx+1),1-tw*(idy+0)); glVertex2d(j+1,-i); | |
269 | glTexCoord2d(tw*(idx+1),1-tw*(idy+1)); glVertex2d(j+1,-(i+1)); | |
270 | glTexCoord2d(tw*(idx+0),1-tw*(idy+1)); glVertex2d(j,-(i+1)); | |
271 | ||
272 | } | |
273 | } | |
274 | glEnd(); | |
275 | ||
276 | if (showgray) | |
277 | { | |
278 | glBindTexture( GL_TEXTURE_2D, GroundGrey ); | |
279 | glBegin( GL_QUADS ); | |
280 | glTexCoord2d(0,0); glVertex2d(0,-0); | |
281 | glTexCoord2d(1,0); glVertex2d(64,-0); | |
282 | glTexCoord2d(1,1); glVertex2d(64,-64); | |
283 | glTexCoord2d(0,1); glVertex2d(0,-64); | |
284 | glEnd(); | |
285 | } | |
286 | ||
287 | /*glBindTexture( GL_TEXTURE_2D, texture ); | |
288 | glBegin( GL_QUADS ); | |
289 | ||
290 | glTexCoord2d(tw*(3+0),1-tw*(0+0)); glVertex2d(cx,-cy); | |
291 | glTexCoord2d(tw*(3+1),1-tw*(0+0)); glVertex2d(cx+1,-cy); | |
292 | glTexCoord2d(tw*(3+1),1-tw*(0+1)); glVertex2d(cx+1,-cy-1); | |
293 | glTexCoord2d(tw*(3+0),1-tw*(0+1)); glVertex2d(cx,-cy-1); | |
294 | glEnd();*/ | |
295 | glPopMatrix(); | |
296 | ||
297 | SwapBuffers( hDC ); | |
298 | } | |
299 | ||
300 | ||
301 | // Texture /////////////////////////////////////////////////////////// | |
302 | ||
303 | // load a 256x256 RGB .RAW file as a texture | |
304 | GLuint LoadTextureRAW( const char * filename, int wrap ) | |
305 | { | |
306 | GLuint texture; | |
307 | int width, height; | |
308 | BYTE * data; | |
309 | FILE * file; | |
310 | FILE *f; | |
311 | BYTE tmp; | |
312 | int i; | |
313 | ||
314 | // open texture data | |
315 | file = fopen( filename, "rb" ); | |
316 | if ( file == NULL ) return 0; | |
317 | ||
318 | // allocate buffer | |
319 | width = 512; | |
320 | height = 512; | |
321 | data = (BYTE*)malloc( width * height * 3 ); | |
322 | ||
323 | // read texture data | |
324 | ||
325 | fseek( file, 0x36, SEEK_SET); | |
326 | fread( data, width * height * 3, 1, file ); | |
327 | fclose( file ); | |
328 | ||
329 | for (i=0; i<width*height; ++i) | |
330 | { | |
331 | tmp = data[i*3]; | |
332 | data[i*3] = data[i*3+2]; | |
333 | data[i*3+2] = tmp; | |
334 | } | |
335 | ||
336 | // allocate a texture name | |
337 | glGenTextures( 1, &texture ); | |
338 | ||
339 | // select our current texture | |
340 | glBindTexture( GL_TEXTURE_2D, texture ); | |
341 | ||
342 | // select modulate to mix texture with color for shading | |
343 | glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); | |
344 | ||
345 | // when texture area is small, bilinear filter the closest MIP map | |
346 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); | |
347 | ||
348 | // when texture area is large, bilinear filter the first MIP map | |
349 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); | |
350 | ||
351 | // if wrap is true, the texture wraps over at the edges (repeat) | |
352 | // ... false, the texture ends at the edges (clamp) | |
353 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, | |
354 | wrap ? GL_REPEAT : GL_CLAMP ); | |
355 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, | |
356 | wrap ? GL_REPEAT : GL_CLAMP ); | |
357 | ||
358 | // build our texture MIP maps | |
359 | //gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, | |
360 | // height, GL_RGB, GL_UNSIGNED_BYTE, data ); | |
361 | glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, | |
362 | height, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); | |
363 | ||
364 | // free buffer | |
365 | free( data ); | |
366 | ||
367 | return texture; | |
368 | ||
369 | } | |
370 | ||
371 | double randf() | |
372 | { | |
373 | return rand()/double(RAND_MAX); | |
374 | } | |
375 | ||
376 | void GenerateGroundRecursive(Ground &g, int x, int y, int width, int height) | |
377 | { | |
378 | if (width <= 1 || height <= 1) | |
379 | return; | |
380 | double a,b,c,d; | |
381 | a = g[x ][y ]; | |
382 | b = g[x+width][y ]; | |
383 | c = g[x ][y+height]; | |
384 | d = g[x+width][y+height]; | |
385 | ||
386 | g[(x + (x + width))/2][ y ] = (a + b)/2; | |
387 | g[ x ][(y + (y + height))/2] = (a + c)/2; | |
388 | g[(x + (x + width))/2][ y + height ] = (c + d)/2; | |
389 | g[ x + width ][(y + (y + height))/2] = (b + d)/2; | |
390 | ||
391 | double z = (a+b+c+d)/4+((-1+randf()*2)*width/64/2); | |
392 | if (z > 1) | |
393 | z = 1; | |
394 | if (z < 0) | |
395 | z = 0; | |
396 | g[(x + (x + width))/2][(y + (y + height))/2] = z; | |
397 | ||
398 | GenerateGroundRecursive(g, x , y , width/2, height/2); | |
399 | GenerateGroundRecursive(g, x + width/2, y , width/2, height/2); | |
400 | GenerateGroundRecursive(g, x , y + height/2, width/2, height/2); | |
401 | GenerateGroundRecursive(g, x + width/2, y + height/2, width/2, height/2); | |
402 | } | |
403 | - | void LocalPick(int x, int y) |
403 | + | |
404 | void LocalPick(int x, int y, int type) | |
405 | { | |
406 | static bool was[2*64+1][2*64+1]; | |
407 | ||
408 | for (int i=0; i<2*64+1; ++i) | |
409 | for (int j=0; j<2*64+1; ++j) | |
410 | was[i][j] = false; | |
411 | ||
412 | static int X[(2*64+1)*(2*64+1)]; | |
413 | static int Y[(2*64+1)*(2*64+1)]; | |
414 | double z = g[x][y]; | |
415 | int s = 0,e = 0; | |
416 | X[e] = x; | |
417 | Y[e] = y; | |
418 | was[x][y] = true; | |
419 | ++e; | |
420 | while (s < e) | |
421 | { | |
422 | for (int i=-1; i<2; ++i) | |
423 | for (int j=-1; j<2; ++j) | |
424 | if (X[s]+i>=0 && X[s]+i<2*64+1 | |
425 | && Y[s]+j>=0 && Y[s]+j<2*64+1 | |
426 | && !was[X[s]+i][Y[s]+j] | |
427 | && g[X[s]+i][Y[s]+j]>=z) | |
428 | { | |
429 | X[e] = X[s]+i; | |
430 | Y[e] = Y[s]+j; | |
431 | was[X[e]][Y[e]] = true; | |
432 | ++e; | |
433 | } | |
434 | ++s; | |
435 | } | |
436 | ||
437 | for (int x=0; x<64; ++x) | |
438 | { | |
439 | for (int y=0; y<64; ++y) | |
440 | { | |
441 | int mask = 0; | |
442 | for (int i=0; i<3; ++i) | |
443 | for (int j=0; j<3; ++j) | |
444 | if (was[i+x*2][j+y*2]) | |
445 | mask |= 1<<(i+j*3); | |
446 | ||
447 | int k = 0; | |
448 | //1 2 4 | |
449 | //8 16 32 | |
450 | //64 128 256 | |
451 | if ( (mask&(1+2+4)) == (1+2+4)) | |
452 | k++; | |
453 | if ( (mask&(4+32+256)) == (4+32+256)) | |
454 | k |= 2; | |
455 | if ( (mask&(64+128+256)) == (64+128+256)) | |
456 | k |= 4; | |
457 | if ( (mask&(1+8+64)) == (1+8+64)) | |
458 | k |= 8; | |
459 | int id = duneGround[x][y]; | |
460 | - | id = duneGround[x][y]; |
460 | + | if ( type == 0 ) |
461 | { | |
462 | id = 0x80+k; | |
463 | if ( k == 0) | |
464 | id = duneGround[x][y]; | |
465 | if ( k == 0 && (mask & 16)) // point | |
466 | id = 0x80; | |
467 | if ( k == 3 && !(mask & 16)) | |
468 | id = 0x3C; | |
469 | if ( k == 6 && !(mask & 16)) | |
470 | id = 0x3D; | |
471 | if ( k == 12 && !(mask & 16)) | |
472 | id = 0x3F; | |
473 | if ( k == 9 && !(mask & 16)) | |
474 | id = 0x3E; | |
475 | } | |
476 | if ( type == 1 ) | |
477 | { | |
478 | id = 0xB0+k; | |
479 | if ( k == 0) | |
480 | id = duneGround[x][y]; | |
481 | if ( k == 3 && !(mask & 16)) | |
482 | id = 0x40; | |
483 | if ( k == 6 && !(mask & 16)) | |
484 | id = 0x41; | |
485 | if ( k == 12 && !(mask & 16)) | |
486 | id = 0x43; | |
487 | if ( k == 9 && !(mask & 16)) | |
488 | id = 0x42; | |
489 | } | |
490 | if ( type == 2 ) | |
491 | { | |
492 | id = 0xC0+k; | |
493 | if ( k == 0) | |
494 | id = duneGround[x][y]; | |
495 | if ( k == 3 && !(mask & 16)) | |
496 | id = 0x44; | |
497 | if ( k == 6 && !(mask & 16)) | |
498 | id = 0x45; | |
499 | if ( k == 12 && !(mask & 16)) | |
500 | id = 0x47; | |
501 | if ( k == 9 && !(mask & 16)) | |
502 | id = 0x46; | |
503 | } | |
504 | duneGroundNew[x][y] = id; | |
505 | } | |
506 | } | |
507 | } | |
508 | ||
509 | void RangeGround(double z) | |
510 | { | |
511 | for (int x=0; x<64; ++x) | |
512 | { | |
513 | for (int y=0; y<64; ++y) | |
514 | { | |
515 | int mask = 0; | |
516 | for (int i=0; i<3; ++i) | |
517 | for (int j=0; j<3; ++j) | |
518 | if (g[i+x*2][j+y*2]>z) | |
519 | mask |= 1<<(i+j*3); | |
520 | int k = 0; | |
521 | //1 2 4 | |
522 | //8 16 32 | |
523 | //64 128 256 | |
524 | if ( (mask&(1+2+4)) == (1+2+4)) | |
525 | k++; | |
526 | if ( (mask&(4+32+256)) == (4+32+256)) | |
527 | k |= 2; | |
528 | if ( (mask&(64+128+256)) == (64+128+256)) | |
529 | k |= 4; | |
530 | if ( (mask&(1+8+64)) == (1+8+64)) | |
531 | k |= 8; | |
532 | int id = 0x80+k; | |
533 | if ( k == 0) | |
534 | id = 0xB0; | |
535 | if ( k == 0 && (mask & 16)) | |
536 | id = 0x80; | |
537 | if ( k == 3 && !(mask & 16)) | |
538 | id = 0x3C; | |
539 | if ( k == 6 && !(mask & 16)) | |
540 | id = 0x3D; | |
541 | if ( k == 12 && !(mask & 16)) | |
542 | id = 0x3F; | |
543 | if ( k == 9 && !(mask & 16)) | |
544 | id = 0x3E; | |
545 | ||
546 | duneGround[x][y] = id; | |
547 | } | |
548 | } | |
549 | } | |
550 | ||
551 | GLuint GenerateGround() | |
552 | { | |
553 | g[ 0][ 0] = randf(); | |
554 | g[g.width-1][ 0] = randf(); | |
555 | g[ 0][g.height-1] = randf(); | |
556 | g[g.width-1][g.height-1] = randf(); | |
557 | ||
558 | GenerateGroundRecursive(g, 0, 0, g.width-1, g.height-1); | |
559 | ||
560 | BYTE *data = (BYTE*)malloc( (g.width-1) * (g.height-1) * 3 ); | |
561 | ||
562 | - | /*for (int x=0; x<64; ++x) |
562 | + | |
563 | { | |
564 | for (int y=0; y<g.height-1; ++y) | |
565 | { | |
566 | - | int t; |
566 | + | |
567 | - | if (g[x*2][y*2]>0.5) |
567 | + | |
568 | - | t = 0x8F; |
568 | + | |
569 | } | |
570 | - | t = 0xB0; |
570 | + | |
571 | - | Map[x+y*64]=t; |
571 | + | |
572 | glGenTextures( 1, &texture ); | |
573 | ||
574 | glBindTexture( GL_TEXTURE_2D, texture ); | |
575 | ||
576 | glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); | |
577 | ||
578 | // when texture area is small, bilinear filter the closest MIP map | |
579 | - | int t; |
579 | + | |
580 | - | if (g[x*2][y*2]>0.5) |
580 | + | |
581 | - | t = 0x8F; |
581 | + | |
582 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); | |
583 | - | t = 0xB0; |
583 | + | |
584 | - | Map[x+y*64]=t; |
584 | + | |
585 | // ... false, the texture ends at the edges (clamp) | |
586 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); | |
587 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); | |
588 | ||
589 | glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, g.width-1, g.height-1, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); | |
590 | ||
591 | free(data); | |
592 | - | if ( y > 0 && Map[x+(y-1)*64] == 0x8F) |
592 | + | |
593 | return texture; | |
594 | - | if ( x < 63 && Map[x+1+y*64] == 0x8F) |
594 | + | |
595 | ||
596 | - | if ( y < 63 && Map[x+(y+1)*64] == 0x8F) |
596 | + | |
597 | { | |
598 | - | if ( x > 0 && Map[x-1+y*64] == 0x8F) |
598 | + | |
599 | if (!f) | |
600 | - | if (k != 0 && Map[x+y*64] != 0x8F) |
600 | + | |
601 | - | Map[x+y*64] = 0x80 + k; |
601 | + | |
602 | for (int y=0; y<64; ++y) | |
603 | - | }*/ |
603 | + | |
604 | { | |
605 | fread(&tmp,1,1,f); | |
606 | duneGround[x][y]=tmp; | |
607 | } | |
608 | - | GLuint LoadVRAM( const char * vram, const char * pal) |
608 | + | |
609 | } | |
610 | ||
611 | - | int width, height; |
611 | + | |
612 | - | BYTE palette[16*4][3]; |
612 | + | |
613 | - | BYTE * data; |
613 | + | |
614 | - | BYTE * vdata; |
614 | + | |
615 | - | FILE * file; |
615 | + | |
616 | - | FILE *f; |
616 | + | |
617 | - | int x; |
617 | + | |
618 | - | int y; |
618 | + | |
619 | fclose(f); | |
620 | - | file = fopen( pal, "rb" ); |
620 | + | |
621 | - | if ( file == NULL ) return 0; |
621 | + | |
622 | void FreeTexture( GLuint texture ) | |
623 | - | for (int i=0; i<16*4; ++i) |
623 | + | |
624 | glDeleteTextures( 1, &texture ); | |
625 | - | BYTE tmp = 0; |
625 | + | |
626 | - | short color; |
626 | + | |
627 | - | fread(&tmp, 1, 1, file); |
627 | + | |
628 | - | color = tmp << 8; |
628 | + | |
629 | - | fread(&tmp, 1, 1, file); |
629 | + | |
630 | - | color |= tmp; |
630 | + | |
631 | RECT rc; | |
632 | - | for (int j=0; j<3; ++j) |
632 | + | |
633 | glViewport( 0, 0, rc.right, rc.bottom); | |
634 | - | palette[i][j] = (((color >> (j*4))&0xE)/double(0xE))*0xFF; |
634 | + | |
635 | glLoadIdentity(); | |
636 | //gluOrtho2D( 0,0,500,500);//camera.x, camera.y, camera.x+rc.right, camera.y+rc.bottom); | |
637 | - | fclose( file ); |
637 | + | |
638 | - | |
638 | + | |
639 | - | // open texture data |
639 | + | |
640 | - | file = fopen( vram, "rb" ); |
640 | + | |
641 | - | if ( file == NULL ) return 0; |
641 | + | |
642 | ||
643 | - | // allocate buffer |
643 | + | |
644 | - | width = 512; |
644 | + | |
645 | - | height = 512; |
645 | + | |
646 | - | data = (BYTE*)malloc( width * height * 3 ); |
646 | + | |
647 | - | vdata = (BYTE*)malloc( 0x800 * 32 ); |
647 | + | |
648 | } | |
649 | - | // read texture data |
649 | + | |
650 | // Window Proc /////////////////////////////////////////////////////// | |
651 | - | fread( vdata, 0x800 * 32, 1, file ); |
651 | + | |
652 | - | fclose( file ); |
652 | + | |
653 | WPARAM wParam, LPARAM lParam ) | |
654 | - | x = 0; |
654 | + | |
655 | - | y = 0; |
655 | + | |
656 | - | for (int i=0; i < 0x800; ++i) |
656 | + | |
657 | case WM_CREATE: | |
658 | - | for (int v = 0; v < 8; ++v) |
658 | + | |
659 | - | for (int u = 0; u < 4; ++u) |
659 | + | |
660 | case WM_CLOSE: | |
661 | - | BYTE tmp = vdata[i*32+v*4+u]; |
661 | + | |
662 | - | BYTE *ptr = data+((y+v)*512+x+u*2)*3; |
662 | + | |
663 | ||
664 | case WM_SIZE: | |
665 | - | ptr[j] = palette[tmp>>4][j]; |
665 | + | |
666 | - | ptr[j+3] = palette[tmp&0xF][j]; |
666 | + | |
667 | ||
668 | - | /*for (int j=0; j<3; ++j) |
668 | + | |
669 | return 0; | |
670 | - | ptr[j] = palette[i%17][j]; |
670 | + | |
671 | - | ptr[j+3] = palette[i%17][j]; |
671 | + | |
672 | - | }*/ |
672 | + | switch ( wParam ) { |
673 | ||
674 | - | x += 8; |
674 | + | case VK_ESCAPE: |
675 | - | if (x == 512) |
675 | + | PostQuitMessage( 0 ); |
676 | return 0; | |
677 | - | x = 0; |
677 | + | |
678 | - | y += 8; |
678 | + | case 'S': |
679 | SaveMap("map.bin"); | |
680 | return 0; | |
681 | ||
682 | - | for (int i=0; i<0x1000/2; ++i) |
682 | + | case 'R': |
683 | FreeTexture(GroundGrey); | |
684 | - | PlaneB[i]=(vdata[0xC000+i*2]<<8)|vdata[0xC000+i*2+1]; |
684 | + | GroundGrey = GenerateGround(); |
685 | return 0; | |
686 | case 'E': | |
687 | ChangeState(state^1); | |
688 | return 0; | |
689 | case '0': | |
690 | drawtype = 0; | |
691 | return 0; | |
692 | case '1': | |
693 | drawtype = 1; | |
694 | return 0; | |
695 | case '2': | |
696 | drawtype = 2; | |
697 | return 0; | |
698 | case '3': | |
699 | drawtype = 3; | |
700 | return 0; | |
701 | case 'C': | |
702 | for (int x=0; x<duneGround.width; ++x) | |
703 | - | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
703 | + | for (int y=0; y<duneGround.height; ++y) |
704 | - | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
704 | + | duneGround[x][y] = 0xB0; |
705 | return 0; | |
706 | ||
707 | - | gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, |
707 | + | case VK_SPACE: |
708 | - | height, GL_RGB, GL_UNSIGNED_BYTE, data ); |
708 | + | showgray = !showgray; |
709 | return 0; | |
710 | } | |
711 | return 0; | |
712 | ||
713 | - | // free vram data |
713 | + | case WM_MOUSEWHEEL: |
714 | - | free ( vdata ); |
714 | + | |
715 | RECT rc; | |
716 | GetClientRect(hWnd,&rc); | |
717 | mouse.x = GET_X_LPARAM(lParam); | |
718 | mouse.y = GET_Y_LPARAM(lParam); | |
719 | short zDelta = HIWORD(wParam); | |
720 | if (zDelta > 0) | |
721 | { | |
722 | zoom *= 1.2; | |
723 | camera.x *= 1.2;//(camera.x + mouse.x) * (zoom/(zoom-0.1)) - mouse.x; | |
724 | camera.y *= 1.2;//(camera.y + mouse.y) * (zoom/(zoom-0.1)) - mouse.y; | |
725 | } | |
726 | else | |
727 | { | |
728 | zoom /= 1.2; | |
729 | camera.x /= 1.2; | |
730 | camera.y /= 1.2; | |
731 | } | |
732 | ||
733 | UpdateViewport(hWnd); | |
734 | } | |
735 | break; | |
736 | case WM_LBUTTONDOWN: | |
737 | { | |
738 | SetCapture(hWnd); | |
739 | mouse.x = GET_X_LPARAM(lParam); | |
740 | mouse.y = GET_Y_LPARAM(lParam); | |
741 | RECT rc; | |
742 | GetClientRect(hWnd,&rc); | |
743 | int cx = int((camera.x+mouse.x-(rc.right/2))/32.0/zoom); | |
744 | int cy = int((camera.y+mouse.y-(rc.bottom/2))/32.0/zoom); | |
745 | if (state == 1) | |
746 | duneGround = duneGroundNew; | |
747 | mousedown = true; | |
748 | } | |
749 | break; | |
750 | case WM_MOUSEMOVE: | |
751 | if (mousedown) | |
752 | { | |
753 | int xPos = mouse.x; mouse.x = GET_X_LPARAM(lParam); | |
754 | int yPos = mouse.y; mouse.y = GET_Y_LPARAM(lParam); | |
755 | camera.x -= mouse.x-xPos; | |
756 | camera.y -= mouse.y-yPos; | |
757 | UpdateViewport(hWnd); | |
758 | } | |
759 | mouse.x = GET_X_LPARAM(lParam); | |
760 | mouse.y = GET_Y_LPARAM(lParam); | |
761 | break; | |
762 | case WM_LBUTTONUP: | |
763 | ReleaseCapture(); | |
764 | mousedown = false; | |
765 | break; | |
766 | } | |
767 | return DefWindowProc( hWnd, message, wParam, lParam ); | |
768 | } | |
769 | ||
770 | ||
771 | // OpenGL //////////////////////////////////////////////////////////// | |
772 | ||
773 | // Enable OpenGL | |
774 | ||
775 | VOID EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC ) | |
776 | { | |
777 | PIXELFORMATDESCRIPTOR pfd; | |
778 | int iFormat; | |
779 | ||
780 | // get the device context (DC) | |
781 | *hDC = GetDC( hWnd ); | |
782 | ||
783 | // set the pixel format for the DC | |
784 | ZeroMemory( &pfd, sizeof( pfd ) ); | |
785 | pfd.nSize = sizeof( pfd ); | |
786 | pfd.nVersion = 1; | |
787 | pfd.dwFlags = PFD_DRAW_TO_WINDOW | | |
788 | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; | |
789 | pfd.iPixelType = PFD_TYPE_RGBA; | |
790 | pfd.cColorBits = 24; | |
791 | pfd.cDepthBits = 16; | |
792 | pfd.iLayerType = PFD_MAIN_PLANE; | |
793 | iFormat = ChoosePixelFormat( *hDC, &pfd ); | |
794 | SetPixelFormat( *hDC, iFormat, &pfd ); | |
795 | ||
796 | - | switch ( wParam ) { |
796 | + | // create and enable the render context (RC) |
797 | *hRC = wglCreateContext( *hDC ); | |
798 | - | case VK_ESCAPE: |
798 | + | wglMakeCurrent( *hDC, *hRC ); |
799 | ||
800 | } | |
801 | ||
802 | - | case 'S': |
802 | + | |
803 | - | SaveMap("map.bin"); |
803 | + | |
804 | VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC ) | |
805 | { | |
806 | - | case 'R': |
806 | + | wglMakeCurrent( NULL, NULL ); |
807 | - | FreeTexture(GroundGrey); |
807 | + | wglDeleteContext( hRC ); |
808 | - | GroundGrey = GenerateGround(); |
808 | + | ReleaseDC( hWnd, hDC ); |
809 | } |