1. /*
  2. Image of the bug: http://img23.imageshack.us/img23/6972/texerror.png
  3. edit: the bug seems to change on different gfx cards, but still visible one way or another!
  4. */
  5. #pragma comment(lib, "opengl32.lib")
  6. #pragma comment(lib, "Glu32.lib")
  7.  
  8. #include <windows.h>
  9. #include <stdio.h>
  10. #include <gl/glew.h>
  11. #include <gl/gl.h>
  12.  
  13. HDC hDC = NULL;
  14. HGLRC hRC = NULL;
  15. HWND hWnd = NULL;
  16. HINSTANCE hInstance;
  17.  
  18. bool active = 1;
  19. int window_width = 1024;
  20. int window_height = 768;
  21.  
  22. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
  23.     switch(uMsg){
  24.         case WM_ACTIVATE: {
  25.             active = !HIWORD(wParam);
  26.             return 0;
  27.         }
  28.         case WM_CLOSE: {
  29.             exit(0);
  30.             return 0;
  31.         }
  32.         case WM_SIZE: {
  33.             window_width = LOWORD(lParam);
  34.             window_height = HIWORD(lParam);
  35.             return 0;
  36.         }
  37.     }
  38.     return DefWindowProc(hWnd,uMsg,wParam,lParam);
  39. }
  40.  
  41. BOOL create_window(int width, int height){
  42.     GLuint PixelFormat;
  43.     WNDCLASS wc;
  44.     DWORD dwExStyle,dwStyle;
  45.     RECT WindowRect;
  46.     WindowRect.left = (long)0;
  47.     WindowRect.right = (long)width;
  48.     WindowRect.top = (long)0;
  49.     WindowRect.bottom = (long)height;
  50.     hInstance = GetModuleHandle(NULL);
  51.     wc.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
  52.     wc.lpfnWndProc = (WNDPROC)WndProc;
  53.     wc.cbClsExtra = 0;
  54.     wc.cbWndExtra = 0;
  55.     wc.hInstance = hInstance;
  56.     wc.hIcon = NULL;
  57.     wc.hCursor = NULL;
  58.     wc.hbrBackground = NULL;
  59.     wc.lpszMenuName = NULL;
  60.     wc.lpszClassName = TEXT("test");
  61.     if(!RegisterClass(&wc)) return FALSE;
  62.     dwExStyle = WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;
  63.     dwStyle = WS_OVERLAPPEDWINDOW;
  64.     ShowCursor(TRUE);
  65.     AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
  66.     if(!(hWnd = CreateWindowEx(dwExStyle,TEXT("test"),TEXT("test"),dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,0,0,width,height,NULL,NULL,hInstance,NULL))) return FALSE;
  67.     static PIXELFORMATDESCRIPTOR pfd = {sizeof(PIXELFORMATDESCRIPTOR),1,PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,PFD_TYPE_RGBA,(BYTE)32,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,PFD_MAIN_PLANE,0,0,0,0};
  68.     if(!(hDC = GetDC(hWnd))) return FALSE;
  69.     if(!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) return FALSE;
  70.     if(!SetPixelFormat(hDC, PixelFormat, &pfd)) return FALSE;
  71.     if(!(hRC = wglCreateContext(hDC))) return FALSE;
  72.     if(!wglMakeCurrent(hDC, hRC)) return FALSE;
  73.     ShowWindow(hWnd, SW_SHOW);
  74.     SetForegroundWindow(hWnd);
  75.     SetFocus(hWnd);
  76.     return TRUE;
  77. }
  78.  
  79.  
  80.  
  81. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
  82.     if(!create_window(window_width,window_height)){
  83.         return 1;
  84.     }
  85.     glShadeModel(GL_SMOOTH);
  86.     glDisable(GL_DEPTH_TEST);
  87.     glDepthFunc(GL_LEQUAL);
  88.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  89.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  90.     glClearColor(0,0,0,1);
  91.     glColor4f(1,1,1,1);
  92.  
  93.     // create red/yellow checkers pattern with slightly randomized tile pixels:
  94.     int img_w = 256;
  95.     int img_h = 256;
  96.     int tilesize = 16;
  97.     unsigned int *data = (unsigned int *)malloc(img_w*img_h*4);
  98.     unsigned int colors[] = {0xFF3333, 0xFFFF33};
  99.     for(int y = 0; y < img_h; y+=tilesize){
  100.         for(int x = 0; x < img_w; x+=tilesize){
  101.             unsigned int i = ((x/tilesize)+((y/tilesize)%2))%2;
  102.             for(int yy = 0; yy < tilesize; yy++){
  103.                 for(int xx = 0; xx < tilesize; xx++){
  104.                     int r = ((colors[i]>>0)&255)-(rand()%30);
  105.                     int g = ((colors[i]>>8)&255)-(rand()%30);
  106.                     int b = ((colors[i]>>16)&255)-(rand()%30);
  107.                     if(r < 0) r = 0;
  108.                     if(g < 0) g = 0;
  109.                     if(b < 0) b = 0;
  110.                     data[(y+yy)*img_w+(x+xx)] = (b << 16) | (g << 8) | r;
  111.                 }
  112.             }
  113.         }
  114.     }
  115.  
  116.     unsigned int texid = 0;
  117.     glGenTextures(1, &texid);
  118.     glBindTexture(GL_TEXTURE_2D, texid);
  119.     glEnable(GL_TEXTURE_2D);
  120.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  121.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  122.     glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
  123.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_w, img_h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
  124.     free(data);
  125.  
  126.     BOOL done = 0;
  127.     static MSG msg;
  128.  
  129.     float zpos = 600.0f;
  130.  
  131.     while(!done){
  132.         if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
  133.             if(msg.message == WM_QUIT){
  134.                 done = TRUE;
  135.             }else{
  136.                 TranslateMessage(&msg);
  137.                 DispatchMessage(&msg);
  138.             }
  139.         }else if(active){
  140.             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  141.  
  142.             glViewport(0, 0, window_width, window_height);
  143.             glMatrixMode(GL_PROJECTION);
  144.             glLoadIdentity();
  145.             gluPerspective(45.0f, (GLdouble)window_width/(GLdouble)window_height, 0.05f, 5000.0f);
  146.             glMatrixMode(GL_MODELVIEW);
  147.             glLoadIdentity();
  148.  
  149.             glRotatef(0, 1,0,0);
  150.             glRotatef(0, 0,1,0);
  151.             glRotatef(0, 0,0,1);
  152.             glTranslatef(0, 0, -zpos);
  153.             zpos /= 1.02f;
  154.             if(zpos < 0.1f) zpos = 0.1f;
  155.  
  156.             // draw map from randomly picked tiles:
  157.             glDisable(GL_DEPTH_TEST);
  158.             glDisable(GL_BLEND);
  159.             glEnable(GL_TEXTURE_2D);
  160.             glBindTexture(GL_TEXTURE_2D, texid);
  161.             glColor4f(1,1,1,1);
  162.             static GLuint my_list = 0;
  163.             static bool list_made = 0;
  164.             if(!list_made){
  165.                 int map_w = 100;
  166.                 int map_h = 100;
  167.                 int tiles_x = img_w/tilesize;
  168.                 int tiles_y = img_h/tilesize;
  169.                 my_list = glGenLists(1);
  170.                 glNewList(my_list, GL_COMPILE);
  171.                 glBegin(GL_QUADS);
  172.                 for(int y = -map_h; y < map_h; y++){
  173.                     for(int x = -map_w; x < map_w; x++){
  174.                         int xt = (rand()%tiles_x)*tilesize;
  175.                         int yt = (rand()%tiles_y)*tilesize;
  176.                         float tx1 = (float)xt/img_w;
  177.                         float ty1 = (float)yt/img_h;
  178.                         float tx2 = (float)(xt+tilesize)/img_w;
  179.                         float ty2 = (float)(yt+tilesize)/img_h;
  180.                         float x1 = (float)x;
  181.                         float y1 = (float)y;
  182.                         float x2 = (float)(x+1);
  183.                         float y2 = (float)(y+1);
  184.                         glTexCoord2f(tx1,ty1); glVertex2f(x1,y1);
  185.                         glTexCoord2f(tx2,ty1); glVertex2f(x2,y1);
  186.                         glTexCoord2f(tx2,ty2); glVertex2f(x2,y2);
  187.                         glTexCoord2f(tx1,ty2); glVertex2f(x1,y2);
  188.                     }
  189.                 }
  190.                 glEnd();
  191.                 glEndList();
  192.                 list_made = 1;
  193.             }
  194.             if(list_made){
  195.                 glCallList(my_list);
  196.             }
  197.  
  198.  
  199.             Sleep(16); // dont run too fast or you break your legs!
  200.  
  201.             SwapBuffers(hDC);
  202.         }
  203.     }
  204.  
  205.     return 0;
  206. }