|
|

楼主 |
发表于 2006-6-1 08:55:00
|
显示全部楼层
Re:[求助]如何用DIRECTX9 绘制DIB与设备无关的位图?
感谢楼上的回复!
楼上问题,给DIB创建DC,是可以的!
下面是我的测试代码,是用OPENGL渲染出3D图形,把图形绘制在DIB上,然后以流的形式发给WEB客户端,在WEB中显示3D的图象.
OPENGL部分的代码
(C++ CLR)
namespace OpenGLLib {
public ref class OpenGLClass
{
private :
HDC _dc;
HWND _hwnd;
HGLRC _hglrc;
HBITMAP hBitmap;
public :
OpenGLClass(System::IntPtr hwnd) //此处传入的hwnd,是一个BITMAP,而不是WIN窗体
{
_hwnd = (HWND)(hwnd.ToInt32());
_dc = ::GetDC(_hwnd);
if(SetPixelFormat(_dc) == 0)
return;
_hglrc = wglCreateContext(_dc);
wglMakeCurrent(_dc, _hglrc);
}
OpenGLClass()
{
}
~OpenGLClass()
{
wglMakeCurrent(NULL, NULL);
: eleteObject(hBitmap);
wglDeleteContext(_hglrc);
::ReleaseDC(_hwnd, _dc);
}
System::IntPtr InitBmp(int w, int h)
{
wglMakeCurrent(NULL, NULL);
_dc = ::CreateCompatibleDC(NULL); //创建空的DC
SetBmp(w, h);
::SelectObject(_dc, hBitmap);
//_hwnd = (HWND)(hBitmap);
//_dc = ::GetDC(_hwnd);
if(SetPixelFormat2(_dc) == 0)
return IntPtr::Zero;
_hglrc = wglCreateContext(_dc);
wglMakeCurrent(_dc, _hglrc);
return System::IntPtr(hBitmap);
}
System::IntPtr ResizeBmp(int w, int h)
{
//Resize(w, h);
SetBmp(w, h);
::SelectObject(_dc, hBitmap);
return System::IntPtr(hBitmap);
}
void SetBmp(int w, int h)
{
//::DeleteObject(hBitmap);
void * pBits;
BITMAPINFOHEADER *bmih = new BITMAPINFOHEADER();
bmih->biSize = sizeof (BITMAPINFOHEADER) ;
bmih->biWidth = w ;
bmih->biHeight = h ;
bmih->biPlanes = 1 ;
bmih->biBitCount = 24 ;
bmih->biCompression = BI_RGB ;
bmih->biSizeImage = 0 ;
bmih->biXPelsPerMeter = 0 ;
bmih->biYPelsPerMeter = 0 ;
bmih->biClrUsed = 0 ;
bmih->biClrImportant = 0 ;
hBitmap = CreateDIBSection (_dc, (BITMAPINFO *) bmih, DIB_PAL_COLORS, &pBits, NULL, 0) ;
free(bmih);
}
int SetPixelFormat(HDC hdc)
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int iPixelFormat;
if((iPixelFormat = ::ChoosePixelFormat(hdc, &pfd)) == 0)
return 0;
if(::SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)
return 0;
return 1;
}
int SetPixelFormat2(HDC hdc)
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_BITMAP |
PFD_SUPPORT_OPENGL |
PFD_SUPPORT_GDI,
PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int iPixelFormat;
if((iPixelFormat = ::ChoosePixelFormat(hdc, &pfd)) == 0)
return 0;
if(::SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)
return 0;
return 1;
}
void DrawObject(void);
void Resize(int w, int h)
{
glViewport(0, 0, w, h);
if(w <= h)
gluOrtho2D(0.0, 15.0, 0.0, 15.0 * (GLfloat)h / (GLfloat)w);
else
gluOrtho2D(0.0, 15.0 * (GLfloat)w / (GLfloat)h, 0.0, 15.0);
}
void Render()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*glBegin(GL_TRIANGLES);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(2.0, 3.0);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(12.0, 3.0);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(7.0, 12.0);
glEnd();*/
//DrawObject();
s
glFlush();
SwapBuffers(_dc);
}
void Render2()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*for(int i = 0; i < 10000; i++)
{*/
glBegin(GL_TRIANGLES);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(2.0, 2.0);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(10.0, 3.0);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(7.0, 12.0);
glEnd();
//DrawObject();
//}
glFlush();
//SwapBuffers(_dc);
}
};
}
以下是WEB部分的调用
(C#)
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
OpenGLLib.OpenGLClass gl;
IntPtr hbmp;
gl = new OpenGLLib.OpenGLClass();
hbmp = gl.InitBmp(300, 300);
gl.Resize(300, 300);
gl.Render();
Bitmap bmp = System.Drawing.Image.FromHbitmap(hbmp);
Graphics g = Graphics.FromImage(bmp);
//g.FillRectangle(new SolidBrush(Color.Red), 10, 10, 100, 100); //GDI+混合绘制
bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); //以流的方式把BITMAP绘制在WEB窗体上
}
}
|
|