|
Aaron Stubbendieck wrote: I keep meaning to learn DX and I'd appreciate taking a look at what you've got to get me started.
What I wrote doesn't use directx but it is still lightning fast and could be optimited further. Basically I needed it for some image recognition/ai stuff I wanted to display for debugging purposes. The dotnet functions were way too slow on my old laptop.
I will post the code from my graphics module in the next post. If you would like to see it used in an example project I wrote that uses the module please let me know your email and I will send you a zip of my project.
Here's how it works:
1) ReadStream takes a filestream as an argument and reads the pixel and header data into pixelarray and header. If you are not planning to modify an existing bitmap just make an empty one of the dimensions you need to serve this purpose.
2) GetPixel & SetPixel are pretty strait forward. They read or write data into the pixelarray but the results of this are not immediately displayed (there's a reason for this).
3) WriteStream takes the data in the 2 dimensional array and produces a bitmap memorystream.
4) WriteToPictureBox is like WriteStream but it will display the results in a picturebox you specify.
WriteStream & WriteToPictureBox should not be called until after you write all the data because this is by far the slowest of the functions. So if you are drawing a graph call Setpixel for all of the dots and when you are done call WriteToPictureBox to display it. Don't call it after every SetPixel.
This is probably one of the reasons that my code is so fast. It avoids certain repeated calculation that the dotnet methods probably have to use since some of them refresh after every draw.
Please note the example only works for 24 bit bitmaps you will have to modify the code if you want to use other ones. Also pixelarray data starts at position 1x1, I skipped the 0 indexes of the array because I prefer base 1 arrays and I wrote this code for myself originally.
|
|
|
|
|
Please note the example only works for 24 bit bitmaps you will have to modify the code if you want to use other ones. Also pixelarray data starts at position 1x1, I skipped the 0 indexes of the array because I prefer base 1 arrays and I wrote this code for myself originally.
Public Module GraphicsIO
Private Header() As Byte
Private HeaderLen As Integer
Private PixelArray(,) As PixelStr
Public Width As Integer
Public Height As Integer
'reads the data from a filestream into the header and pixelarray
Public Sub ReadStream(ByVal fstream As IO.FileStream)
Dim bytearray() As Byte, len As Integer, rowoffset As Integer, offset As Integer
Dim n As Integer, x As Integer, y As Integer, padding As Integer
Dim remainder As Integer
len = fstream.Length
ReDim bytearray(len)
fstream.Read(bytearray, 0, len) 'copies file stream into an array
'this extracts header information
HeaderLen = System.BitConverter.ToInt32(bytearray, 10)
Width = System.BitConverter.ToInt32(bytearray, 18)
Height = System.BitConverter.ToInt32(bytearray, 22)
ReDim PixelArray(Width, Height)
'this copies the header information into its own array
ReDim Header(HeaderLen)
For n = 0 To (HeaderLen - 1)
Header(n) = bytearray(n)
Next
'each row in a bitmap file must be a multiple of 4
'If not empty padding bytes are added
'This takes that into account and calculates how many padding bytes were added
remainder = (Width * 3) Mod 4
If remainder > 0 Then
padding = 4 - remainder
Else
padding = 0
End If
'this extracts the data and puts it into a 2d array of structures representing the colors
For y = 1 To Height
rowoffset = ((y - 1) * ((3 * Width) + padding))
offset = rowoffset + HeaderLen
For x = 1 To Width
'bitmaps store colors in reverse order: blue, green, red
PixelArray(x, y).B = bytearray(offset) 'blue
offset += 1
PixelArray(x, y).G = bytearray(offset) 'green
offset += 1
PixelArray(x, y).R = bytearray(offset) 'red
offset += 1
Next
Next
End Sub
'displays the image on the picturebox
Public Sub WriteToPictureBox(ByVal pictbox As PictureBox)
Dim myimage As Image, mstream As New IO.MemoryStream
mstream = GraphicsIO.WriteStream(mstream)
myimage = Image.FromStream(mstream)
pictbox.Image = myimage
Form1.GloImage = myimage
End Sub
'creates a file stream from the pixelarray
Public Function WriteStream(ByVal mstream As IO.MemoryStream)
Dim rowoffset As Integer, offset As Integer, bytearray() As Byte, len As Integer
Dim n As Integer, x As Integer, y As Integer, padding As Integer
Dim remainder As Integer
'Each row in a bitmap file must be a multiple of 4
'If not empty padding bytes are added
'This takes that into account and calculates how many padding bytes to add
remainder = (Width * 3) Mod 4
If remainder > 0 Then
padding = 4 - remainder
Else
padding = 0
End If
len = HeaderLen + (Height * ((Width * 3) + padding))
ReDim bytearray(len)
'copies the header into the byte array
For n = 0 To (HeaderLen - 1)
bytearray(n) = Header(n)
Next
'this extracts the data from a 2d array of structures representing the colors
For y = 1 To Height
rowoffset = ((y - 1) * ((3 * Width) + padding))
offset = rowoffset + HeaderLen
For x = 1 To Width
'bitmaps store colors in reverse order: blue, green, red
bytearray(offset) = PixelArray(x, y).B
offset += 1
bytearray(offset) = PixelArray(x, y).G
offset += 1
bytearray(offset) = PixelArray(x, y).R
offset += 1
Next
Next
'copies the bytearray into the memory stream
mstream.Write(bytearray, 0, len)
Return mstream
End Function
'reads a pixel
Public Sub GetPixel(ByVal x As Integer, ByVal y As Integer, ByRef r As Integer, ByRef g As Integer, ByRef b As Integer)
Dim pixel As PixelStr
pixel = PixelArray(x, y)
r = pixel.R
g = pixel.G
b = pixel.B
End Sub
'reads a pixel
Public Function GetPixel(ByVal x As Integer, ByVal y As Integer) As PixelStr
Dim pixel As PixelStr
pixel = PixelArray(x, y)
Return pixel
End Function
'writes a pixel
Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, ByVal r As Integer, ByVal g As Integer, ByVal b As Integer)
PixelArray(x, y).R = r
PixelArray(x, y).G = g
PixelArray(x, y).B = b
End Sub
Public Structure PixelStr
Public R As Byte 'red
Public G As Byte 'green
Public B As Byte 'blue
End Structure
End Module
|
|
|
|
|
1. C# does automatic array-bounds checking which slows it down. Try putting your plotting code inside an unsafe { } block, which may speed it up.
2. Your code is executed in a pipeline, where several consecutive instructions may be in various stages of execution at any one point. When you branch (i.e. go back to the top of your inner loop) it messes this up.
Drawing multiple points in your inner loop (called "loop unrolling") allows your program to take advantage of pipelining. E.g. instead of
while ()
{
draw point n
}
Try:
while ()
{
draw point n
draw point n+1
draw point n+2
draw point n+3
}
3. You can write a faster plotting function in C++ using GDI and put it in a DLL. Then you can call this DLL from C#.
|
|
|
|
|
I got a marginal increase in performance with the unsafe block, I'll try unrolling my loop and if that doesn't work we'll get down and dirty with GDI.
Thanks
modified 12-Jul-20 21:01pm.
|
|
|
|
|
Hi,
before you make drastic changes, you might consider showing some of your actual code, so CPians get a chance of offering specific advice about it.
|
|
|
|
|
I know this is late comings but you might want to look at OpenGL via the Tao wrapper. Drawing point is stupid simple and can be optimized multiple ways.
ARon
|
|
|
|
|
Hello all,
I'm very new in DirectX programming (Actually I started 2 hours ago!!! ). I'm reading a great ebook about DirectX in VC++ and I'm trying to convert that codes into C# but I couldn't find the reference of Direct3DCreate9 method. My ebook includes d3d9.h in its code, I found d3d9.dll in system32 folder but I couldn't add that as a reference.
1 - Can I use this method in C#?
If yes,
2 - What is its reference?
Thank you in advance.
When you're alone in the Dark, Fear will protect you...
|
|
|
|
|
In C#, you are using the NET Framework version of DirectX. I don't think you actually reference the DirectX DLLs, you just add the using namespace declarations at the beginning of your source version:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectDraw;
And, the path to the DirectX libraries must be known to the compiler. I program in C++, which allows you to use either managed or unmanaged versions of DirectX; the syntax is slightly different for C++ and C#. There are numerous tutorials for beginning DirectX using the NET Framework on the internet. The DirectX 9 SDK has numerous examples and that's probably the best place to start. Also, there are numerous C# DirectX tutorials right here at Codeproject.
A good introductory article on mamaged DirectX is : HERE at MSDN Magazine[^]
|
|
|
|
|
Hi Baltoro, Thanks for reply.
Actually I searched all Microsoft.Direct3D namespace (include all its classes and namespaces) for Direct3DCreate9 but I couldn't find anything! I couldn't find something useful in Google too.
Maybe I should use some other methods in C#. Currently searching for that. If you have any reference or anything, I'll be glad to hear that.
However thanks
When you're alone in the Dark, Fear will protect you...
|
|
|
|
|
|
Thanks a lot, you made my day.
Reading your links is in progress...
Life is 5: 3 me, 1 you.
|
|
|
|
|
I highly recommend avoiding Managed DirectX as its now effectively a legacy API. XNA is the replacement, but if the limitations and general "xboxyness" of it bother you, then I suggest you use SlimDX.
SlimDX has a bunch of examples - and you can also follow the official C++ API to a certain extent to get a rough idea of what is going on. Its a much better managed directx wrapper than the original.
|
|
|
|
|
hi..
I'm using Splitcontainer and drawing a bitmap on the panel2 of the Splitcontainer, now i need to capture the panel2 waveform and save it to bit map.. so pls help me how to capture and save the waveform (panel2 contents).
if possible provide me some reference links..
thanks in advance
vinay
|
|
|
|
|
i wana to load a JPG file and render it on gui,but no any result however...and every time it prints: Render PIC SUC!! and i cannot resolve the problem,my code is:
void CTestLoadJPEGDlg::OnBtnNew()
{
CFileDialog cFileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "File(*.JPEG;*.JPG;*.BMP)|*.JPEG;*.JPG;*.BMP||", NULL);
if (IDOK == cFileDlg.DoModal())
{
CString strPicFilePath;
strPicFilePath = cFileDlg.GetPathName();
TRACE("the file path:%s\n",strPicFilePath);
CFile cFile(strPicFilePath,CFile::modeRead);
int nPicFileBufSize = cFile.GetLength();
HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, nPicFileBufSize);
if(NULL != hGlobal)
{
LPVOID lpData = NULL;
lpData = ::GlobalLock(hGlobal);
if (NULL != lpData)
{
cFile.ReadHuge(lpData, nPicFileBufSize);
GlobalUnlock(hGlobal);
IStream *pIstream = NULL;
CreateStreamOnHGlobal(hGlobal,TRUE,&pIstream);
if (NULL != pIstream)
{
HRESULT hr = ::OleLoadPicture(pIstream, nPicFileBufSize, TRUE, IID_IPicture, (LPVOID*)&m_iPicture);
if (FAILED(hr))
{
TRACE("OleLoadPicture failed!!\n");
goto CLOSEFILE;
}
pIstream->Release();
}
}
else
{
TRACE("lpData=NULL!!!\n");
goto CLOSEFILE;
}
}
else
{
TRACE("hGlobal=NULL!!!\n");
goto CLOSEFILE;
}
if (NULL != m_iPicture)
{
CSize sizeInHimetric;
HRESULT hr = NULL;
hr = m_iPicture->get_Width(&sizeInHimetric.cx);
if (FAILED(hr))
{
TRACE("get_Width failed!!\n");
goto CLOSEFILE;
}
hr = m_iPicture->get_Height(&sizeInHimetric.cy);
if (FAILED(hr))
{
TRACE("get_Height failed!!\n");
goto CLOSEFILE;
}
HDC hDCScreen = ::GetDC(NULL);
int nPixelsPerInchX = ::GetDeviceCaps(hDCScreen, LOGPIXELSX);
int nPixelsPerInchY = ::GetDeviceCaps(hDCScreen, LOGPIXELSY);
::ReleaseDC(NULL, hDCScreen);
CSize sizeInPixel;
sizeInPixel.cx = MulDiv(sizeInHimetric.cx, nPixelsPerInchX, HIMETRIC_PER_INCH);
sizeInPixel.cy = MulDiv(sizeInHimetric.cy, nPixelsPerInchY, HIMETRIC_PER_INCH);
m_szPicPixel = sizeInPixel;
m_szPicHimetric = sizeInHimetric;
DrawPic();
}
CLOSEFILE:
cFile.Close();
}
return;
}
void CTestLoadJPEGDlg::DrawPic()
{
if (NULL == m_iPicture)
{
TRACE("m_iPicture=NULL!!\n");
return;
}
CRect rect;
m_staticPicRect.GetWindowRect(rect);
CPoint ptTopLeft;
ptTopLeft = rect.TopLeft();
float fZoomRate = 1.0;
int xSrcPos = (int)(ptTopLeft.x / fZoomRate);
int ySrcPos = (int)(ptTopLeft.y / fZoomRate);
int cxSrcWidth = (int)(rect.Width() / fZoomRate);
int cySrcHeight = (int)(rect.Height() / fZoomRate);
CDC* dc = GetDC();
int nPixelsPerInchX = ::GetDeviceCaps(*dc, LOGPIXELSX);
int nPixelsPerInchY = ::GetDeviceCaps(*dc, LOGPIXELSY);
int xHimetric = MulDiv(xSrcPos, HIMETRIC_PER_INCH, nPixelsPerInchX);
int yHimetric = MulDiv(ySrcPos, HIMETRIC_PER_INCH, nPixelsPerInchY);
int wHimetric = MulDiv(cxSrcWidth, HIMETRIC_PER_INCH, nPixelsPerInchX);
int hHimetric = MulDiv(cySrcHeight, HIMETRIC_PER_INCH, nPixelsPerInchY);
HRESULT hr = m_iPicture->Render(dc->GetSafeHdc(), rect.left, rect.top, rect.Width(), rect.Height(),
xHimetric, yHimetric, wHimetric, hHimetric, NULL);
if (FAILED(hr))
{
TRACE("Render failed!!\n");
return;
}
TRACE("Render PIC SUC!!\n");
}
thks again!
|
|
|
|
|
It appears that you are trying to use the code from: Load JPEG and Transparant GIF Picture Files From a Resource in 3 Lines Code[^]
What exactly are you trying to do?
It also appears that you are pasting code from various sources, just to get it to work.
You should probably rethink your approach,...if you are merely trying to display a JPG image, there are MUCH simpler ways of doing it. This has the advantage that you will actually clearly understand how the code operates. If you are a novice at this kind of thing, this is important.
Does your application have to be MFC? Which operating system are you compiling for? Are you actually using a resource from your executable?
On the other hand, if you want to use the code as is, I would start off by reading the HRESULT error code returned by IPicture->Render and OleLoadPicture. Look in Winerror.h. HRESULTS[^]. The FAILED or SUCCEEDED Macros don't tell you much.
Maybe this MSDN article will help: Displaying a JPEG in your MFC Application[^].
The Source Code accompanying that article is here: Source Classes[^]
There are plenty of problems with your code, as it is.
|
|
|
|
|
thanku very much. i got it.
|
|
|
|
|
Here's a much simpler start:
#include <atlimage.h>
...
CFileDialog cFileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("File(*.JPEG;*.JPG;*.BMP;*.PNG;*.TIF;*.GIF)|*.JPEG;*.JPG;*.BMP;*.PNG;*.TIF;*.GIF||"), NULL);
if (IDOK == cFileDlg.DoModal())
{
CString strPicFilePath = cFileDlg.GetPathName();
CImage SrcBitmap;
SrcBitmap.Load(strPicFilePath);
CClientDC dc(this);
SrcBitmap.Draw(dc, 0, 0);
SrcBitmap.Destroy();
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi!
I am new in directx. I want to create water ripple whose center will be the mouse clicking point.Is it possible? I am using VC++ and DirectX9 SDK
Please help....
|
|
|
|
|
http://developer.download.nvidia.com/SDK/9.5/Samples/samples.html[^] Look for Vertex Texture Fetch Water
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
John Andrew Holmes "It is well to remember that the entire universe, with one trifling exception, is composed of others."
|
|
|
|
|
Hi,
I'm learning how Silverlight/WPFapplication/Direct3D interact between themselves...
Sorry but I haven't a lot experience about this issues, so my question is:
- IS IT POSSIBLE, WITH SILVERLIGHT, TO RENDER WPF FILES IN A DIREC3D/WIN32 APPLICATION? HOW CAN DO IT?
Thanks a lots,
bye,
Carmelo.
|
|
|
|
|
Hello
I have a user control that has an image property which holds a metafile. This metafile is drawn to screen using DrawImage().
I wish to save the current image being displayed to disk as either a jpeg or a bitmap. I have written the code below which first creates a temporary bitmap and then draw the metafile to it.
I then attempt to save this bitmap to disk. However I always get the error "A generic error occured in GDI+."
Ive searched the messageboards and google but found nothing that fixs my problem - any ideas...?
Cheers
Bitmap saveImage = new Bitmap(m_canvasWidth, m_canvasHeight);
Graphics g = Graphics.FromImage(saveImage);
g.DrawImage(this.zoomAndScrollPictureBox.Image, new Point(0,0));
g.Dispose();
try
{
saveImage.Save(savePath,System.Drawing.Imaging.ImageFormat.Bmp);
}
catch (Exception saveEx)
{
MessageBox.Show(saveEx.Message);
}
|
|
|
|
|
OK, I've worked out what I had forgot to do. Prior to the code snippet shown I had used a saveFileDialog to select the file to save to. To test the file was not null I used a stream and the dialogs openfile method.
All good so far, however I never closed the stream (bad in itself) and so I was in affect trying to save to a file that was in use. Closing the stream solves the problem.
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((saveStream = saveFileDialog1.OpenFile()) != null)
{
saveStream.Close();
savePath = saveFileDialog1.FileName;
}
}
saveFileDialog1.Dispose();
|
|
|
|
|
I'm working on an artificial intelligence program of my own and I am planning to use OpenCV to capture the input data from digital cameras/webcams. I want to use 2 of them and have them in a stable mount that will keep there relative orientation the same so I can obtain 3d information. My question is does anybody know of such a camera that I can buy (preferably one that doesn't cost a mint)? Also is there anything in OpenCv that will allow simple audio capture like OpenCv does video capture?
thanks,
Mike
|
|
|
|
|
I have a friend who's using two of these Logitech[^] cameras on his robot. He has stereo image capture working with OpenCV running on a Beagle Board[^] under Linux. They're not the cheapest webcam but a lot cheaper than trying to buy a commercial stereo camera rig.
OpenCV has no audio capability but it certainly doesn't preclude using other audio capture libraries.
You didn't mention what OS you'll be using. The OpenCV frame caputure routines in the HighGUI library have some problems on Vista but are fine under XP. The simple streaming cam routines based on DirectShow work on Vista, however. I'm investigating a fix I found and am looking into other capture routines.
Your silly assed, irrelevant opinion has been duly noted. Now take it elsewhere!
|
|
|
|
|
Thank you for your help.
Tim Craig wrote: I have a friend who's using two of these Logitech[^] cameras on his robot. He has stereo image capture working with OpenCV running on a Beagle Board[^] under Linux. They're not the cheapest webcam but a lot cheaper than trying to buy a commercial stereo camera rig.
I was thinking of doing the same thing but I couldn't find any webcams with bolts or holes on them that would allow me to securely mount it to a piece of wood or metal or something. How did your friend secure the camera to the robot so the cameras don't shake or move (I see it has a flap on it that could possibly be used but that flap is on a swivel it looks like)?
You're right most of the ready made things are really expensive but I guess I should also mention I found this thing http://www.slipperybrick.com/2008/10/minoru-robot-webcam-for-3d-video-chat/[^] after posting the previous message but it won't be released for another month it looks like and all the info on it is pretty vague.
Tim Craig wrote: You didn't mention what OS you'll be using. The OpenCV frame caputure routines in the HighGUI library have some problems on Vista but are fine under XP. The simple streaming cam routines based on DirectShow work on Vista, however. I'm investigating a fix I found and am looking into other capture routines.
Fortunately I'm using XP.
Thanks again for your help,
Mike
|
|
|
|
|