directdraw的多画面显示rgb

// showpicDlg.cpp : 实现文件

//

#include "stdafx.h"

#include "showpic.h"

#include "showpicDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog

{

public:

 CAboutDlg();

// 对话框数据

 enum { IDD = IDD_ABOUTBOX };

 protected:

 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现

protected:

 DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

 CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

 

// CshowpicDlg 对话框

 

 

CshowpicDlg::CshowpicDlg(CWnd* pParent /*=NULL*/)

 : CDialog(CshowpicDlg::IDD, pParent)

{

 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CshowpicDlg::DoDataExchange(CDataExchange* pDX)

{

 CDialog::DoDataExchange(pDX);

 DDX_Control(pDX, IDC_SCREEN, m_screen);

}

BEGIN_MESSAGE_MAP(CshowpicDlg, CDialog)

 ON_WM_SYSCOMMAND()

 ON_WM_PAINT()

 ON_WM_QUERYDRAGICON()

 //}}AFX_MSG_MAP

 ON_BN_CLICKED(IDC_BUTTON1, &CshowpicDlg::OnBnClickedButton1)

 ON_BN_CLICKED(IDC_BUTTON2, &CshowpicDlg::OnBnClickedButton2)

 ON_WM_TIMER()

END_MESSAGE_MAP()

 

// CshowpicDlg 消息处理程序

BOOL CshowpicDlg::OnInitDialog()

{

 CDialog::OnInitDialog();

 // 将“关于...”菜单项添加到系统菜单中。

 // IDM_ABOUTBOX 必须在系统命令范围内。

 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);

 if (pSysMenu != NULL)

 {

  CString strAboutMenu;

  strAboutMenu.LoadString(IDS_ABOUTBOX);

  if (!strAboutMenu.IsEmpty())

  {

   pSysMenu->AppendMenu(MF_SEPARATOR);

   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

  }

 }

 // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动

 //  执行此操作

 SetIcon(m_hIcon, TRUE);   // 设置大图标

 SetIcon(m_hIcon, FALSE);  // 设置小图标

 // TODO: 在此添加额外的初始化代码

 m_screen.SetWindowPos(&CWnd::wndBottom,0,0,960,720, SWP_NOMOVE | SWP_SHOWWINDOW);

 return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

}

void CshowpicDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

 if ((nID & 0xFFF0) == IDM_ABOUTBOX)

 {

  CAboutDlg dlgAbout;

  dlgAbout.DoModal();

 }

 else

 {

  CDialog::OnSysCommand(nID, lParam);

 }

}

// 如果向对话框添加最小化按钮,则需要下面的代码

//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,

//  这将由框架自动完成。

void CshowpicDlg::OnPaint()

{

 if (IsIconic())

 {

  CPaintDC dc(this); // 用于绘制的设备上下文

  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

  // 使图标在工作矩形中居中

  int cxIcon = GetSystemMetrics(SM_CXICON);

  int cyIcon = GetSystemMetrics(SM_CYICON);

  CRect rect;

  GetClientRect(&rect);

  int x = (rect.Width() - cxIcon + 1) / 2;

  int y = (rect.Height() - cyIcon + 1) / 2;

  // 绘制图标

  dc.DrawIcon(x, y, m_hIcon);

 }

 else

 {

  CDialog::OnPaint();

 }

}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。

//

HCURSOR CshowpicDlg::OnQueryDragIcon()

{

 return static_cast<HCURSOR>(m_hIcon);

}

BYTE *buf[6];

CBitmap m_bitmap;

void CshowpicDlg::OnBnClickedButton1()

{

 // TODO: 在此添加控件通知处理程序代码

 for(int i=0;i<6;i++)

 {

  HBITMAP m_hBitmap;//位图句柄

  BITMAP bm;//存放位图信息的结构

  CString strFilename,str;

  CFileDialog openBox(TRUE,NULL,_T(""),OFN_HIDEREADONLY,_T("bmp(*.bmp)|*.bmp|ALLFiles(*.*)|*.*||"),NULL);

  openBox.m_ofn.lpstrTitle=_T("打开数据文件640*480_bmp");

  INT_PTR nResult = openBox.DoModal();

  // 如果文件打开则准备播放

  if (nResult == IDOK)

  {

   strFilename=openBox.GetPathName();

  }

  else

  {

   return;

  }

  strFilename.ReleaseBuffer();

  str =strFilename;

  m_hBitmap = (HBITMAP)::LoadImage(NULL,str,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);   //装载位图

  if(m_bitmap.m_hObject)

   m_bitmap.DeleteObject();

  m_bitmap.Attach(m_hBitmap);//将句柄与CBitmap关联起来

  m_bitmap.GetBitmap(&bm);

  int  height = bm.bmHeight;//图像的宽高

  int  width = bm.bmWidth;

  int  widthBytes=bm.bmWidthBytes;//图像一行数据所占的字节数

  

  int size=height*widthBytes;

  buf[i]=new BYTE[size];

  m_bitmap.GetBitmapBits(size,buf[i]);//得到RGB数据

 }

}

#include <ddraw.h>

#pragma comment (lib,"ddraw.lib")

#pragma comment (lib,"dxguid.lib")

LPDIRECTDRAW         lpdd=NULL;

LPDIRECTDRAW7        lpdd7=NULL;

LPDIRECTDRAWSURFACE7 lpddsback;

LPDIRECTDRAWSURFACE7 lpddsprimary=NULL;

LPDIRECTDRAWSURFACE7 lpddsmypage[6];

LPDIRECTDRAWPALETTE  lpddpal=NULL;

DDSURFACEDESC2       ddsd;

LPDIRECTDRAWCLIPPER  lpDDClipper = NULL;

//

#define  _RGB32BIT(a,r,g,b)  ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))

//#define  SCREEN_WIDTH  640

//#define  SCREEN_HEIGHT 480

RECT rcRectSrc;

RECT rcRectDest;

int   index_y = 0, index_x = 0;

int height,width,widthBytes;

int R, G, B;

int SCREEN_WIDTH,SCREEN_HEIGHT;

HWND main_window_handle;

void CshowpicDlg::OnBnClickedButton2()

{

 // TODO: 在此添加控件通知处理程序代码

 height=width=widthBytes=0;

 main_window_handle = m_screen.GetSafeHwnd();

 if(DD_OK!=(DirectDrawCreate(NULL, &lpdd, NULL)))

 {

  return ;

 }

 //获取DIRECTDRAW7 接口

    if(DD_OK != (lpdd->QueryInterface(IID_IDirectDraw7,(LPVOID*)&lpdd7)))

 {

  return ;

 }

 // set the cooperative level for full-screen mode

 if(DD_OK != lpdd7->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL))

 {

  return ;

 }

 

 // set the display mode to 640x480x256

#if 0 //设置分辨率

    if(DD_OK!=(lpdd7->SetDisplayMode(800,600,32,0,0)))

 {  

  AfxMessageBox("dsf");

  return ;

 }

#endif

 // clear ddsd and set size

 memset(&ddsd,0,sizeof(ddsd));

 ddsd.dwSize = sizeof(ddsd);

 

 // enable valid fields

 ddsd.dwFlags=DDSD_CAPS;

 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

 // create the primary surface

 

 /* 

 ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;

 if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback)))

 {

  return -1;

 }

 */

 

 if(DD_OK!=(lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL)))

 {

  return ;

 }

 

 // 创建裁剪器

 if (FAILED(lpdd7->CreateClipper(0, &lpDDClipper, NULL)))

  return ; 

 // 与窗口工作区关联

 if (FAILED(lpDDClipper->SetHWnd(0, main_window_handle)))

 {

  lpDDClipper->Release();

  return ;

 } 

 

 if (FAILED(lpddsprimary->SetClipper(lpDDClipper)))

 {

  lpDDClipper->Release();

  return ;

 }

 {

  SCREEN_WIDTH = 640 ;SCREEN_HEIGHT = 480;

 }

 //

 memset(&ddsd,0,sizeof(ddsd));

 ddsd.dwSize = sizeof(ddsd);

 

 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

 ddsd.dwWidth = SCREEN_WIDTH;

 ddsd.dwHeight = SCREEN_HEIGHT;

 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; 

 //

 

    SetTimer(1,1000,NULL);

 return; //执行成功

}

int index=0;

void CshowpicDlg::OnTimer(UINT_PTR nIDEvent)

{

 // TODO: 在此添加消息处理程序代码和/或调用默认值

 int tmp = 0;

    for(int i=0;i<6;i++)

 {

  if(DD_OK!=(lpdd7->CreateSurface(&ddsd, &lpddsmypage[i], NULL)))

  {

   return ;

  }

  POINT p;

  

  p.x = 0; p.y = 0;

  m_screen.ClientToScreen(&p);

  tmp = (i+index)%6;

 // m_screen.GetClientRect(&rcRectDest);

        if(i==5)

      {rcRectDest.left = 0;  rcRectDest.top=0;  rcRectDest.right = 640;  rcRectDest.bottom = 480;}

  else if(i==4)

   {rcRectDest.left = 640;  rcRectDest.top=0;  rcRectDest.right = 960;  rcRectDest.bottom = 240;}

  else if(i==3)

   {rcRectDest.left = 640;  rcRectDest.top=240;  rcRectDest.right = 960;  rcRectDest.bottom = 480;}

  else if(i==2)

   {rcRectDest.left = 640;  rcRectDest.top=480;  rcRectDest.right = 960;  rcRectDest.bottom = 720;}

  else if(i==1)

   {rcRectDest.left = 320;  rcRectDest.top=480;  rcRectDest.right = 640;  rcRectDest.bottom = 720;}

  else if(i==0)

   {rcRectDest.left = 0;  rcRectDest.top=480;  rcRectDest.right = 320;  rcRectDest.bottom = 720;}

  OffsetRect(&rcRectDest, p.x, p.y);

  

  SetRect(&rcRectSrc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

  /////////////////////////////////////////////////////////////

 

  if(DD_OK != lpddsmypage[i]->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR,NULL))

  {

   return ;

  }

  

  DWORD *bmp_buffer = (DWORD *)ddsd.lpSurface;

  

  memcpy(bmp_buffer,buf[tmp],SCREEN_WIDTH*SCREEN_HEIGHT*4);

  if(DD_OK != lpddsmypage[i]->Unlock(NULL))

  {

   return ;

  }

  if(DD_OK != lpddsprimary->Blt( &rcRectDest, lpddsmypage[i], &rcRectSrc, DDBLT_WAIT, NULL))

  {

   return ;

  }

  if(lpddsmypage)

  {

   lpddsmypage[i]->Release();

   lpddsmypage[i]=NULL;

  }

 }

 index++;

 CDialog::OnTimer(nIDEvent);

}v

时间: 2024-08-01 20:00:57

directdraw的多画面显示rgb的相关文章

如何使用DirectDraw直接显示RGB、YUV视频数据(播放yuv)

#include "draw.h" void CTest100Dlg::OnButton1() { // TODO: Add your control notification handler code here CloseShowBMP(); InitDrawBMP(m_screen.GetSafeHwnd(),m_sel.GetCurSel());} void CTest100Dlg::OnButton2() { CString strFilename,str; CFileDial

初次接触:DirectDraw

第六章 初次接触:DirectDraw 本章,你将初次接触DirectX中最重要的组件:DirectDraw.DirectDraw可能是DirectX中最强大的技术,因为其贯穿着2D图形绘制同时其帧缓存层也是DirectX3D的基础.当然,DirectX8.0中DirectDraw已经完全集成到了DirectX3D里面.此外,如果你对DirectDraw深有了解,那将拥有创建任何DOS16/32类型的图形化程序的能力.DirectDraw是理解众多DirectX自身概念的钥匙.所以,听仔细了.

DirectDraw 与 DirectInput 的游戏编程体验

我想关于这个主题的文章,不算少,但也不算太多.但大多是分别介绍 DirectDraw 与 DirectInput,而并没有将其结合起来,也许你会问:"分开与合并起来并没有本质区别啊!".其实的确没有本质区别,但那样使那些最初对游戏编程报有极大热情的爱好者感到非常失望,因为这其中的一个并不能完全满足他们的要求,并且使其感到巨大的阻力,从而失去信心.所以本文将 DirectDraw 与 DirectInput结合起来去讲一个主题就是"游戏编程",请注意是"游戏

最简单的视音频播放示例7:SDL2播放RGB/YUV

本文记录SDL播放视频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API用于播放视频:封装了DirectSound这类的API用于播放音频.因为SDL的编写目的就是简化视音频播放的开发难度,所以使用SDL播放视频(YUV/RGB)和音频(PCM)数据非常的容易.下文记录一下使用SDL播放视频数据的技术.   SDL简介 SDL(Simple DirectMedia La

高级DirectDraw

使用高彩模式 上一章中说了可以用16位的色彩深度,但是16位的色彩深度的数据表示模式可以有两种:Alpha.5.5.5(or X.5.5.5) 和 5.6.5(这是16位色彩最常用的).对于使用哪种16位的色彩模式这个是由硬件决定的,我们不能决定.但是我们可以查询,然后按照硬件支持的模式来填写. 我们可以调用方法IDIRECTDRAWSURFACE7::GetPixelFormat(),同时这个函数需要一个LPDDPIXELFORMAT的结构,其中的dwFlags 和 dwRGBBitCount

DirectDraw读书笔记

DirectDraw对象 DirectDraw对象是DirectDraw应用程序的核心.它是你在建立DirectDraw应用程序时所要创建的第一个对象,再用它来创建所有其它相关的对象.通过调用DirectDrawCreate函数可以创建一个DirectDraw对象.DirectDraw 对象通过IDirectDraw(移动版本仅支持这个),IDirectDraw2,和IDirectDraw4接口为开发者提供其函数性. DirectDrawSurface对象 DirectDrawSurface对象

最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)

上一篇文章记录了GDI播放视频的技术.打算接下来写两篇文章记录Direct3D(简称D3D)播放视频的技术.Direct3D应该Windows下最常用的播放视频的技术.实际上视频播放只是Direct3D的"副业",它主要用于3D游戏制作.当前主流的游戏几乎都是使用Direct3D制作的,例如<地下城与勇士>,<穿越火线>,<英雄联盟>,<魔兽世界>,<QQ飞车>等等.使用Direct3D可以用两种方式渲染视频:Surface和

使用DirectDraw直接显示YUV视频数据

最近在编写一个进行视频播放的ActiveX控件,工作已经接近尾声,现将其中显示YUV数据的使用DirectDraw的一些经验总结如下:(解码部分不是我编写的,我负责从网络接收数据,将数据传给解码器,并将解码得到的YUV数据进行显示,最初在显示部分我是先将YUV数据转换为RGB数据,再以位图的形式显示到屏幕上,但发现CPU占用率比较高,后来改用DirectDraw直接显示YUV数据) 1.在DirectDraw中创建YUV表面   与一般表面不同的是,创建YUV表面时需要指定象素格式,并指定YUV

Converting Between YUV and RGB

It is frequently necessary to convert between YUV pixel formats (used by the JPEG and MPEG compression methods) and RGB format (used by many hardware manufacturers.) The following formulas show how to compute a pixel's value in one format from the pi