그래서 저는 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);
}
지금,이 잘 작동하지만 (현재 오프 주석)을 // 일부 HEAVY 픽셀 이 속도를 많이 차지합니다. 그때 나는 당신이 이미지를 잠그고 물기를 조작 할 수 있다고 들었다.
나는 그저 내 머리를 감당할 수 없습니까? 모든 고비용의 전화 기능을 피하면서 개별 픽셀로 x, y에서 100x100 필드를 채우고 싶습니다 (표본의 경우).
그리고 많은 다른 버전을 시도했습니다. 하지만 난 일할 수없는 것 같아요.
아무도 아이디어가 있습니까?
내 전체 작업 코드는 여기에 있습니다 :
#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;
}
}
'SetDIBits'와'GetDIBits'는 픽셀 단위로 여러 API를 호출하는 대신 Bitmap에서 픽셀 데이터를 수정하여 메모리 덩어리로 읽을 수있게합니다. 이것은 아마도 당신이 찾고있는 것입니다 (GDI를 넘어서서 기꺼이 움직이게하지 않는 한). https://msdn.microsoft.com/en-us/library/windows/desktop/dd162973(v=vs.85).aspx –
고마워, 그것을 시도했지만 도움이되지 않는 것 같습니다. – JavaApprentis