Jump to content
  • Advertisement
Sign in to follow this  
yurixd

Problems with grey images

This topic is 4766 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

Hi guys! I have a big problem to get the data for grey images when i render to a surface create with CreateRenderTArget. By default, all codes I saw until know are for R5G6B5 format, but I want to use 16bits for grey images. SO, what can I do? When I change my backbuffer format and my Create render format to L16 the program compille but I always have problem of violation acces, when my program sets my transform matrix, if I don-t change, my program works, but the data I obtain is not what I want...! I'm using .png images... Someone can help me?? I don't know how to result the problem, and I need to transform the code below to 16bits grey color values..... Any help will be useful. Thanks d3dpp.AutoDepthStencilFormat = D3DFMT_D16; g_d3d_device->CreateRenderTarget(640, 480, D3DFMT_R5G6B5, D3DMULTISAMPLE_NONE,0,true,&pRenderSurface,NULL); hr=g_D3D->CheckDeviceType(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,D3DFMT_R5G6B5,D3DFMT_R5G6B5,FALSE); if(SUCCEEDED(hr)){ OutputDebugString("D3DFMT_R5G6B5\n"); return D3DFMT_R5G6B5; } D3DLOCKED_RECT lockedRect; DWORD *pBits = new DWORD [217*181]; DWORD m_pixelbytes; pRenderSurface->LockRect(&lockedRect,NULL,D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY); FILE *stream; stream = fopen( "fprintf.out", "w" ); pBits=(DWORD*)lockedRect.pBits; m_pixelbytes=lockedRect.Pitch/sizeof(DWORD); ; pRenderSurface->UnlockRect(); for (long x=0; x< 256; x++){ for (long y=0; y< 256; y++) fprintf(stream, "%ld ", pBits[m_pixelbytes*y+x]); fprintf (stream,"\n"); } fprintf(stream,"%ld",lockedRect.Pitch); fclose( stream );

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by yurixd
I have a big problem to get the data for grey images when i render to a surface create with CreateRenderTArget.

From looking at your code, you're just saving out a greyscale copy of your rendertarget - is that what you're after? or do you actually want the image (displayed on screen) to be greyscale as well?

Quote:
Original post by yurixd
When I change my backbuffer format and my Create render format to L16 the program compille but I always have problem of violation acces, when my program sets my transform matrix

Have you checked that your hardware supports an L16 back buffer / render target? if your hardware does not support it, it will fail. If it fails and you ignore it, you'll have an invalid pointer. If you try and use the invalid pointer (e.g. setting your transform matrix) then your app will die a horrible death via an access violation [smile]

You should be checking return codes using the FAILED( ... ) macro and either bailing or reporting any failed function calls.


Quote:
Original post by yurixd
DWORD *pBits = new DWORD [217*181];
DWORD m_pixelbytes;
pRenderSurface->LockRect(&lockedRect,NULL,D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY);

FILE *stream;
stream = fopen( "fprintf.out", "w" );
pBits=(DWORD*)lockedRect.pBits;
m_pixelbytes=lockedRect.Pitch/sizeof(DWORD); ;
pRenderSurface->UnlockRect();
for (long x=0; x< 256; x++){
for (long y=0; y< 256; y++)
fprintf(stream, "%ld ", pBits[m_pixelbytes*y+x]);
fprintf (stream,"\n");
}
fprintf(stream,"%ld",lockedRect.Pitch);
fclose( stream );


Right, there are a few things with the above fragment that could cause you problems.

Firstly, where does [217*181] for the pBits declaration come from? hardcoded values like this don't make sense [wink] and in this instance they don't seem to match up with anything else you've posted..?

Secondly, iterating through your array as you are *might* work, but you're not properly compensating for the pitch. For a 2n dimension you're usually okay, but theres no guarantee. Something like the following is safer:


for( each row )
{
for( each pixel in the row )
{
//Get the colour
this_colour = pBits[ Loop_index ];
}
//increment by the pitch to move onto the next row
pBits += pitch;
}



Thirdly, you're outputting to your file the DWORD element - this is the whole colour (assuming that it's a 32bit format, which is unwise). You need to perform some binary magic on it to get it's luminance. Extract the 3 colours (R,G,B) then average them for a trivial luminance calculation.

hth
Jack

Share this post


Link to post
Share on other sites
Thanks,
First, if I am using DEVICE_REF, does it matter if my backbuffer supports or no D16 format? If I use Device_HAL, it should be a problem but not with REF...isn-t it?

Secondly,
In fact, what I-m looking for is only to put a texture in a square after define four vertex, and be sure that the values written are what I want in grey values.
I have done it, but given R5G6B5 formats, and visualize them, but after if I get the values, they are not going to be in 16bits grey values

After I want to make some translation and rotation. And see many possibilites of interpolation. Translation and rotation, are not a problem, I got it easily, but always for colour images.

I have use a window, to see easily if my image is exactly I want to...but really I don-t care. I only want the values of a pixels of an image obtained like a texture. And operate with it.
So, I'm gonna try to put out the window, so backbuffer teoricly will not be a problem.
In any case, thansk for your help, and if you have any recommendation, it would be really helpful.
Thanks
Jesus

Share this post


Link to post
Share on other sites
In any case...I will write again for the new code...to know if you can help me. FOr the moment...i must work to have somethin clear and easy to understand!
Thanks a lot

Share this post


Link to post
Share on other sites
Quote:
Original post by yurixd
if I am using DEVICE_REF, does it matter if my backbuffer supports or no D16 format? If I use Device_HAL, it should be a problem but not with REF...isn-t it?

This is correct. You didn't mention in your OP that you were using REF though - in fact, your CheckDeviceType() call would indicate you were using HAL [smile]

Quote:
Original post by yurixd
After I want to make some translation and rotation. And see many possibilites of interpolation. Translation and rotation, are not a problem, I got it easily, but always for colour images.

The transform process is independent of the texturing units - so anything that works for a colour image will also work for a greyscale image.


A simple solution that I can think of would use a pixel shader to output a greyscale image from an RGB input. An alternative is that you *might* be able to use the D3DXFillTexture() or D3DXFillTextureTX() functions.

hth
Jack

Share this post


Link to post
Share on other sites

This question it would be easy for you...but not for me
IS it possible to create a device without define a backbuffer and a window?
Imagine that the only want is to operate with grey image data with the Graphic card, but I dont need to show it in a window and i don-t need a backbuffer, the only thing i want is to profit the credit cards performance to operate with images.

The only possibilitie i have thougth is to use a create render target, 4 vertex describing a square with the same dimensions to my image and load a texture in this square like my image. Then get the data and work with it.

There is any other possibilitie??

Therefore, I have tried to create a Device without define a parameters for my device, because I don-t want backbuffer and a HWND...but it makes me error.
How can I get it??
D3DPRESENT_PARAMETERS m_PresentParameters;
HRESULT hr;
//create Direct3D object
if((m_pDirect3DObject = Direct3DCreate9(D3D_SDK_VERSION)) == NULL){
FatalError("Direct3DCreate9() failed!");
m_bRunningD3D = false;
}

ZeroMemory(&m_PresentParameters,sizeof(m_PresentParameters));

if(FAILED(hr=m_pDirect3DObject->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,NULL,m_dwVertexProcessing,&m_PresentParameters,&m_pDirect3DDevice))){
FatalError("CreateDevice() failed!");
m_bRunningD3D = false;
}

The value returned by hr is 0x86c ... so I think bad specified.

Share this post


Link to post
Share on other sites
Hmm,

I'm pretty sure you can't create a device without a target to draw on - for the simple reason that D3D needs some sort of lifetime and message cycle to hook into.

However, you can probably target a very small window and never actually Present() to it, just do everything to an internal render target.

Although, from a theory point of view there is a problem.

You say you want to use D3D so you can leverage the power of the GPU - which is a good idea - but you're also wanting to do pixel-processing. If you want that sort of feature to be done entirely on the GPU you have two choices - the fixed function texture blending or the programmable pixel shaders route.

I'll have to admit that I'm not the best person at remembering all of the results/combinations for FF blending, but what you want can definitely be done using a pixel shader. If you're new to D3D, neither of them are easy.

I mention this, because your current system of locking/writing/unlocking the data will be done by the CPU - you're not going to be getting any advantage from the GPU for that [smile] In truth doing it that way would probably be slower than manually loading, processing and saving the data - especially if you aggressively optimized it.

hth
Jack

Share this post


Link to post
Share on other sites
So...what-s the difference between d3d and a pixel shader??

I thought is also directx 9!! To program a pixel shader is not with d3d??

CAn you tell me the difference and how to do it?? Your help is really helpful!
Any good tutorial to learn to program pixel shaders?

Thanks,
Jesus

Share this post


Link to post
Share on other sites
Quote:
Original post by yurixd
what-s the difference between d3d and a pixel shader??

It's not quite like that... a "Pixel Shader" is an advanced feature of "D3D" - instead of having Direct3D operate based on the properties/parameters you specify (e.g. the SetRenderState() calls) you can write your own program (in Assembly language or "HLSL" - High Level Shader Language) called a Pixel or Vertex Shader.

Quote:
Original post by yurixd
CAn you tell me the difference and how to do it??

If you pick the pixel shader route, something like this might work:
float4 weighted = in.Color * float4( 0.33, 0.34, 0.33, 1.0 );
float temp = weighted.x + weighted.y + weighted.z;
out.color = float4( temp, temp, temp, 1.0 );



I can't guarantee that'll work as I haven't tried it - but something like that should convert a colour image to greyscale using the GPU [smile].

Quote:
Original post by yurixd
Any good tutorial to learn to program pixel shaders?

I've not updated it recently, but I was writing up my findings here (resource list here) as part of my journal. Maybe you'll find the references useful.

hth
Jack

Share this post


Link to post
Share on other sites
I'm sorry, maybe was not a good idea to send you the code.
You must be busy.....
I only want to know why is not possible tu execute this instruction

hr=g_pd3dDevice->CreateRenderTarget(640,480,D3DFMT_L16,D3DMULTISAMPLE_NONE,0,true,&pRenderSurface,NULL);

I f I change D3DFMT_L16 to any other kind of backbuffer formats it works, but if not.....the rendertarget is not create. I know D3DFMT_L16 is not a backbuffer format but it must be some possibility to get my data in 16bitslumiannce if my input is this format. I'm sure...

But like I'm going to change my rendertarget, from my backbuffer to this rendertarger, i would like to have 16luminance bit as format...and don't need to transform my data :( Because for medical iamges, is many operations to transform it, and I lose precision.

Is the only think I need to know :(((

Thanks,

Jesus

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!