SOL9 Sample: Direct3D11FullScreenWithColorChooser

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * Direct3D11FullScreenWithColorChooser.cpp 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// 2016/01/16
// 2017/01/28 Updated to use ModuleFileName class and caught macro.

#pragma warning(disable : 4005) 
#pragma warning(disable : 4838) 

#define COMMONCONTROLS_V6
#include <sol/SystemMetrics.h>

#include <sol/ColorChooser.h>
#include <sol/PushButton.h>

#include <sol/direct3d11/DirectX3D11FullScreen.h>
#include <sol/dxgi/DirectXGISwapChain.h>
#include <sol/dxgi/DXGISwapChainDesc.h>

#include <sol/direct3d11/Direct3D11RenderTargetView.h>
#include <sol/direct3d11/Direct3D11DepthStencilView.h>

#include <sol/direct3d11/Direct3D11Texture2D.h>
#include <sol/direct3d11/D3D11Texture2DDesc.h>
#include <sol/direct3d11/D3D11DepthStencilViewDesc.h>

#include <sol/directx/Direct2D1Factory.h>
#include <sol/directx/Direct2D1RenderTarget.h>
#include <sol/directx/Direct2D1SolidColorBrush.h>
#include <sol/directx/DirectWriteFactory.h> 
#include <sol/directx/DirectWriteTextFormat.h>
#include <sol/dxgi/DirectXGISurface.h>

#include "resource.h"

namespace SOL {
  
class MainView :public DirectX3D11FullScreen {
private:
  
  SmartPtr<Direct3D11RenderTargetView>  renderTargetView;
  SmartPtr<Direct3D11DepthStencilView>  depthStencilView;

  SmartPtr<Direct2D1SolidColorBrush>    solidColorBrush;
  SmartPtr<DirectXGISurface>            dxgiSurface;
  SmartPtr<Direct2D1Factory>            d2d1Factory;
  SmartPtr<Direct2D1RenderTarget>       d2d1RenderTarget;
  SmartPtr<DirectWriteFactory>          writeFactory;
  SmartPtr<DirectWriteTextFormat>       textFormat;
  SmartPtr<ColorChooser>                chooser;
  SmartPtr< PushButton>                  quitButton;
  static const int CONTROL_AREA_WIDTH = 300;
  static const int MARGIN = 2;
  
  D2D1_COLOR_F                 color;

public:
   DirectXGISwapChain* getSwapChain()
   {
     return swapChain;
   }
  
public:
  void deleteViews()
  {
    renderTargetView = NULL;
    depthStencilView = NULL;
  }

  virtual void createViews()
  {
    int width = 0;
    int height = 0;
    validateClientSize(width, height);
    
    try {

      Direct3D11Device*   d3d11Device  = getD3D11Device();
      Direct3D11ImmediateContext* d3d11ImmediateContext = getD3D11ImmediateContext();
      
      DirectXGISwapChain* swapChain = getSwapChain();
      //if (d3dDevice && swapChain) {
      d3d11ImmediateContext ->setOMRenderTargets(0, NULL, NULL);

      //1 Create an instance of Direct3D11RenderTargetView
      Direct3D11Texture2D renderTargetViewTexture(*swapChain); ; 

      renderTargetView = new Direct3D11RenderTargetView(*d3d11Device, renderTargetViewTexture, NULL);

      //2 Create a temporary depthDesc(D3D11Texture2DDesc).
      D3D11Texture2DDesc depthDesc;
      depthDesc.width(width);
      depthDesc.height(height);
      depthDesc.mipLevels(1);
      depthDesc.arraySize(1);
      depthDesc.format(DXGI_FORMAT_D32_FLOAT);
      depthDesc.sampleDescCount(1);
      depthDesc.sampleDescQuality(0);
      depthDesc.usage(D3D11_USAGE_DEFAULT);
      depthDesc.bindFlags(D3D11_BIND_DEPTH_STENCIL);

      //3 Create a temporary depthStencilTexture(Direct3D11Texture2D) from texture2DDesc.
      Direct3D11Texture2D depthStencilTexute(*d3d11Device, depthDesc); 

      //4 Create a temporary depthStencilViewDesc(D3D11DepthStencilViewDesc) 
      D3D11DepthStencilViewDesc depthStencilViewDesc(DXGI_FORMAT_D32_FLOAT, D3D11_DSV_DIMENSION_TEXTURE2D);

      //5 Create an instance of Direct3DDepthStencilView from depthStencilTexture and depthStencilViewDesc
      depthStencilView = new Direct3D11DepthStencilView(*d3d11Device, depthStencilTexute, depthStencilViewDesc);


      ID3D11RenderTargetView* targets[1];
      targets[0]= *renderTargetView; 
      //6 Set renderTargetView and depthStencilView to id3d11Device
      d3d11ImmediateContext ->setOMRenderTargets(1, targets, *depthStencilView);
      //}
    } catch (Exception& ex) {
      caught(ex);
    }
  }
  
  //virtual void initialize()
  virtual void initialize()
  {
    try {      
      Direct3D11Device* d3d11Device = getD3D11Device();

      //1 Create rendarTargetView and depthStencilView.
      createViews();

      
      //3 Create the quitButton.
      Args ar;
      quitButton = new PushButton(this, _T("Quit"), ar);
      quitButton -> addCallback(XmNactivateCallback, this,
        (Callback)&MainView::doQuit, NULL);
    
      //4 Create the colorChooser.
      ar.reset();
      ar.set(XmNstyle, WS_VISIBLE);
      chooser = new ColorChooser(this, NULL, ar);
      addEventHandler(WM_COLORCHOOSER_PICKED, this,
        (Handler)&MainView::picked, NULL);
//
      DirectXGISwapChain* swapChain = getSwapChain();

      // 2 Create an instance of DirectXGISurface;
      dxgiSurface = new DirectXGISurface(*swapChain);

      d2d1Factory = new Direct2D1Factory();

      FLOAT dpiX = 0.0f;
      FLOAT dpiY = 0.0f;
      d2d1Factory->getDesktopDpi(&dpiX, &dpiY);

      D2D1_RENDER_TARGET_PROPERTIES props =D2D1::RenderTargetProperties(
                D2D1_RENDER_TARGET_TYPE_DEFAULT,
                D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
                dpiX,
                dpiY
                );
      // 3 Create an instance of Direct2D1RenderTarget.
      d2d1RenderTarget = new Direct2D1RenderTarget(*d2d1Factory, *dxgiSurface, &props);

      // 4 Create an instance DirectWriterFactory.
      writeFactory = new DirectWriteFactory();
        
      // 5 Create a red solidColorBrush.
      solidColorBrush   = new Direct2D1SolidColorBrush(*d2d1RenderTarget, 
                      color);

      // 6 Create an instance DirectWriterTextFormat.
      textFormat   = new DirectWriteTextFormat(*writeFactory,
                  L"Gabriola",
                  NULL,
                  DWRITE_FONT_WEIGHT_NORMAL,
                  DWRITE_FONT_STYLE_ITALIC,
                  DWRITE_FONT_STRETCH_NORMAL,
                  50.0f,  
                  L"");      

      textFormat -> setTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
      textFormat -> setParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

      
    } catch (Exception& ex) {
      caught(ex);
    }
  }
  
  // Draw a wchar_t string on the d2d1RenderTarget.
  void drawText(const wchar_t* text)
  {
      try {
        d2d1RenderTarget -> beginDraw();

        d2d1RenderTarget -> setTransform(D2D1::Matrix3x2F::Identity());
        d2d1RenderTarget -> clear(D2D1::ColorF(D2D1::ColorF::Navy));

        auto size = d2d1RenderTarget->getSize();
        auto rectangle = D2D1::RectF(0.0f, 0.0f, size.width, size.height);

        d2d1RenderTarget -> drawText(
            text,
            wcslen(text),
            *textFormat,
            rectangle,
            *solidColorBrush);
        d2d1RenderTarget -> endDraw();
        
      } catch (Exception& ex) {
        caught(ex);
      }
  }

  virtual void display()
  {
    try {
      Direct3D11Device*  d311Device = getD3D11Device();
      DirectXGISwapChain* swapChain = getSwapChain();
      Direct3D11ImmediateContext* d3d11ImmediateContext = getD3D11ImmediateContext();
      
      if (renderTargetView && depthStencilView) {
        d3d11ImmediateContext -> clear(*renderTargetView, XMColor(0.0f, 0.1f, 0.2f, 0.0f));
        d3d11ImmediateContext -> clear(*depthStencilView);
  
        const wchar_t* text =
          L"There is a tide in the affairs of men, Which taken at the flood,\n"
          L"leads on to fortune. Omitted, all the voyage of their life is bound\n" 
          L"in shallows and in miseries. On such a full sea are we now afloat. \n"
          L"And we must take the current when it serves, or lose our ventures.\n\n"
            L"Shakespeare ";
        drawText(text);
      }
      swapChain -> present();

    } catch (Exception& ex) {
      caught(ex);
    }
  }

  long picked(Event& event)
  {
    COLORREF rgb = (COLORREF)event.getLParam();
    BYTE r = GetRValue(rgb);
    BYTE g = GetGValue(rgb);
    BYTE b = GetBValue(rgb);
    
    float rf = (float)r/(float)0xff;
    float gf = (float)g/(float)0xff;
    float bf = (float)b/(float)0xff;
    
    color =  D2D1::ColorF(D2D1::ColorF(rf, gf, bf, 1.0f));
    solidColorBrush -> setColor(color);
    invalidateAll();
    update();
    
    return 0L;
  }
  
  virtual void doQuit(Action& event)
  {
      swapChain ->setFullscreenState(FALSE, NULL);
      Action action;
      exit(action); 
  }
  
  virtual void keyDown(Event& event)
  {
    WPARAM wparam = event.getWParam();
    if (wparam == VK_ESCAPE) {
      DirectXGISwapChain* swapChain = getSwapChain();
      swapChain ->setFullscreenState(FALSE, NULL);
      Action action;
      exit(action); 
    }
  }

public:
  /**
   * Constructor
   */
  MainView(Application& applet, const TCHAR* name, Args& args)
  :DirectX3D11FullScreen(applet, name,
                 args.set(XmNstyle, (ulong)WS_CLIPCHILDREN) ),
  color( D2D1::ColorF(D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f)) )
  {
    postResizeRequest(); 
  }

public:
  ~MainView()
  {
  }
  
  virtual void resize(int width, int height)
  {
    Direct3D11Device*   device = getD3D11Device();
    DirectXGISwapChain* swapChain = getSwapChain();
    Direct3D11ImmediateContext*  d3d11ImmediateContext = getD3D11ImmediateContext();

    if (device           == NULL ||
        swapChain        == NULL ||
        renderTargetView == NULL ||
        depthStencilView == NULL ||
        quitButton       == NULL ||
        chooser          == NULL) {
        return ;
    }
    
    try {
      int cw = 0;
      int ch = 0;

      if (chooser) {
        cw = chooser->get(XmNwidth);
        ch = chooser->get(XmNheight);
        chooser -> reshape(width - cw-10, 10, cw, ch);
      
        if (quitButton) {
          quitButton -> reshape(width -150, 10 + ch + 30, 120, 30);  
        }
      }

      d3d11ImmediateContext ->setOMRenderTargets(0, NULL, NULL);
      // 1 Delete already existing rendarTargetView and depthStencilView.
      deleteViews();

      // 2 ResizeBuffers swapChain(IDXGISwapChain)
      swapChain -> resizeBuffers(width, height); 

      // 3 Call setNoCopyBits to display the colorChooser and quiButton in the fullScreen mode. 
      setNoCopyBits();
      
      // 4 Recreate rendarTargetView and depthStencilView.
      createViews();
      
      // 5 SetViewPort
      setViewPort(width, height);
      
    } catch (Exception& ex) {
      caught(ex);
    }
  }  
};

}


//////////////////////////////////////////////
//
void  Main(int argc, TCHAR** argv)
{
  ModuleFileName module(argv[0]);
  const TCHAR* appClass =  module.getAppName(); 
  try {    
    Application applet(appClass, argc, argv);

     SystemMetrics metrics;
    int width  = metrics.fullScreenWidth();
    int height = metrics.fullScreenHeight();
    
    const int EXTRA_SIZE = 200;

    Args args;
    args.set(XmNx,  0);
    args.set(XmNy,  0);
    
    args.set(XmNwidth,  width  + EXTRA_SIZE);
    args.set(XmNheight, height + EXTRA_SIZE);
    MainView mainv(applet, appClass, args);
    
    mainv.realize();

    applet.run();
  } catch (Exception& ex) {
    caught(ex);
  }
}


Last modified: 1 Feb 2017

Copyright (c) 2017 Antillia.com ALL RIGHTS RESERVED.