Click to See Complete Forum and Search --> : The easiest way of getting a pixel from a D3D Window.


arva
January 29th, 2010, 03:32 PM
Hi, guys I've been searching the Internet for a fast way of pixel analyzing. I have to get about 10000 pixels from a game window every 0,5 second and check if some of that pixels are blue. I tried GDI but it comed to that I had wait 9 seconds for comparsion of 60000 pixels!(the code of program below)-I need at least two screenshots in one second. Finally I get to know that D3D-GDI interactions are very poor. So here is my question: what is the simplest way of doing this comparision? I know one way but maybe there is something easier.

My "one way":
Hooking Direct3D9::Present or EndScene in the game
Reading out the back buffer and writing the pixel data to a shared memory mapped file
Reading said pixel data from my external app and rendering it to a Direct3D surface.

The code:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Some.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"


#include <windows.h>

#include <stdio.h>

#include <winuser.h>

#include <windowsx.h>

#include "fstream.h"

//#include <mmsystem.h>


String dir;

String czas;

String data;

int b=0;

int s=0;

TColor * m=new TColor(RGB(0,0,0));
TCanvas &PulpitCanvas = *new TCanvas();
Graphics::TBitmap *bitmap = new Graphics::TBitmap;
COLORREF k[116][114];
HWND Wnd;

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{

b++;




if(b>100) return;

bitmap->Canvas->CopyRect(Rect(0, 0, bitmap->Width, bitmap->Height), &PulpitCanvas, Rect(0, 0, bitmap->Width, bitmap->Height));


for(int i=0; i<116; i++)
{
for(int j=0; j<114; j++)
{
if(bitmap->Canvas->Pixels[i][j]==*m);
if(bitmap->Canvas->Pixels[i][j]==*m);
if(bitmap->Canvas->Pixels[i][j]==*m);
if(bitmap->Canvas->Pixels[i][j]==*m);
if(bitmap->Canvas->Pixels[i][j]==*m);
}
}
try
{
dir = "";
dir = dir + b+ ".bmp";
//zapisujemy do pliku
bitmap->SaveToFile(dir);
//ReleaseDC(0, PulpitCanvas.Handle);
}
catch(...)

{

}

}




//---------------------------------------------------------------------------


void __fastcall TForm1::FormCreate(TObject *Sender)
{
Wnd=FindWindow(NULL,"WINDOW");
if(Wnd==0) {MessageBox(0,"Ddint find the window!",0,0);}
PulpitCanvas.Handle = GetDC(Wnd);
bitmap->Width = 800;//Screen->Width;
bitmap->Height = 600;//Screen->Height;
}
//---------------------------------------------------------------------------

Mike Harnad
February 1st, 2010, 07:52 AM
Sounds like you might be spendinhg too much time on I/O management for accessing the buffer. I'm not sure if this will help, but, check out the technique (http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c6345/) I used to capture a bitmap to a surface for debugging. And, maybe, here (http://doc.51windows.net/Directx9_SDK/?url=/Directx9_SDK/graphics/reference/d3d/interfaces/idirect3dsurface9/_idirect3dsurface9.htm) for some added info.