Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

bartiss

Fast pixel plotting?

This topic is 5492 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can anybody tell me how to draw pixels much faster than using SetPixel? I know you can use either assembler or direct memory access, but I don''t know how to implement it! I tried some assembler functions from one book, but compiler isn''t able to make the file. I don''t understand errors because I don''t understand Assembler Can anybody tell me where to find such functions (under C++ DirectX) or send me one? Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Well, why would you want to plot pixels? What are you trying to do? There isn't ayn example where plotting pixels the only way to do it.

Plus, you write in "Assembly" and the code is parsed by the "assembler" (I think).

[edited by - PlayGGY on November 28, 2003 12:20:46 PM]

Share this post


Link to post
Share on other sites
What are you using?
DirectDraw, Direct3D?

Drawing a single pixel is useless unless you want to draw single points on a map, stars or some rudimentary particle.

Share this post


Link to post
Share on other sites
quote:
Well, why would you want to plot pixels?

Because not everyone is doing 3D stuff. If he''s doing 2D effects, then he''ll want to plot pixels. Or, maybe he''s interested in making his own graphics library.

Writing in assembly won''t make a difference, really, unless we''re talking about using string instructions as a substutite for, say, memcpy—and even that is a moot point when you enable intrinsic functions in your compiler. So, the fastest starting point is to lock your buffer. This gives you a pointer to its memory. You''ll need to take note of its stride, because you''ll use that in your x/y --> offset calculation. Once you''ve done that, dereference the pointer or access it as an array. Or, use it with memcpy and memset to fill or copy entire blocks. After locking the surface, you could always access that memory using assembly functions. No matter what, don''t forget to unlock your buffer when you''re done.

Share this post


Link to post
Share on other sites
Even if he is doing 2D stuff, he could use texture quads. Maybe he for some reason he wanted to render 1 pixel all alone, but even then rendering Direct3D points would be faster.

[edited by - PlayGGY on November 28, 2003 8:27:13 PM]

[edited by - PlayGGY on November 28, 2003 8:27:46 PM]

Share this post


Link to post
Share on other sites
If you''re using DirectDraw, here''s a decent one I used a long time ago:

Here''s the class definition so you know what it''s using:

class S3DDDSURFACE
{
protected:
LPDIRECTDRAWSURFACE7 m_Surface;
S3Dlong m_VideoPitch;
LPVOID m_VideoStart;
S3Dboolean m_IsColorKeyed;
S3Dint m_SurfaceLocked;
DDSURFACEDESC2 m_SurfaceDescription;
//--

public:
S3DDDSURFACE();
~S3DDDSURFACE();
//--

LPDIRECTDRAWSURFACE7 GetSurface(S3Dvoid);
S3Dboolean GetIsColorKeyed(S3Dvoid);
//--

S3DERROR CreateSurface(LPDIRECTDRAWSURFACE7 Surface);
S3DERROR CreateSurface(LPDIRECTDRAW7 DDraw, DDSURFACEDESC2* SurfaceDescriptin);
S3Dvoid CleanupSurface(S3Dvoid);
//--

S3DERROR DrawBitmap(S3Dcrptr Filename, S3Dulong Width, S3Dulong Height);
S3DERROR DrawBitmap(HBITMAP BMPHandle, S3Dulong X, S3Dulong Y, S3Dulong Width, S3Dulong Height);
S3DERROR DrawText(HFONT FontHandle, S3Dcrptr Text, S3Dulong X, S3Dulong Y, COLORREF Color);
//--

S3Dint LockSurface(S3Dvoid);
S3Dvoid UnlockSurface(S3Dvoid);
S3Dulong AutoGrabColorKey(S3Dvoid);
S3Dvoid GrayScaleSurface(S3Dvoid);
S3DERROR SetColorKey(S3Dulong ColorKey);
S3Dulong ConvertGDIColor(COLORREF Color);
S3DERROR GetBitMaskInfo(S3Dulong Mask, S3Dulong* retShift, S3Dulong* retBits);
//--

S3Dvoid GetPixelXL(S3Dint X, S3Dint Y, S3Duchar &retRed, S3Duchar &retGreen, S3Duchar &retBlue);
S3Dvoid SetPixelXL(S3Dint X, S3Dint Y, S3Duchar Red, S3Duchar Green, S3Duchar Blue);
S3Dvoid GetPixelXL_LITE(S3Dint X, S3Dint Y, S3Duchar &retRed, S3Duchar &retGreen, S3Duchar &retBlue);
S3Dvoid SetPixelXL_LITE(S3Dint X, S3Dint Y, S3Duchar Red, S3Duchar Green, S3Duchar Blue);
S3Dvoid DrawRectangleXL(S3Dint X, S3Dint Y, S3Dint Width, S3Dint Height, COLORREF Color);
S3Dvoid DrawRectangleXL_LITE(S3Dint X, S3Dint Y, S3Dint Width, S3Dint Height, COLORREF Color);
};


Here''s the Lock/Unlock surface functions:

S3Dint S3DDDSURFACE::LockSurface(S3Dvoid)
{
if(this->m_Surface == NULL)
{
return 0;
}
//--

if(this->m_Surface->Lock(NULL, &this->m_SurfaceDescription, DDLOCK_WAIT, NULL) != DD_OK)
{
return 0;
}
//--

this->m_VideoPitch = this->m_SurfaceDescription.lPitch;
this->m_VideoStart = this->m_SurfaceDescription.lpSurface;
this->m_SurfaceLocked = 1;
return 1;
}

S3Dvoid S3DDDSURFACE::UnlockSurface(S3Dvoid)
{
if(this->m_Surface == NULL || !this->m_SurfaceLocked)
{
return;
}
//--

this->m_Surface->Unlock(NULL);
this->m_VideoPitch = 0;
this->m_VideoStart = 0;
this->m_SurfaceLocked = 0;
}


And here''s the Set/Get Pixel functions:

S3Dvoid S3DDDSURFACE::GetPixelXL_LITE(S3Dint X, S3Dint Y, S3Duchar &retRed, S3Duchar &retGreen, S3Duchar &retBlue)
{
if((this->m_Surface == NULL) | (!this->m_SurfaceLocked))
{
return;
}
S3Duchar Red;
S3Duchar Green;
S3Duchar Blue;
//--

S3Dlong Pitch = this->m_VideoPitch;
LPVOID Start = this->m_VideoStart;
S3Dint BPP = this->m_SurfaceDescription.ddpfPixelFormat.dwRGBBitCount;
//--

if((BPP == 16) | (BPP == 24))
{
_asm
{
PUSH ESI
PUSHF
MOV EAX, Y
MUL Pitch
MOV EBX, EAX
MOV EAX, X
MOV CX, 3
MUL CX
ADD EAX, EBX
MOV ESI, Start
ADD ESI, EAX
MOV AL, [ESI]
INC ESI
MOV DH, [ESI]
INC ESI
MOV DL, [ESI]
MOV Blue, AL
MOV Green, DH
MOV Red, DL
POPF
POP ESI
}
}
else
{
if(BPP == 32)
{
_asm
{
PUSH ESI
PUSHF
MOV EAX, Y
MUL Pitch
MOV EBX, EAX
MOV EAX, X
MOV CX, 4
MUL CX
ADD EAX, EBX
MOV ESI, Start
ADD ESI, EAX
MOV AL, [ESI]
INC ESI
MOV DH, [ESI]
INC ESI
MOV DL, [ESI]
MOV Blue, AL
MOV Green, DH
MOV Red, DL
POPF
POP ESI
}
}
}
retRed = Red;
retGreen = Green;
retBlue = Blue;
}
//--

S3Dvoid S3DDDSURFACE::SetPixelXL_LITE(S3Dint X, S3Dint Y, S3Duchar Red, S3Duchar Green, S3Duchar Blue)
{
if((this->m_Surface == NULL) | (!this->m_SurfaceLocked))
{
return;
}
//--

S3Dlong Pitch = this->m_VideoPitch;
LPVOID Start = this->m_VideoStart;
S3Dint BPP = this->m_SurfaceDescription.ddpfPixelFormat.dwRGBBitCount;
//--

if((BPP == 16) | (BPP == 24))
{
_asm
{
PUSH ESI
PUSHF
MOV EAX, Y
MUL Pitch
MOV EBX, EAX
MOV EAX, X
MOV CX, 3
MUL CX
ADD EAX, EBX
MOV ESI, Start
ADD ESI, EAX
MOV AL, Blue
MOV DH, Green
MOV DL, Red
MOV [ESI], AL
INC ESI
MOV [ESI], DH
INC ESI
MOV [ESI], DL
POPF
POP ESI
}
}
else
{
if(BPP == 32)
{
_asm
{
PUSH ESI
PUSHF
MOV EAX, Y
MUL Pitch
MOV EBX, EAX
MOV EAX, X
MOV CX, 4
MUL CX
ADD EAX, EBX
MOV ESI, Start
ADD ESI, EAX
MOV AL, Blue
MOV DH, Green
MOV DL, Red
MOV [ESI], AL
INC ESI
MOV [ESI], DH
INC ESI
MOV [ESI], DL
POPF
POP ESI
}
}
}
}


Now just call the this:
LockSurface();
SetPixelXL_LITE(50, 50, 255, 0, 0);
UnlockSurface();

Remember I said this was old, so there might be a faster way. That should give you some ideas though.

Best of luck,

-UltimaX-

"You wished for a white christmas... Now go shovel your wishes!"

Share this post


Link to post
Share on other sites
Some of the formatting got messed up O_°
Oh well, if you have any problems let me know. One of use should be able to help you

-UltimaX-

"You wished for a white christmas... Now go shovel your wishes!"

Share this post


Link to post
Share on other sites
For me, being able to plot single pixels is very important. The absence of a drawPixel function in the standard Java API was the result of a terrible design choice. I use single pixels for graphics programming such as fractals and particle physics and other things.

[edited by - pUnkInner on November 29, 2003 3:38:37 AM]

Share this post


Link to post
Share on other sites
It always drives me insane when I see people say "There is no reason for you to do x" when someone asks how they should do x. There is no way you can know that, it''s not your project. I can thnk of about a billion reasons why you''d want to plot pixels without resorting to texture quads.

There''s an article in the articles section I wrote some years ago on this subject, called "Bit Depth Independant Pixel Plotting in DirectDraw" or something like that. It was written for DirectDraw, but the concepts should apply to a D3D texture surface in an equivalent manner.

Share this post


Link to post
Share on other sites
quote:
Original post by RonHiler
It always drives me insane when I see people say "There is no reason for you to do x" when someone asks how they should do x. There is no way you can know that, it''s not your project. I can thnk of about a billion reasons why you''d want to plot pixels without resorting to texture quads.

There''s an article in the articles section I wrote some years ago on this subject, called "Bit Depth Independant Pixel Plotting in DirectDraw" or something like that. It was written for DirectDraw, but the concepts should apply to a D3D texture surface in an equivalent manner.


Actually, I gree with the first thing you said. I figured he was probably trying to do sprites, and texture quads would be faster. I was just trying to help him, thats all.

And, by the way, you could still use a point list to render single pixels, if you want.

But, if he wants to render pixels a fast way just because he thinks it would be a cool thing to try (I have done that), then I am sorry that I tried giving him a faster method.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!