Uživatelské nástroje

Nástroje pro tento web


pitel:mul:cv5

DirectX rozhraní

cvic5_2.cpp
// ----------------------------------------------------------------------------
// Direct X Demo
// (c) 2003 Pavel Tisnovsky
//
// Tento program otestuje zakladni vlastnosti knihovny DirectDraw.
// ----------------------------------------------------------------------------
 
#include <windows.h>
 
#include <ddraw.h>
#include <cstdio>
#include <cmath>
#include <ctime>
 
#define FULLSCREEN          1                       // 1-prejit do plne obrazovky, jinak zustat v rozliseni desktopu
#define SET_DISPLAY_MODE    1                       // 1-nastavit rezim obrazovky, jinak zustat v rozliseni desktopu
#define SET_PALETTE         1                       // 1-nastavit paletu, jinak nechat paletu systemovou
 
#define SCREEN_WIDTH        800                     // sirka obrazovky v pixelech
#define SCREEN_HEIGHT       600                     // vyska obrazovky v pixelech
#define SCREEN_BPP          8                       // pocet bitu na pixel
 
 
typedef struct {
    LPDIRECTDRAW        directDraw;                 // objekt DirectDraw
    LPDIRECTDRAWSURFACE primarySurface;             // framebuffer
    LPDIRECTDRAWSURFACE secondarySurface;             // framebuffer
    DDSURFACEDESC       primarySurfaceDesc;         // struktura s popisem framebufferu
    LPDIRECTDRAWPALETTE palette;                    // paleta
    PALETTEENTRY        paletteEntry[256];          // data palety
    unsigned char       color;                      // platna barva kresleni
} DirectDraw;
 
DirectDraw     dd;                                  // instance predchozi struktury
HWND           hwndMain=NULL;                       // handle hlavniho okna aplikace
 
// hlavicky pouzitych funkci
LRESULT CALLBACK MainWindowProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI       WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR commandLine, int ShowMode);
void             directDrawError(char *errmsg);
int              directDrawOpen(HWND hwnd, int width, int height, int bpp, int fullScreen, int setMode, int setPalette);
int              directDrawClose(void);
unsigned char *  directDrawLockSurface(void);
int              directDrawUnlockSurface(void);
int              directDrawClearSurface(void);
void             directDrawSetColor(unsigned char color);
void             directDrawPutpixel(int x, int y, unsigned char color);
void             directDrawHLine(int x1, int x2, int y);
void             directDrawVLine(int x, int y1, int y2);
 
 
void Flip()
{
  dd.primarySurface->Flip( NULL, DDFLIP_WAIT );
}
 
// ----------------------------------------------------------------------------
// ukazka vykresleni zakladnich objektu pomoci DirectDraw
// ----------------------------------------------------------------------------
void drawExample(float p0 = 5.0f, float p1 = 4.0f)
{
    float x, y, a;
    for (a=0; a<360.0f; a+=0.05f) {
        x=300.0f+200.0f*cos(a*3.1415f/180.0f*p0);
        y=300.0f+200.0f*sin(a*3.1415f/180.0f*p1);
        directDrawPutpixel((int)x, (int)y, (unsigned char)(127.0f*(cos(7.0f*a*3.1415f/180.0)+1.0f)));
    }
    directDrawSetColor(255);
    directDrawHLine(100, 500, 100);
    directDrawHLine(100, 500, 500);
    directDrawVLine(100, 100, 500);
    directDrawVLine(500, 100, 500);
 
    Flip();
}
 
// ----------------------------------------------------------------------------
// ukazka vykresleni zakladnich objektu pomoci DirectDraw
// ----------------------------------------------------------------------------
void drawExampleAnime(void)
{
  //float f0=1.0f;
  for(float f0=1.0f; f0<5.0f; f0+=0.5)
    drawExample(f0, f0+1.0f);
}
 
void xkalab00() {
	directDrawSetColor(255);
	srand(time(NULL));
	int x1 = (float(rand()) / RAND_MAX) * SCREEN_WIDTH;
	int y1 = (float(rand()) / RAND_MAX) * SCREEN_HEIGHT;
	int x2 = (float(rand()) / RAND_MAX) * SCREEN_WIDTH;
	int y2 = (float(rand()) / RAND_MAX) * SCREEN_HEIGHT;
	unsigned short vmax = 5;
	short v1x = (float(rand()) / RAND_MAX) * vmax + 1;
	short v1y = (float(rand()) / RAND_MAX) * vmax + 1;
	short v2x = (float(rand()) / RAND_MAX) * vmax + 1;
	short v2y = (float(rand()) / RAND_MAX) * vmax + 1;
	while (1) {
		directDrawClearSurface();
		x1 += v1x;
		if (x1 <= 0) {
			v1x *= -1;
			x1 = 0;
		} else if (x1 >= SCREEN_WIDTH) {
			v1x *= -1;
			x1 = SCREEN_WIDTH - 1;
		}
		y1 += v1y;
		if (y1 <= 0) {
			v1y *= -1;
			y1 = 0;
		} else if (y1 >= SCREEN_HEIGHT) {
			v1y *= -1;
			y1 = SCREEN_HEIGHT - 1;
		}
		x2 += v2x;
		if (x2 <= 0) {
			v2x *= -1;
			x2 = 0;
		} else if (x2 >= SCREEN_WIDTH) {
			v2x *= -1;
			x2 = SCREEN_WIDTH - 1;
		}
		y2 += v2y;
		if (y2 <= 0) {
			v2y *= -1;
			y2 = 0;
		} else if (y2 >= SCREEN_HEIGHT) {
			v2y *= -1;
			y2 = SCREEN_HEIGHT - 1;
		}
		directDrawHLine(x1, x2, y1);
		directDrawHLine(x1, x2, y2);
		directDrawVLine(x1, y1, y2);
		directDrawVLine(x2, y1, y2);
		Flip();
	}
}
 
// ----------------------------------------------------------------------------
// reakce na otevreni hlavniho okna aplikace
// ----------------------------------------------------------------------------
void onCreate(HWND hWnd)
{
 
}
 
// ----------------------------------------------------------------------------
// reakce na zruseni hlavniho okna aplikace
// ----------------------------------------------------------------------------
void onDestroy(HWND hWnd)
{
    directDrawClose();
}
 
// ----------------------------------------------------------------------------
// reakce na stisk klavesy
// ----------------------------------------------------------------------------
void onKeyPress(HWND hwnd, unsigned char key)
{
    switch (key) {
        case 'c': directDrawClearSurface(); Flip(); break;
        case 'd': drawExample();            break;
        case 'f': drawExampleAnime();       break;
        case 'a': xkalab00();       break;
    }
}
 
// ----------------------------------------------------------------------------
// reakce na zadost o prekresleni okna
// ----------------------------------------------------------------------------
void onPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    BeginPaint(hWnd, &ps);
    EndPaint(hWnd, &ps);
}
 
 
 
// ----------------------------------------------------------------------------
// hlavni smycka zprav
// ----------------------------------------------------------------------------
LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg) {
        case WM_CREATE:                             // zprava generovana pri vytvoreni okna
            onCreate(hwnd);
            break;
 
        case WM_DESTROY:                            // zprava generovana pri uzavirani okna
            onDestroy(hwnd);
            PostQuitMessage(0);
            break;
 
        case WM_CLOSE:                              // zprava generovana pred uzavrenim okna
            DestroyWindow(hwnd);
            break;
 
        case WM_CHAR:                               // zprava generovana pri stlaceni klavesy
            if (wParam==27) DestroyWindow(hwnd);
            else onKeyPress(hwnd,(unsigned char)wParam);
            break;
 
        case WM_PAINT:                              // zprava generovana pri pozadavku na prekresleni
            onPaint(hwnd);
            break;
 
        case WM_KILLFOCUS:                          // zprava generovana, kdyz okno ztrati fokus
            directDrawClose();
            break;
 
        case WM_SETFOCUS:                           // zprava generovana, kdyz okno ziska fokus
            directDrawOpen(hwnd, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, FULLSCREEN, SET_DISPLAY_MODE, SET_PALETTE);
            break;
 
        default:                                    // dalsi zpravy
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 1;
}
 
 
 
// ----------------------------------------------------------------------------
// hlavni funkce GDI aplikace
// ----------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR commandLine, int ShowMode)
{
    MSG stMsg;
    WNDCLASS    wc;
 
    wc.style = CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc = MainWindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "MAINWINDOW";
    if ((RegisterClass(&wc)) == 0) {
        MessageBox(NULL, "Can't create Window Class", "Error", MB_OK | MB_ICONSTOP);
        return 0;
    }
    if ((hwndMain=CreateWindowEx(WS_EX_TOPMOST, "MAINWINDOW", NULL, WS_POPUP,
                                     0, 0,
                                     GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
                                     NULL, NULL, hInstance, NULL)) == NULL) {
        MessageBox(NULL, "Can't create main window", "Error", MB_OK | MB_ICONSTOP);
        return 0;
    }
    ShowWindow(hwndMain, SW_SHOW);
    UpdateWindow(hwndMain);
    directDrawClearSurface();
    while (GetMessage(&stMsg, NULL, 0, 0)) {
        TranslateMessage(&stMsg);
        DispatchMessage(&stMsg);
    }
 
    return int(stMsg.wParam);
}
 
 
// ----------------------------------------------------------------------------
// Funkce volana pri vyskytu chyby
// ----------------------------------------------------------------------------
void directDrawError(char *errmsg)
{
    directDrawClose();
    MessageBox(NULL, "DirectDraw error", errmsg, MB_OK | MB_ICONSTOP);
    ExitProcess(0);
}
 
 
 
// ----------------------------------------------------------------------------
// Otevreni DirectDraw
// ----------------------------------------------------------------------------
int directDrawOpen(HWND hwnd, int width, int height, int bpp, int fullScreen, int setMode, int setPalette)
{
    DWORD       dwFlags;
    int i;
 
    // vytvoreni objektu DirectDraw
    if ((DirectDrawCreate(NULL, &(dd.directDraw), NULL))!=DD_OK) {
        directDrawError("Can't create direct draw object");
        return 0;
    }
 
    if (fullScreen)                                 // ma se vykreslovat do plneho okna
        dwFlags=DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_NOWINDOWCHANGES;
    else
        dwFlags=DDSCL_NORMAL | DDSCL_ALLOWREBOOT;
 
    // nastaveni rezimu kooperaci mezi HW a procesem
    if ((IDirectDraw_SetCooperativeLevel(dd.directDraw, hwnd, dwFlags)) != DD_OK) {
        directDrawError("Can't set co-operative level");
        return 0;
    }
 
    if (setMode) {                                  // ma se nastavit video rezim
        if ((IDirectDraw_SetDisplayMode(dd.directDraw, width, height, bpp)) != DD_OK) {
            directDrawError("Can't set display mode");
            return 0;
        }
    }
 
    // nastaveni framebufferu
    memset(&(dd.primarySurfaceDesc), 0, sizeof((dd.primarySurfaceDesc)));
 
    dd.primarySurfaceDesc.dwSize=sizeof(dd.primarySurfaceDesc);
    dd.primarySurfaceDesc.dwFlags=DDSD_CAPS| DDSD_BACKBUFFERCOUNT;
    dd.primarySurfaceDesc.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
    dd.primarySurfaceDesc.dwBackBufferCount = 1;
 
    if ((IDirectDraw_CreateSurface(dd.directDraw, &(dd.primarySurfaceDesc), &(dd.primarySurface), NULL)) != DD_OK) {
        directDrawError("Can't create primary surface");
        return 0;
    }
 
    DDSCAPS ddscaps;
    ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    if( dd.primarySurface->GetAttachedSurface(&ddscaps, &dd.secondarySurface) != DD_OK )
    {
        directDrawError("Can't get secondary surface");
        return 0;
    }
 
 
    if (setPalette) {                               // nastaveni palety
        for (i=0; i<256; i++) {                     // vytvorit barevnou skalu grayscale
            dd.paletteEntry[i].peRed  =(unsigned char)i;
            dd.paletteEntry[i].peGreen=(unsigned char)i;
            dd.paletteEntry[i].peBlue =(unsigned char)i;
            dd.paletteEntry[i].peFlags=(unsigned char)i;
        }
        IDirectDraw_CreatePalette(dd.directDraw, DDPCAPS_8BIT, dd.paletteEntry, &(dd.palette), NULL);
        IDirectDrawSurface_SetPalette(dd.primarySurface, dd.palette);
    }
    return 1;
}
 
 
 
// ----------------------------------------------------------------------------
// Uzavreni DirectDraw
// ----------------------------------------------------------------------------
int directDrawClose(void)
{
    if (dd.primarySurface) {                        // pokud existuje framebuffer
        IDirectDraw_Release(dd.primarySurface);     // zrusit ho
        dd.primarySurface=NULL;
    }
    if (dd.directDraw) {                            // pokud existuje objekt DirectDraw
        IDirectDraw_RestoreDisplayMode(dd.directDraw);
        IDirectDraw_Release(dd.directDraw);         // zrusit ho
        dd.directDraw=NULL;
    }
    return 1;                                       // vse probehlo v poradku
}
 
 
 
// ----------------------------------------------------------------------------
// Ziskani framebufferu do vyhradniho ovladani a vraceni jeho adresy
// ----------------------------------------------------------------------------
unsigned char * directDrawLockSurface(void)
{
    dd.primarySurfaceDesc.dwSize=sizeof(dd.primarySurfaceDesc);
    if (FAILED(IDirectDrawSurface_Lock(dd.secondarySurface, NULL, &(dd.primarySurfaceDesc), DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT, NULL))) {
        directDrawClose();
        directDrawError("Failure Locking Buffer");
        return NULL;
    }
 
    return (unsigned char *) dd.primarySurfaceDesc.lpSurface;
}
 
 
 
// ----------------------------------------------------------------------------
// Vraceni framebufferu zpet systemu (proces se vzdava ovladani)
// ----------------------------------------------------------------------------
int directDrawUnlockSurface(void)
{
    if (FAILED(IDirectDrawSurface_Unlock(dd.secondarySurface, NULL))) {
        directDrawClose();
        directDrawError("Failure Unlocking Buffer");
        return 0;
    }
 
    return 1;
}
 
 
 
// ----------------------------------------------------------------------------
// Vymazani cele obrazovky
// ----------------------------------------------------------------------------
int directDrawClearSurface(void)
{
    unsigned char *p=directDrawLockSurface();       // ziskat adresu framebufferu
    if (!p) return 0;
    memset(p, 0, dd.primarySurfaceDesc.lPitch*dd.primarySurfaceDesc.dwHeight);
    if (!directDrawUnlockSurface()) return 0;       // vratit framebuffer systemu
    return 1;
}
 
 
// ----------------------------------------------------------------------------
// Nastaveni barvy pro vykreslovani dalsich primitiv
// ----------------------------------------------------------------------------
void directDrawSetColor(unsigned char color)
{
    dd.color=color;
}
 
 
 
 
 
// ----------------------------------------------------------------------------
// Tato funkce nakresli na pozici [x, y] pixel
// ----------------------------------------------------------------------------
void directDrawPutpixel(int x, int y, unsigned char color)
{
    unsigned char *p=directDrawLockSurface();       // ziskat ukazatel na framebuffer
    *(p+x+y*dd.primarySurfaceDesc.lPitch)=color;    // ulozit barvu do framebufferu
    directDrawUnlockSurface();                      // vratit framebuffer systemu
}
 
 
 
// ----------------------------------------------------------------------------
// Tato funkce nakresli vertikalni usecku z bodu [x1, y] do bodu [x2, y]
// ----------------------------------------------------------------------------
void directDrawHLine(int x1, int x2, int y)
{
    int i;
    unsigned char *p=directDrawLockSurface();       // ziskat ukazatel na framebuffer
    if (x1>x2) {x1=x1^x2; x2=x1^x2; x1=x1^x2;}      // x1 musi byt mensi nez x2
    p+=x1+y*dd.primarySurfaceDesc.lPitch;           // prvni pixel usecky
    for (i=x1; i<x2; i++) *p++=dd.color;            // vyplnit usecku
    directDrawUnlockSurface();                      // vratit framebuffer systemu
}
 
 
 
// ----------------------------------------------------------------------------
// Tato funkce nakresli vertikalni usecku z bodu [x, y1] do bodu [x, y2]
// ----------------------------------------------------------------------------
void directDrawVLine(int x, int y1, int y2)
{
    int i;
    unsigned char *p=directDrawLockSurface();       // ziskat ukazatel na framebuffer
    if (y1>y2) {y1=y1^y2; y2=y1^y2; y1=y1^y2;}      // y1 musi byt mensi nez y2
    p+=x+y1*dd.primarySurfaceDesc.lPitch;           // prvni pixel usecky
    for (i=y1; i<y2; i++, p+=dd.primarySurfaceDesc.lPitch) *p=dd.color;// vyplnit usecku
    directDrawUnlockSurface();                      // vratit framebuffer systemu
}
 
 
 
 
// ----------------------------------------------------------------------------
// finito
// ----------------------------------------------------------------------------
/var/www/wiki/data/pages/pitel/mul/cv5.txt · Poslední úprava: 30. 12. 2022, 13.43:01 autor: 127.0.0.1