2016-06-13 11 views
0

Also habe ich schon einige Zeit mit C++ herumgespielt, mit verschiedenen Büchern und Web-Tutorials.SetPixel und mehrere Pixel C++ winapi

und jetzt bin ich zu Grafiken gekommen. derzeit in WinApi.

Ich habe ein Fenster, in das ich Text, Bilder oder Pixel male.

Aber das Malen vieler Pixel mit SetPixels ist einfach zu langsam.

Snippet von meinem Code:

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); 
} 

jetzt, das funktioniert gut, aber die // einige schwere PIXEL (derzeit kommentiert off) nimmt viel von der Geschwindigkeit auf. dann habe ich gehört, du kannst das Bild sperren und die Bisse manipulieren.

Ich kann einfach nicht meinen Kopf herumkommen? Ich möchte (für das Beispiel, das ist), ein 100 von 100 Feld an der x, y mit einzelnen Pixeln ausfüllen, während alle kostspieligen Anruffunktionen zu vermeiden.

Ich habe versucht, [https://msdn.microsoft.com/en-us/library/5ey6h79d(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-2]

Und viele andere Versionen derselben. aber ich kann nicht scheinen, ich zu arbeiten ..

hat jemand eine Idee?

mein voller Arbeits Code ist hier:

#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

Mit 'SetDIBits' und' GetDIBits' können Sie Pixeldaten aus Bitmaps als Teil des Arbeitsspeichers ändern und lesen, statt über mehrere API-Aufrufe pro Pixel. Dies ist wahrscheinlich das, wonach Sie suchen (es sei denn, Sie sind bereit, über GDI hinauszugehen). https://msdn.microsoft.com/en-us/library/windows/desktop/dd162973(v=vs.85).aspx –

+0

Danke, ich habe es ausprobiert, aber es scheint nicht zu helfen. – JavaApprentis

Antwort

0

Wenn Sie gerade schauen, um ein Rechteck zu zeichnen/Quadrat, dann können Sie FillRect, dies zu tun.

+0

Ich weiß, aber nein. Ich möchte viele Pixel einzeln manipulieren (als SetPixels()) Das Beispiel verwendet einfach 100 zu 100 Box, um es einfach zu machen, die Position von 10.000 einzelnen Pixel zu programmieren, in späteren Gebrauch wird es am Ende eine Reihe von Standalone sein Pixel, die sich bewegen können. aber zuerst muss ich wissen, um die Grafiken schneller zu manipulieren als setPixel – JavaApprentis

+0

@JavaApprentis - kümmern sich um ..? – Sean

Verwandte Themen