2016-06-13 6 views
0

だから、私はいろいろな本やWebチュートリアルを使ってC++で遊んでいました。SetPixelと複数のピクセルC++ winapi

と今私はグラフィックスに来ました。現在WinApiにあります。

テキスト、画像、またはピクセルをペイントするウィンドウがあります。

しかし、SetPixelsを使用して多くのピクセルをペイントするのは簡単です。

私のコードからの抜粋:

void DrawBitmap(RECT rect, string text) { 


    HDC buffer = CreateCompatibleDC(device); 
    HBITMAP BGimage = CreateCompatibleBitmap(device, rect.right - rect.left, rect.bottom - rect.top); 
    SelectObject(buffer, BGimage); 

    //Clearing the screen with a full rect 
    Rectangle(buffer, rect.left, rect.top, rect.right, rect.bottom); 


    //Sample on making a single pixel at mouseclik, with color 250 on screen. 

    SetPixelV(buffer, x, y, 250); 


    int PixelSize = 4; 



    //SOME HEAVY PIXELS to slow the FPS 
    /* 
    for (int i = 0; i < 255; i++) { 
     for (int k = 0; k < 255; k++) { 
      SetPixelV(buffer, x + i, y + k, COLORREF RGB(150, i, k)); 
     } 
    } 
    */ 



    //Sample on making some text. 
    RECT drawRect; 
    drawRect = { rect.left + 5, rect.top + 5, rect.left + 105, rect.top + 25 }; 
    DrawText(buffer, text.c_str(), text.length(), &drawRect, DT_LEFT); 


    // counter number to be converted to a string 
    int timeint = GetTickCount(); 
    ostringstream convert; // stream used for the conversion 
    convert << "TIME: " << timeint;  // insert the textual representation of 'Number' in the characters in the stream 
    text = convert.str(); 
    drawRect = { rect.left + 5, rect.top + 25, rect.left + 680, rect.top + 45 }; 
    DrawText(buffer, text.c_str(), text.length(), &drawRect, DT_LEFT); 

    ostringstream convert2; // stream used for the conversion 
    convert2 << "FPS: " << FPS_calc;  // insert the textual representation of 'Number' in the characters in the stream 
    text = convert2.str(); 
    drawRect = { rect.left + 5, rect.top + 45, rect.left + 680, rect.top + 65 }; 
    DrawText(buffer, text.c_str(), text.length(), &drawRect, DT_LEFT); 


    //do the dubble buffering 
    BitBlt(device, 0, 0, rect.right - rect.left, rect.bottom - rect.top, buffer, 0, 0, SRCCOPY); 

    DeleteDC(buffer); 
    DeleteObject((HBITMAP)BGimage); 
} 

、これは正常に動作しますが、// SOME HEAVY PIXELS(現在はオフコメント) はスピードの多くを占めています。それから私はあなたがイメージをロックし、ビットを操作することができると聞いた。

私は単にその周りに頭を上げることはできませんか? すべての高価なコール機能を避けながら、x、yの各フィールドに100×100のフィールドを記入したい(サンプルの場合)必要があります。

私は[同じのhttps://msdn.microsoft.com/en-us/library/5ey6h79d(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-2]

そして、多くの他のバージョンを試してみました。しかし、私は働くことができないようです..

誰もが考えている?

私の完全な作業コードはここにある:

#include<Windows.h> 
#include<iostream> 
#include<time.h> 
#include<string> 


#include <sstream> 

using namespace std; 

const string APPTITLE = "GAME LOOP"; 
const string APPNAME = "GAME LOOP"; 
HWND window; 
HDC device; 

bool gameover = false; 
POINT p; 
int x = 200; 
int y = 200; 
int startTime; 
int currentTime; 
int lastTime; 
int FPS_calc = 0; 


// FORWARD DECLARATIONS 
void DrawBitmap(RECT rect, string text); 
bool Game_Init(); 
void Game_Run(); 
void Game_End(); 
ATOM MyRegisterClass(HINSTANCE hInstance); 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow); 
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 
string ArrowKey(); 
void MouseDet(POINT &mp); 



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { 
    MSG msg; 
    MyRegisterClass(hInstance); 

    if (InitInstance(hInstance, nCmdShow) != 1) return GetLastError(); 

    if (!Game_Init()) return 0; 
    while (!gameover) { 
     if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
     Game_Run(); 
    } 
    Game_End(); 

    return msg.wParam; 
} 

//////////Functions////////////// 


// Main game function 
void Game_Run() { 
    if (gameover == true) return; 

    RECT rect; 
    GetClientRect(window, &rect); 


    //ARROW KEY DETECTOR 
    string text = ArrowKey(); 
    //MouseDetector sets point if Left mouse key is pressed/held 
    MouseDet(p); 
    currentTime = GetTickCount(); 
    FPS_calc = int(1000/(currentTime-lastTime)); 
    if (lastTime != currentTime) lastTime = currentTime-1; 
    else lastTime = currentTime-30; 
    DrawBitmap(rect, text); 

} 


//Draw function with dubble buffering 
void DrawBitmap(RECT rect, string text) { 


    HDC buffer = CreateCompatibleDC(device); 
    HBITMAP BGimage = CreateCompatibleBitmap(device, rect.right - rect.left, rect.bottom - rect.top); 
    SelectObject(buffer, BGimage); 

    //Clearing the screen with a full rect 
    Rectangle(buffer, rect.left, rect.top, rect.right, rect.bottom); 


    //Sample on making a single pixel at mouseclik, with color 250 on screen. 

    SetPixelV(buffer, x, y, 250); 


    int PixelSize = 4; 



    //SOME HEAVY PIXELS to slow the FPS 
    /* 
    for (int i = 0; i < 255; i++) { 
     for (int k = 0; k < 255; k++) { 
      SetPixelV(buffer, x + i, y + k, COLORREF RGB(150, i, k)); 
     } 
    } 
    */ 



    //Sample on making some text. 
    RECT drawRect; 
    drawRect = { rect.left + 5, rect.top + 5, rect.left + 105, rect.top + 25 }; 
    DrawText(buffer, text.c_str(), text.length(), &drawRect, DT_LEFT); 


    // counter number to be converted to a string 
    int timeint = GetTickCount(); 
    ostringstream convert; // stream used for the conversion 
    convert << "TIME: " << timeint;  // insert the textual representation of 'Number' in the characters in the stream 
    text = convert.str(); 
    drawRect = { rect.left + 5, rect.top + 25, rect.left + 680, rect.top + 45 }; 
    DrawText(buffer, text.c_str(), text.length(), &drawRect, DT_LEFT); 

    ostringstream convert2; // stream used for the conversion 
    convert2 << "FPS: " << FPS_calc;  // insert the textual representation of 'Number' in the characters in the stream 
    text = convert2.str(); 
    drawRect = { rect.left + 5, rect.top + 45, rect.left + 680, rect.top + 65 }; 
    DrawText(buffer, text.c_str(), text.length(), &drawRect, DT_LEFT); 


    //do the dubble buffering 
    BitBlt(device, 0, 0, rect.right - rect.left, rect.bottom - rect.top, buffer, 0, 0, SRCCOPY); 

    DeleteDC(buffer); 
    DeleteObject((HBITMAP)BGimage); 
} 



//initialize value 
bool Game_Init() { 
    //get a random engine 
    srand(time(NULL)); 
    //getStartTime 
    startTime = GetTickCount(); 
    currentTime = startTime; 
    lastTime = currentTime - 1; 
    FPS_calc = int(1000/(lastTime - currentTime)); 
    return 1; 
} 


//End the game, release the window 
void Game_End() { 
    ReleaseDC(window, device); 
} 

//A window "setup" 
ATOM MyRegisterClass(HINSTANCE hInstance) { 
    WNDCLASSEX wc; 
    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = (WNDPROC)WinProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = hInstance; 
    wc.hIcon = NULL; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName = NULL; 
    wc.lpszClassName = APPTITLE.c_str(); 
    wc.hIconSm = NULL; 
    return RegisterClassEx(&wc); 
} 



//Creates our visible window 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { 
    window = CreateWindow(APPTITLE.c_str(), APPTITLE.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL); 

    if (window == 0) return 0; 

    ShowWindow(window, nCmdShow); 
    UpdateWindow(window); 

    device = GetDC(window); 
    return 1; 
} 


LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 
    switch (message) { 
    case WM_DESTROY: 
     gameover = true; 
     PostQuitMessage(0); 
     break; 
    } 
    return DefWindowProc(hWnd, message, wParam, lParam); 
} 


//Test if arrow keys have been typed, return text wit hwich one 
string ArrowKey() { 
    string text = "NONE"; 
    if ((1 << 16) & GetAsyncKeyState(VK_UP)) 
    { 
     text = "UP"; 
     y--; 
    } 
    if ((1 << 16) & GetAsyncKeyState(VK_DOWN)) 
    { 
     text = "DOWN"; 
     y++; 
    } 
    if ((1 << 16) & GetAsyncKeyState(VK_RIGHT)) 
    { 
     text = "RIGTH"; 
     x++; 
    } 
    if ((1 << 16) & GetAsyncKeyState(VK_LEFT)) 
    { 
     text = "LEFT"; 
     x--; 
    } 
    return text; 
} 


void MouseDet(POINT &mp) { 
    if ((1 << 16) & GetAsyncKeyState(VK_LBUTTON)) { 

     GetCursorPos(&mp); 
     if (ScreenToClient(window, &mp)) {} 
     x = p.x; 
     y = p.y; 
    } 
} 
+0

'SetDIBits'と' GetDIBits'を使うと、複数のピクセルごとのAPI呼び出しではなく、ビットマップからピクセルデータを変更してメモリのチャンクとして読み取ることができます。これはおそらくあなたが探しているものです(あなたがGDIを越えて移動したい場合を除いて)。 https://msdn.microsoft.com/en-us/library/windows/desktop/dd162973(v=vs.85).aspx –

+0

ありがとう、私はそれを試してみましたが、それは助けていないようです。 – JavaApprentis

答えて

0

あなただけの長方形/四角形を描画するために探しているなら、あなたはこれを行うにはFillRectを使用することができます。

+0

私は知っているが、いいえ。 多くのピクセルを個別に操作したい(SetPixels()) この例では100個の100個のボックスを使用して、10.000個のピクセルの位置を簡単にプログラムできるようにしています。後で使用するとスタンドアロン移動できるピクセル。しかし、まずグラフィックスをsetPixelより速く操作することを知っておく必要があります – JavaApprentis

+0

@JavaApprentis - 詳細を教えてください..? – Sean

関連する問題