D3D D2D Interop on Windows 7 - c++-cli
I'm trying to use DWrite to draw text in my dx11 app but I'm having lot of problems, I shared resources beetween D3D10 Device and D3D11 Device because dx10 is capable to connect D3D with D2D, that's the code of my GraphicsDevice:
// File: GraphicsDevice.h
#pragma once
#ifndef _GRAPHICSDEVICE_H_
#define _GRAPHICSDEVICE_H_
#ifndef _DEFINES_H_
#include "Defines.h"
#endif
#ifndef _COLOR_H_
#include "Color.h"
#endif
#ifndef _UTILITIES_H_
#include "Utilities.h"
#endif
#ifndef _DWRITE_H_
#include "DWrite.h"
#endif
// Forward declaration
namespace BSGameFramework { ref class Game; }
using namespace BSGameFramework;
using namespace System;
namespace BSGameFramework
{
namespace Graphics
{
public ref class GraphicsDevice
{
public:
/// <summary>GraphicsDevice constructor.</summary>
/// <param name="game">The game wich the device has to work.</param>
GraphicsDevice(Game^ game);
virtual ~GraphicsDevice();
/// <summary>Clear the screen.</summary>
/// <param name="color">The color that the screen background will assume after clearing.</param>
void Clear(Color color);
/// <summary>Render on the screen.</summary>
void Render();
/// <summary>Set the full screen state.</summary>
void FullScreen(bool isFullScreen);
property Color BlendFactor
{
Color get()
{
return blendFactor_;
}
void set(Color blendFactor_)
{
blendFactor_ = BlendFactor;
}
}
property D3D_DRIVER_TYPE DriverType
{
D3D_DRIVER_TYPE get()
{
return driverType_;
}
}
property D3D_FEATURE_LEVEL FeatureLevel
{
D3D_FEATURE_LEVEL get()
{
return featureLevel_;
}
}
property ID3D11Device* D3DDevice
{
ID3D11Device* get()
{
return d3dDevice_;
}
}
property ID3D11DeviceContext* D3DContext
{
ID3D11DeviceContext* get()
{
return d3dContext_;
}
}
property ID3D10Device1* D3DDevice10_1
{
ID3D10Device1* get()
{
return d3dDevice10_1_;
}
}
property ID2D1Factory* D2DFactory
{
ID2D1Factory* get()
{
return d2dFactory_;
}
}
property ID2D1RenderTarget* D2DRenderTarget
{
ID2D1RenderTarget* get()
{
return d2dRenderTarget_;
}
}
property ID2D1SolidColorBrush* D2DSolidColorBrush
{
ID2D1SolidColorBrush* get()
{
return d2dSolidColorBrush_;
}
}
property IDWriteFactory* DWriteFactory
{
IDWriteFactory* get()
{
return dWriteFactory_;
}
}
property int WindowWidth
{
int get()
{
return GetWindowWidth();
}
}
property int WindowHeight
{
int get()
{
return GetWindowHeight();
}
}
property HWND Window
{
HWND get()
{
return GetWindow();
}
}
property int SafeTitleArea
{
int get()
{
return safeTitleArea_;
}
void set(int safeTitleArea)
{
safeTitleArea_ = safeTitleArea;
}
}
private:
void CreateD3D11Resources();
void CreateD3D10Resources(ID3D11Texture2D* d3d11Texture);
void CreateD2D1Resources(ID3D10Texture2D* d3d10Texture);
Game^ game_;
Color blendFactor_;
D3D_DRIVER_TYPE driverType_;
D3D_FEATURE_LEVEL featureLevel_;
int safeTitleArea_;
int GetWindowWidth();
int GetWindowHeight();
HWND GetWindow();
// Direct3D 11
ID3D11Device* d3dDevice_;
ID3D11DeviceContext* d3dContext_;
// Direct3D 10
ID3D10Device1* d3dDevice10_1_;
// Direct2D
ID2D1Factory* d2dFactory_;
ID2D1RenderTarget* d2dRenderTarget_;
ID2D1SolidColorBrush* d2dSolidColorBrush_;
// DirectWrite
IDWriteFactory* dWriteFactory_;
IDXGISwapChain* swapChain_;
ID3D11RenderTargetView* backBufferTarget_;
};
}
}
#endif
// FILE: GraphicsDevice.cpp
#include "GraphicsDevice.h"
#include "Game.h"
#include "GraphicsDeviceNativeWrapper.h"
using namespace BSGameFramework::Graphics;
using namespace BSGameFramework;
inline GraphicsDevice::GraphicsDevice(Game^ game) : driverType_( D3D_DRIVER_TYPE_NULL ), featureLevel_( D3D_FEATURE_LEVEL_11_0 ),
d3dDevice_( 0 ), d3dContext_( 0 ), swapChain_( 0 ), backBufferTarget_( 0 )
{
game_ = game;
BlendFactor = Color::White;
CreateD3D11Resources();
}
inline GraphicsDevice::~GraphicsDevice()
{
if (backBufferTarget_)
{
backBufferTarget_->Release();
}
if (swapChain_)
{
swapChain_->Release();
}
if (d3dContext_)
{
d3dContext_->Release();
}
if (d3dDevice_)
{
d3dDevice_->Release();
}
backBufferTarget_ = 0;
swapChain_ = 0;
d3dContext_ = 0;
d3dDevice_ = 0;
}
inline void GraphicsDevice::Clear(Color color)
{
if (d3dContext_ == 0)
{
return;
}
float clearColor[4];
Vec4 convertedColor = Utilities::ColorToVec4(color);
clearColor[0] = convertedColor.values[0];
clearColor[1] = convertedColor.values[1];
clearColor[2] = convertedColor.values[2];
clearColor[3] = convertedColor.values[3];
d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
}
inline void GraphicsDevice::Render()
{
swapChain_->Present(0, 0);
}
inline void GraphicsDevice::FullScreen(bool isFullScreen)
{
swapChain_->SetFullscreenState(isFullScreen, NULL);
}
inline int GraphicsDevice::GetWindowWidth()
{
return game_->WindowWidth;
}
inline int GraphicsDevice::GetWindowHeight()
{
return game_->WindowHeight;
}
inline HWND GraphicsDevice::GetWindow()
{
return game_->Window;
}
#pragma region CreateD3D11Resources
inline void GraphicsDevice::CreateD3D11Resources()
{
HRESULT result;
RECT dimensions;
GetClientRect(Window, &dimensions);
unsigned int width = dimensions.right - dimensions.left;
unsigned int height = dimensions.bottom - dimensions.top;
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 2;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = game_->Window;
swapChainDesc.Windowed = true;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
unsigned int creationFlags = 0;
#ifdef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
unsigned int driver = 0;
pin_ptr<IDXGISwapChain*> swapChainPointer;
swapChainPointer = &swapChain_;
pin_ptr<ID3D11Device*> d3dDevicePointer;
d3dDevicePointer = &d3dDevice_;
pin_ptr<D3D_FEATURE_LEVEL> featureLevelPointer;
featureLevelPointer = &featureLevel_;
pin_ptr<ID3D11DeviceContext*> d3dContextPointer;
d3dContextPointer = &d3dContext_;
for (driver = 0; driver < totalDriverTypes; ++driver)
{
result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0, creationFlags, featureLevels, totalFeatureLevels,
D3D11_SDK_VERSION, &swapChainDesc, swapChainPointer,
d3dDevicePointer, featureLevelPointer, d3dContextPointer);
if (SUCCEEDED(result))
{
driverType_ = driverTypes[driver];
break;
}
}
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the Direct3D device!");
return;
}
ID3D11Texture2D* backBufferTexture;
result = swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);
if (FAILED(result))
{
DXTRACE_MSG("Failed to get the swap chain back buffer!");
return;
}
pin_ptr<ID3D11RenderTargetView*> backBufferTargetPointer;
backBufferTargetPointer = &backBufferTarget_;
result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0, backBufferTargetPointer);
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the render target view!");
return;
}
d3dContext_->OMSetRenderTargets(1, backBufferTargetPointer, 0);
D3D11_VIEWPORT viewport;
viewport.Width = static_cast<float>(width);
viewport.Height = static_cast<float>(height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
d3dContext_->RSSetViewports(1, &viewport);
CreateD3D10Resources(backBufferTexture);
}
#pragma endregion
#pragma region CreateD3D10Resources
inline void GraphicsDevice::CreateD3D10Resources(ID3D11Texture2D* d3d11Texture)
{
//Load D3D10.DLL
HMODULE d3d10_1 = LoadLibrary("D3D10_1.dll");
// Get adapter of the current D3D11 device. Our D3D10 will run on the same adapter.
IDXGIDevice* dxgiDevice;
IDXGIAdapter* dxgiAdapter;
d3dDevice_->QueryInterface<IDXGIDevice>(&dxgiDevice);
dxgiDevice->GetAdapter(&dxgiAdapter);
SafeRelease<IDXGIDevice>(&dxgiDevice);
//Get address of the function D3D10CreateDevice1 dynamically.
typedef HRESULT (WINAPI* FN_D3D10CreateDevice1)(
IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software,
UINT Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, UINT SDKVersion, ID3D10Device1 **ppDevice );
FN_D3D10CreateDevice1 fnCreate = (FN_D3D10CreateDevice1)GetProcAddress(d3d10_1, "D3D10CreateDevice1");
//Call D3D10CreateDevice1 dynamically.
pin_ptr<ID3D10Device1*> d3dDevice10_1Ptr = &d3dDevice10_1_;
fnCreate(dxgiAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_DEBUG, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, d3dDevice10_1Ptr);
//Create a D3D10.1 render target texture and share it with our D3D11.
D3D10_TEXTURE2D_DESC tDesc;
tDesc.Width = game_->WindowWidth;
tDesc.Height = game_->WindowHeight;
tDesc.MipLevels = 1;
tDesc.ArraySize = 1;
tDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
tDesc.SampleDesc.Count = 1;
tDesc.SampleDesc.Quality = 0;
tDesc.Usage = D3D10_USAGE_DEFAULT;
//EVEN IF YOU WON'T USE AS SHADER RESOURCE, SET THIS BIND FLAGS:
tDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
tDesc.CPUAccessFlags = 0;
tDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED;
//Create the RT texture on D3D10
ID3D10Texture2D* texture;
d3dDevice10_1_->CreateTexture2D(&tDesc, NULL, &texture);
//Get DXGI Resource and retrieve the sharing handle.
IDXGISurface* dxgiSurface;
IDXGIResource* dxgiResource;
HANDLE shareHandle;
texture->QueryInterface<IDXGISurface>(&dxgiSurface);
dxgiSurface->QueryInterface<IDXGIResource>(&dxgiResource);
dxgiResource->GetSharedHandle(&shareHandle);
SafeRelease(&dxgiResource);
SafeRelease(&dxgiSurface);
//Call D3D 11 to open shared resource.
ID3D11Resource* d3d11Resource;
d3dDevice_->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource), (void**)&d3d11Resource);
d3d11Resource->QueryInterface<ID3D11Texture2D>(&d3d11Texture);
SafeRelease(&d3d11Resource);
if (d3d11Texture)
{
d3d11Texture->Release();
}
CreateD2D1Resources(texture);
}
#pragma endregion
#pragma region CreateD2D1Resources
inline void GraphicsDevice::CreateD2D1Resources(ID3D10Texture2D* d3d10Texture)
{
pin_ptr<ID2D1Factory*> d2dFactoryPtr = &d2dFactory_;
pin_ptr<IDWriteFactory*> dWriteFactoryPtr = &dWriteFactory_;
//pin_ptr<ID2D1HwndRenderTarget*> d2dRenderTargetPtr = &d2dRenderTarget_;
//pin_ptr<ID2D1SolidColorBrush*> D2DSolidColorBrushPtr = &d2dSolidColorBrush_;
GraphicsDeviceNativeWrapper::CreateFactories(Window, d2dFactoryPtr, dWriteFactoryPtr);
//Get DXGI Surface from the created render target.
IDXGISurface1* pRT10;
d3d10Texture->QueryInterface<IDXGISurface1>(&pRT10);
FLOAT dpiX;
FLOAT dpiY;
d2dFactory_->GetDesktopDpi(&dpiX, &dpiY);
// Create a DC render target.
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE),
static_cast<float>(dpiX),
static_cast<float>(dpiY)
);
// Create a Direct2D render target.
// Assuming m_pD2DFactory was previously created with:
//D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), NULL,
// (void**)(&m_pD2DFactory));
pin_ptr<ID2D1RenderTarget*> renderTargetPtr = &d2dRenderTarget_;
d2dFactory_->CreateDxgiSurfaceRenderTarget(pRT10, (const D2D1_RENDER_TARGET_PROPERTIES *)&props, renderTargetPtr);
pin_ptr<ID2D1SolidColorBrush*> solidColorBrushPtr = &d2dSolidColorBrush_;
d2dRenderTarget_->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), solidColorBrushPtr);
}
#pragma endregion
// File GraphicsDeviceNativeWrapper.h
#pragma once
#ifndef _GRAPHICSDEVICENATIVEWRAPPER_H_
#define _GRAPHICSDEVICENATIVEWRAPPER_H_
#ifndef _DWRITE_H_
#include "DWrite.h"
#endif
#pragma managed(push, false)
namespace BSGameFramework
{
namespace Graphics
{
class GraphicsDeviceNativeWrapper abstract sealed
{
public:
static void CreateFactories(HWND window, ID2D1Factory** d2dFactory, IDWriteFactory** dWriteFactory/*,ID2D1RenderTarget** d2dRenderTarget, ID2D1SolidColorBrush** d2dSolidColorBrush*/)
{
HRESULT result;
result = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,__uuidof(ID2D1Factory), NULL, (void**)d2dFactory);
if (SUCCEEDED(result))
{
result = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(dWriteFactory));
}
RECT rc;
GetClientRect(window, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
}
static void CreateTextFormat(const wchar_t* font, IDWriteFactory* factory, IDWriteTextFormat** format)
{
factory->CreateTextFormat(font, NULL, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 72.0f, L"en-us", format);
(*format)->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
(*format)->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
}
};
}
}
#pragma managed(pop)
#endif
And this is my SpriteBatch:
// File: SpriteBatch.h
#pragma once
#ifndef _SPRITEBATCH_H_
#define _SPRITEBATCH_H_
#ifndef _DEFINES_H_
#include "Defines.h"
#endif
#ifndef _GRAPHICRESOURCE_H_
#include "GraphicResource.h"
#endif
#ifndef _TEXTURE2D_H_
#include "Texture2D.h"
#endif
#ifndef _GRAPHICSDEVICE_H_
#include "GraphicsDevice.h"
#endif
#ifndef _SPRITESORTMODE_H_
#include "SpriteSortMode.h"
#endif
#ifndef _BLENDSTATE_H_
#include "BlendState.h"
#endif
#ifndef _NATIVESPRITEBATCH_H_
#include "NativeSpritebatch.h"
#endif
#ifndef _SPRITEEFFECT_H_
#include "SpriteEffect.h"
#endif
#ifndef _IDRAWABLECOMPONENT_H_
#include "IDrawableComponent.h"
#endif
#ifndef _SPRITEFONT_H_
#include "SpriteFont.h"
#endif
using namespace BSGameFramework::GameBase;
namespace BSGameFramework
{
namespace Graphics
{
public ref class SpriteBatch : GraphicResource
{
public:
SpriteBatch(GraphicsDevice^ graphicsDevice);
~SpriteBatch();
void Begin();
void Begin(SpriteSortMode sortMode, BlendState^ blendState);
void Draw(IDrawableComponent^ component);
void DrawString(SpriteFont^ font, System::String^ text, Vector2 position);
void End();
private:
bool CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer);
void SortByDepth();
SpriteSortMode sortMode_;
BlendState ^blendState_;
System::Collections::Generic::List<IDrawableComponent^>^ componentList_;
bool beginInvoked_;
ID3D11VertexShader* solidColorVS_;
ID3D11PixelShader* solidColorPS_;
ID3D11InputLayout* inputLayout_;
ID3D11Buffer* vertexBuffer_;
ID3D11BlendState* alphaBlendState_;
NativeSpritebatch* spriteBatch;
};
}
}
#endif
// File: SpriteBatch.cpp
#include "SpriteBatch.h"
#ifndef _SPRITEBATCHBEGINENDEXCEPTION_H_
#include "SpriteBatchBeginEndException.h"
#endif
using namespace BSGameFramework::Graphics;
using namespace BSGameFramework::Exception;
inline SpriteBatch::SpriteBatch(GraphicsDevice^ graphicsDevice) : alphaBlendState_( 0 )
{
graphicDevice_ = graphicsDevice;
sortMode_ = SpriteSortMode::Deferred;
blendState_ = BlendState::AlphaBlend;
// ID3DBlob contiene un puntatore ad un dato di lunghezza qualsiasi, GetBufferPointer restituisce il puntatore e GetBufferSize la grandezza
ID3DBlob* vsBuffer = 0;
// Compila lo shader e salva il risultato nel buffer
bool compileResult = CompileD3DShader("TextureMap.fx", "VS_Main", "vs_4_0", &vsBuffer);
if (compileResult == false)
{
DXTRACE_MSG("Error compiling the vertex shader!");
return;
}
HRESULT d3dResult;
pin_ptr<ID3D11VertexShader*> solidColorVSPointer;
solidColorVSPointer = &solidColorVS_;
// Crea il vertex shader e lo salva in solidColorVS_ di tipo ID3D11VertexShader*
d3dResult = Device->D3DDevice->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, solidColorVSPointer);
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating the vertex shader!");
if (vsBuffer)
{
vsBuffer->Release();
}
return;
}
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout);
pin_ptr<ID3D11InputLayout*> inputLayoutPointer;
inputLayoutPointer = &inputLayout_;
// Crea l'input layout e lo salva in inputLayout di tipo ID3D11InputLayout*
d3dResult = Device->D3DDevice->CreateInputLayout(solidColorLayout, totalLayoutElements, vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), inputLayoutPointer);
vsBuffer->Release();
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating the input layout!");
return;
}
ID3DBlob* psBuffer = 0;
// Compila il pixel shader e salva il risultato in psBuffer
compileResult = CompileD3DShader("TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer);
if (compileResult == false)
{
DXTRACE_MSG("Error compiling pixel shader!");
return;
}
pin_ptr<ID3D11PixelShader*> solidColorPSPointer;
solidColorPSPointer = &solidColorPS_;
// Crea il pixel shader e lo salva in solidColorPS_ di tipo ID3D11PixelShader*
d3dResult = Device->D3DDevice->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(), 0, solidColorPSPointer);;
psBuffer->Release();
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating pixel shader!");
return;
}
spriteBatch = new NativeSpritebatch(Device->D3DDevice);
// Spostare nel Begin successivamente
D3D11_BLEND_DESC blendDesc;
ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC));
blendDesc.AlphaToCoverageEnable = FALSE;
blendDesc.IndependentBlendEnable = FALSE;
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
pin_ptr<ID3D11BlendState*> alphaBlendStatePointer;
alphaBlendStatePointer = &alphaBlendState_;
Device->D3DDevice->CreateBlendState(&blendDesc, alphaBlendStatePointer);
Device->D3DContext->OMSetBlendState(alphaBlendState_, blendFactor, 0xFFFFFFFF);
}
inline SpriteBatch::~SpriteBatch()
{
}
inline void SpriteBatch::Begin()
{
if (beginInvoked_)
{
throw gcnew SpriteBatchBeginEndException("Beetween two SpriteBatch begin methods you must call SpriteBacth End method!");
}
beginInvoked_ = true;
Device->D2DRenderTarget->BeginDraw();
Device->D2DRenderTarget->SetTransform(D2D1::IdentityMatrix());
if (componentList_ == nullptr)
{
componentList_ = gcnew System::Collections::Generic::List<IDrawableComponent^>();
}
}
inline void SpriteBatch::Begin(SpriteSortMode sortMode, BlendState^ blendState)
{
Begin();
sortMode_ = sortMode;
}
inline void SpriteBatch::Draw(IDrawableComponent^ component)
{
if (component == nullptr)
{
throw gcnew ArgumentNullException("Component argument is null, please ensure to initialize all components correctly!");
}
else
{
componentList_->Add(component);
}
}
inline void SpriteBatch::DrawString(SpriteFont^ font, System::String^ text, Vector2 position)
{
RECT rc;
GetClientRect(Device->Window, &rc);
// Create a D2D rect that is the same size as the window.
D2D1_RECT_F layoutRect = D2D1::RectF(
static_cast<FLOAT>(rc.left) / font->DpiScaleX,
static_cast<FLOAT>(rc.top) / font->DpiScaleY,
static_cast<FLOAT>(rc.right - rc.left) / font->DpiScaleX,
static_cast<FLOAT>(rc.bottom - rc.top) / font->DpiScaleY
);
// Use the DrawText method of the D2D render target interface to draw.
WCHAR textUnicode = Utilities::StringToWCHAR(text);
UINT32 cTextLength_ = (UINT32) wcslen(&textUnicode);
Device->D2DSolidColorBrush->SetColor(D2D1::ColorF(0,0,0,1));
Device->D2DSolidColorBrush->SetColor(D2D1::ColorF(255, 255, 255, 255));
Device->D2DRenderTarget->DrawText(&textUnicode, cTextLength_, font->DWriteTextFormat, layoutRect, Device->D2DSolidColorBrush);
}
inline void SpriteBatch::End()
{
if (componentList_->Count)
{
if (sortMode_ == SpriteSortMode::BackToFront)
{
SortByDepth();
}
for (int i = 0; i < componentList_->Count; i++)
{
Texture* text = componentList_[i]->Texture->TextureInfo;
unsigned int stride = sizeof(VertexPos);
unsigned int offset = 0;
Device->D3DContext->IASetInputLayout(inputLayout_);
if (componentList_[i]->Effect != SpriteEffect::None)
{
ID3D11Buffer* vertexBuffer;
float width = (float)text->textureDesc_.Width;
float height = (float)text->textureDesc_.Height;
D3D11_BUFFER_DESC vertexDesc;
ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.Usage = D3D11_USAGE_DYNAMIC;
vertexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof(VertexPos) * 6;
D3D11_SUBRESOURCE_DATA resourceData;
ZeroMemory(&resourceData, sizeof(resourceData));
pin_ptr<ID3D11Buffer*> vertexBufferPointer;
vertexBufferPointer = &vertexBuffer;
switch (componentList_[i]->Effect)
{
case BSGameFramework::Graphics::SpriteEffect::FlipHorizontally:
{
VertexPos verticesOne[] =
{
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(width, 0.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(0.0f, height, 1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(0.0f, 0.0f) },
};
resourceData.pSysMem = verticesOne;
Device->D3DDevice->CreateBuffer(&vertexDesc, &resourceData, vertexBufferPointer);
Device->D3DContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
break;
}
case BSGameFramework::Graphics::SpriteEffect::FlipVertically:
{
VertexPos verticesTwo[] =
{
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(width, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(0.0f, height, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(1.0f, 1.0f) },
};
resourceData.pSysMem = verticesTwo;
Device->D3DDevice->CreateBuffer(&vertexDesc, &resourceData, vertexBufferPointer);
Device->D3DContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
break;
}
}
}
else
{
Device->D3DContext->IASetVertexBuffers(0, 1, &text->vertexBuffer_, &stride, &offset);
}
Device->D3DContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
Device->D3DContext->VSSetShader(solidColorVS_, 0, 0);
Device->D3DContext->PSSetShader(solidColorPS_, 0, 0);
Device->D3DContext->PSSetShaderResources(0, 1, &text->colorMap_);
Device->D3DContext->PSSetSamplers(0, 1, &text->colorMapSampler_);
spriteBatch->SetTranspose(Device->D3DContext, text, Device->WindowWidth, Device->WindowHeight, componentList_[i]->Position.X, componentList_[i]->Position.Y,
componentList_[i]->Scale.X, componentList_[i]->Scale.Y, componentList_[i]->Rotation);
Device->D3DContext->Draw(6, 0);
}
}
Device->D2DRenderTarget->EndDraw();
componentList_->Clear();
beginInvoked_ = false;
sortMode_ = SpriteSortMode::Deferred;
}
inline bool SpriteBatch::CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer)
{
DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined(DEBUG) || defined(_DEBUG)
shaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* errorBuffer = 0;
HRESULT result;
result = D3DX11CompileFromFile(filePath, 0, 0, entry, shaderModel, shaderFlags, 0, 0, buffer, &errorBuffer, 0);
if (FAILED(result))
{
if (errorBuffer != 0)
{
OutputDebugStringA((char*)errorBuffer->GetBufferPointer());
errorBuffer->Release();
}
return false;
}
if (errorBuffer != 0)
{
errorBuffer->Release();
}
return true;
}
inline void SpriteBatch::SortByDepth()
{
for (int i = 0; i < componentList_->Count - 1; i++)
{
for (int j = 1; j < componentList_->Count; j++)
{
if (componentList_[i]->ZIndex < componentList_[j]->ZIndex)
{
IDrawableComponent^ component = componentList_[i];
componentList_[i] = componentList_[j];
componentList_[j] = component;
}
}
}
}
When I call SpriteBatch.DrawString(...) from my C# app I'm not obtaining nothing written on my screen, can please somebody explaining me what's I'm missing? I'm new on DirectX programming so please be quiet with me xD Thanks!
There's a lot of code you posted and I didn't read it all, but I was trying to do the same thing (successfully) a few days ago and I might have some suggestions.
Overall, it looks like you do this more or less the same way I do. What I did different it that I created the shared texture using D3D11 device, but this should make no difference. The second thing, which I think could be the problem, is that you're not synchronizing the texture resource between D3D10 and D3D11.
When I tried to use such resources without synchronization, D2D was only rendering stuff once in like 50 calls, the rest just had no effect. I think I was continously blocking the resource when rendering it with D3D11.
You should create the texture using
tDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
instead. Here are the details about this flag: MSDN. Basically, you query two IDXGIKeyedMutex interfaces from the shared texture objects on both D3D10 and D3D11 devices. You lock the D3D10 mutex when you draw your D2D stuff to the texture. You lock the D3D11 mutex when you want to use this texture in D3D11. You do this using IDXGIKeyedMutex::AcquireSync and IDXGIKeyedMutex::ReleaseSync. Just be sure to pass the same Key value to each consecutive D3D10 Release -> D3D11 Acquire and D3D11 Release -> D3D10 Acquire calls.
Oh, one more little, not important thing, I noticed this in your code:
texture->QueryInterface<IDXGISurface>(&dxgiSurface);
dxgiSurface->QueryInterface<IDXGIResource>(&dxgiResource);
I'm not 100% sure, but I think you can get the IDXGIResource interface directly from your texture.
Related
Text dissapears on QOpenGLWidget after undocking
I'm trying to integrate Qt5 and OpenSceneGraph. I've found this minimal example of embedding. When I encapsulate the widget, defined in the example, into a QDockWidget and add a simple text label to the example, the text dissapears when I undock the container window. When I redock the window the text is shown no more. I've already ask this on the OpenSceneGraph forum without success. My guess is that it has something to do with the GL related methods and the internal reparenting of the widgets. In my example only the constructor and the main function are modified from the original. This is my modified example (main.cpp): #include<QApplication> #include<QMainWindow> #include<QOpenGLWidget> #include<QMouseEvent> #include<QWheelEvent> #include<QDesktopWidget> #include<QScreen> #include<QtGlobal> #include<QWindow> #include<QWidget> #include<QDockWidget> #include<QVBoxLayout> #include<osg/ref_ptr> #include<osgViewer/GraphicsWindow> #include<osgText/Text> #include<osgViewer/Viewer> #include<osg/Camera> #include<osg/ShapeDrawable> #include<osg/StateSet> #include<osg/Material> #include<osgGA/EventQueue> #include<osgGA/TrackballManipulator> #include <iostream> #include <stdio.h> class QtOSGWidget : public QOpenGLWidget { public: QtOSGWidget(qreal scaleX, qreal scaleY, QWidget* parent = 0) : QOpenGLWidget(parent) , _mGraphicsWindow(new osgViewer::GraphicsWindowEmbedded( this->x(), this->y(), this->width(), this->height() ) ) , _mViewer(new osgViewer::Viewer) , m_scaleX(scaleX) , m_scaleY(scaleY) { osg::Cylinder* cylinder = new osg::Cylinder( osg::Vec3( 0.f, 0.f, 0.f ), 0.25f, 0.5f ); osg::ShapeDrawable* sd = new osg::ShapeDrawable( cylinder ); sd->setColor( osg::Vec4( 0.8f, 0.5f, 0.2f, 1.f ) ); osg::Geode* geode = new osg::Geode; geode->addDrawable(sd); // adding text to the visualization osgText::Text * test = new osgText::Text(); test->setDataVariance(osg::Object::DYNAMIC); test->setCharacterSize(1.0); test->setColor(osg::Vec4(0.0, 0.0, 0.0, 1.0)); test->setAlignment(osgText::Text::CENTER_BOTTOM); test->setAxisAlignment(osgText::TextBase::SCREEN); test->setCharacterSizeMode(osgText::Text::OBJECT_COORDS); test->setText("CYLINDER"); geode->addDrawable(test); // end adding text osg::Camera* camera = new osg::Camera; camera->setViewport( 0, 0, this->width(), this->height() ); camera->setClearColor( osg::Vec4( 0.9f, 0.9f, 1.f, 1.f ) ); float aspectRatio = static_cast<float>( this->width()) / static_cast<float>( this->height() ); camera->setProjectionMatrixAsPerspective( 30.f, aspectRatio, 1.f, 1000.f ); camera->setGraphicsContext( _mGraphicsWindow ); _mViewer->setCamera(camera); _mViewer->setSceneData(geode); osgGA::TrackballManipulator* manipulator = new osgGA::TrackballManipulator; manipulator->setAllowThrow( false ); this->setMouseTracking(true); _mViewer->setCameraManipulator(manipulator); _mViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); // _mViewer->realize(); } virtual ~QtOSGWidget(){} void setScale(qreal X, qreal Y) { m_scaleX = X; m_scaleY = Y; this->resizeGL(this->width(), this->height()); } protected: virtual void paintGL() { _mViewer->frame(); } virtual void resizeGL( int width, int height ) { this->getEventQueue()->windowResize(this->x()*m_scaleX, this->y() * m_scaleY, width*m_scaleX, height*m_scaleY); _mGraphicsWindow->resized(this->x()*m_scaleX, this->y() * m_scaleY, width*m_scaleX, height*m_scaleY); osg::Camera* camera = _mViewer->getCamera(); camera->setViewport(0, 0, this->width()*m_scaleX, this->height()* m_scaleY); } virtual void initializeGL() { osg::Geode* geode = dynamic_cast<osg::Geode*>(_mViewer->getSceneData()); osg::StateSet* stateSet = geode->getOrCreateStateSet(); osg::Material* material = new osg::Material; material->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE ); stateSet->setAttributeAndModes( material, osg::StateAttribute::ON ); stateSet->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON ); } virtual void mouseMoveEvent(QMouseEvent* event) { this->getEventQueue()->mouseMotion(event->x()*m_scaleX, event->y()*m_scaleY); } virtual void mousePressEvent(QMouseEvent* event) { unsigned int button = 0; switch (event->button()) { case Qt::LeftButton: button = 1; break; case Qt::MiddleButton: button = 2; break; case Qt::RightButton: button = 3; break; default: break; } this->getEventQueue()->mouseButtonPress(event->x()*m_scaleX, event->y()*m_scaleY, button); } virtual void mouseReleaseEvent(QMouseEvent* event) { unsigned int button = 0; switch (event->button()) { case Qt::LeftButton: button = 1; break; case Qt::MiddleButton: button = 2; break; case Qt::RightButton: button = 3; break; default: break; } this->getEventQueue()->mouseButtonRelease(event->x()*m_scaleX, event->y()*m_scaleY, button); } virtual void wheelEvent(QWheelEvent* event) { int delta = event->delta(); osgGA::GUIEventAdapter::ScrollingMotion motion = delta > 0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN; this->getEventQueue()->mouseScroll(motion); } virtual bool event(QEvent* event) { bool handled = QOpenGLWidget::event(event); this->update(); return handled; } private: osgGA::EventQueue* getEventQueue() const { osgGA::EventQueue* eventQueue = _mGraphicsWindow->getEventQueue(); return eventQueue; } osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _mGraphicsWindow; osg::ref_ptr<osgViewer::Viewer> _mViewer; qreal m_scaleX, m_scaleY; }; int main(int argc, char** argv) { // This was necessary for keeping the context when undocking // without it nothing is shown on the widget when gets undocked QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QApplication qapp(argc, argv); QMainWindow window; // Here starts code to put the QtOSGWidget inside a dock area QDockWidget * visDock = new QDockWidget(&window); visDock->setFloating(false); visDock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable); visDock->setAllowedAreas(Qt::TopDockWidgetArea); QWidget * dockWidgetContent = new QWidget(); QVBoxLayout * verticalLayout = new QVBoxLayout(dockWidgetContent); verticalLayout->setSpacing(6); verticalLayout->setContentsMargins(11, 11, 11, 11); QWidget * containerWidget = new QWidget(dockWidgetContent); QHBoxLayout * horizontalLayout = new QHBoxLayout(containerWidget); horizontalLayout->setSpacing(0); horizontalLayout->setContentsMargins(11, 11, 11, 11); horizontalLayout->setContentsMargins(0, 0, 0, 0); QtOSGWidget* widget = new QtOSGWidget(1, 1, containerWidget); horizontalLayout->addWidget(widget); verticalLayout->addWidget(containerWidget); visDock->setWidget(dockWidgetContent); window.addDockWidget(static_cast<Qt::DockWidgetArea>(4), visDock); // No central widget is used for the example window.setCentralWidget(Q_NULLPTR); window.show(); return qapp.exec(); }
After _mViewer->setSceneData(geode); add this: _mGraphicsWindow->init(); initializeGL(); and change the method virtual void paintGL() { _mViewer->frame(); } to virtual void paintGL() { _mGraphicsWindow->decrementContextIDUsageCount(_mGraphicsWindow->getMaxContextID()); _mGraphicsWindow->releaseContext(); _mGraphicsWindow->init(); _mViewer->frame(); } And add thins on main function: QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); will solve your problem.
Connection between two Indy UDP Servers
I'm using RAD Studio 10.2 with two instances of TIdUDPServer from Indy 10. I run my program on Windows 10 and check the counters of sent and received packages, but there are no packages received. At the same time, I see through Wireshark that they come to the PC, but the second TIdUDPServer does not receive the packages. Why? Here is my code: //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; typedef struct { char Data[10000]; } struct_Buffer; int i = 0; int n = 0; int k = 0; int TxSize = 1400; char TxData; struct_Buffer TxBuffer; AnsiString ServerIP1 = "192.168.10.1"; AnsiString ServerIP2 = "192.168.10.2"; TBytes Buffer; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- class TMyQueueProc1 : public TCppInterfacedObject<TThreadProcedure> { private: int m_counter; TIdBytes m_bytes; public: TMyQueueProc1(int ACounter, const TIdBytes &AData) : m_counter(ACounter), m_bytes(AData) {} INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject); void __fastcall Invoke() { Form1->Label1->Caption = "Rx " + IntToStr(m_counter); } }; void __fastcall TForm1::FormCreate(TObject *Sender) { try { TIdSocketHandle *SocketHandle_Server = Form1->IdUDPServer1->Bindings->Add(); SocketHandle_Server->IP = ServerIP1; SocketHandle_Server->Port = 4004; Form1->IdUDPServer1->Active = true; } catch(Exception *ex) { ShowMessage("IdUDPServer1 start error!"); } try { TIdSocketHandle *SocketHandle_Echo = Form1->IdUDPServer2->Bindings->Add(); SocketHandle_Echo->IP = ServerIP2; SocketHandle_Echo->Port = 4004; Form1->IdUDPServer2->Active = true; } catch(Exception *ex) { ShowMessage("IdUDPServer2 start error!"); } Timer1->Interval = 100; Timer1->Enabled = true; Label3->Caption = "IdUPDServer1: " + ServerIP1; Label4->Caption = "IdUDPServer2: " + ServerIP2; } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { TxData++; if (TxData == 255) TxData = 0; for (k = 0; k < TxSize; k++) TxBuffer.Data[k] = TxData; Buffer = RawToBytes(&TxBuffer.Data[0], TxSize); Form1->IdUDPServer1->SendBuffer(ServerIP2, 4004, Buffer); n++; Label2->Caption = "Tx " + IntToStr(n); } //--------------------------------------------------------------------------- void __fastcall TForm1::IdUDPServer2UDPRead(TIdUDPListenerThread *AThread, const TIdBytes AData, TIdSocketHandle *ABinding) { i++; TThread::Queue(NULL, _di_TThreadProcedure(new TMyQueueProc1(i, AData))); } //---------------------------------------------------------------------------
Getting error c2280 at my Update function (at if (Game::vector.at(i).alivez()) specifically)
I'm having an error doing the Update when checking if(Game::vector.at(i).alivez()), the error is C2280. The error says: "Enemy &Enemy::operator =(const Enemy &)': attempting to reference a deleted function. Project: Avoidance Game File:xutility Game.cpp: void Game::Init() { int i = 0; while(i< Game::Enemies) { srand(time(NULL)); Game::vector.push_back(Enemy(0, (rand()% (int)Console::WindowWidth), (rand() % (int)Console::WindowHeight), rand()%1500/1000.0f)); i++; } GameOver = false; Paused = false; } void Game::GameMenu() { cout << "1. Start Game\n2. Instructions\n3. Close Game\nChoose an option:"; } void Game::Instructions() { Console::Clear(); cout << "Left arrow = left (duh)\nRight arrow = right (surprise)\nSpace Bar = Shoot\nEsc = Close Game\nP Key = Pause\n "; system("pause"); } void Game::fire(Player a) { a.mX; } void Game::Run() { while (!GameOver) { if (GetAsyncKeyState(VK_ESCAPE)) { GameOver = true; } else if (GetAsyncKeyState((int)'P')) { Paused = !Paused; } } } void Game::Update() { if (!Paused) { mPlayer.Update(); for (int i = 0; i < Game::Enemies; i++) { Game::vector.at(i).Update(); if (Game::vector.at(i).alivez()) { Game::vector.erase(Game::vector.begin() + i); i--; Game::Enemies--; } } } } Game.h: #pragma once #include "stdafx.h" #include "targetver.h" #include <vector> class Enemy; class Game { int Enemies = 30; bool Paused; bool GameOver; int Score; Player mPlayer = Player(); std::vector<Enemy> vector; public: void Init(); void GameMenu(); void Instructions(); void fire(Player a); void Run(); void Update(); }; Enemy.h: class Enemy { enum Enemy_type {NormalEnemy}; Game game; float mX; float mY; float speed; Enemy_type type; public: bool alive; Enemy(int type, int x, int y, float _speed) { switch (type) { case 0: type = Enemy_type::NormalEnemy; break; } mX = (float)x; mY = (float)y; speed = _speed; alive = true; } float GetX() { return mX; } float GetY() { return mY; } bool alivez() { return alive; } void Kill() { alive = false; } void Update(); void Draw(); };
triangle demo works on ubuntu13.04,doesn't work on ubuntu 12.04
I get a triangle demo from internet. It works on my ubuntu13.04 virtual machine,but it doesn't work on my ubuntu12.04 virtual machine.All of my two vritual machines installed libgles2-mesa-dev(apt-get).The only diffrenet is:the ubuntu12.04 glesv2 is based on mesa-8.0 and the ubuntu13.04 glesv2 is based on mesa-9. My code: #include <GLES2/gl2.h> #include <EGL/egl.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <unistd.h> #include <X11/Xlib.h> #define VERTEX_ARRAY 0 EGLDisplay eglDisplay = 0; EGLConfig eglConfig = 0; EGLSurface eglSurface = 0; EGLContext eglContext = 0; EGLNativeWindowType eglWindow = 0; bool TestEGLError() { EGLint iErr = eglGetError(); if (iErr != EGL_SUCCESS) { return false; } return true; } bool CreateEGLContext() { eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY); EGLint iMajorVersion, iMinorVersion; if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) { return false; } const EGLint pi32ConfigAttribs[] = { EGL_LEVEL, 0, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NATIVE_RENDERABLE, EGL_FALSE, EGL_DEPTH_SIZE, EGL_DONT_CARE, EGL_NONE }; EGLint config16bpp[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 0, EGL_NONE }; int iConfigs; if (!eglChooseConfig(eglDisplay,config16bpp, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { return false; } eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL); if(eglSurface == EGL_NO_SURFACE) { eglGetError(); // Clear error eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, NULL, NULL); } if (!TestEGLError()) { return false; } eglBindAPI(EGL_OPENGL_ES_API); EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError()) { return false; } eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError()) { return false; } return true; } bool Render() { bool bRet = false; float pfIdentity[] = { 1.0f,0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f, 0.0f,0.0f,0.0f,1.0f }; char szFragShaderSrc[] = {"\ void main (void)\ {\ gl_FragColor = vec4(1.0, 1.0, 0.66 ,1.0);\ }"}; char szVertShaderSrc[] = {"\ attribute highp vec4 myVertex;\ uniform mediump mat4 myPMVMatrix;\ void main(void)\ {\ gl_Position = myPMVMatrix * myVertex;\ }"}; char * pszFragShader = (char *)szFragShaderSrc; char * pszVertShader = (char *)szVertShaderSrc; GLuint uiFragShader = 0; GLuint uiVertShader = 0; GLuint uiProgramObject = 0; GLint bShaderCompiled; GLint bLinked; GLuint ui32Vbo = 0; GLfloat afVertices[] = { -0.4f,-0.4f,0.0f, // Position 0.4f ,-0.4f,0.0f, 0.0f ,0.4f ,0.0f}; int i32InfoLogLength, i32CharsWritten; char* pszInfoLog = NULL; int i32Location = 0; unsigned int uiSize = 0; uiFragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(uiFragShader, 1, (const char**)&pszFragShader, NULL); glCompileShader(uiFragShader); glGetShaderiv(uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { glGetShaderiv(uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); delete[] pszInfoLog; goto cleanup; } uiVertShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(uiVertShader, 1, (const char**)&pszVertShader, NULL); glCompileShader(uiVertShader); glGetShaderiv(uiVertShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { glGetShaderiv(uiVertShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(uiVertShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); delete[] pszInfoLog; goto cleanup; } uiProgramObject = glCreateProgram(); glAttachShader(uiProgramObject, uiFragShader); glAttachShader(uiProgramObject, uiVertShader); glBindAttribLocation(uiProgramObject, VERTEX_ARRAY, "myVertex"); glLinkProgram(uiProgramObject); glGetProgramiv(uiProgramObject, GL_LINK_STATUS, &bLinked); if (!bLinked) { glGetProgramiv(uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength); pszInfoLog = new char[i32InfoLogLength]; glGetProgramInfoLog(uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog); delete[] pszInfoLog; goto cleanup; } glUseProgram(uiProgramObject); glClearColor(0.6f, 0.8f, 1.0f, 1.0f); glGenBuffers(1, &ui32Vbo); glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo); uiSize = 3 * (sizeof(GLfloat) * 3); // Calc afVertices size (3 vertices * stride (3 GLfloats per vertex)) glBufferData(GL_ARRAY_BUFFER, uiSize, afVertices, GL_STATIC_DRAW); { glClear(GL_COLOR_BUFFER_BIT); i32Location = glGetUniformLocation(uiProgramObject, "myPMVMatrix"); glUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity); glEnableVertexAttribArray(VERTEX_ARRAY); glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLES, 0, 3); eglSwapBuffers(eglDisplay, eglSurface); } bRet = true; cleanup: if (uiProgramObject) glDeleteProgram(uiProgramObject); if (uiFragShader) glDeleteShader(uiFragShader); if (uiVertShader) glDeleteShader(uiVertShader); // Delete the VBO as it is no longer needed if (ui32Vbo) glDeleteBuffers(1, &ui32Vbo); return bRet; } int main(int argc ,char* argv[]) { unsigned int uiHeight = 800; unsigned int uiWidth = 480; int screen; Display *x_display; Window root_window; x_display = XOpenDisplay ( NULL ); // open the standard display (the primary screen) if ( x_display == NULL ) { printf ("cannot connect to X server"); return false; } screen = DefaultScreen(x_display); root_window = RootWindow(x_display,screen); static int Hnd = XCreateSimpleWindow(x_display, root_window,0,0,800,480,0,0,0); eglWindow = (EGLNativeWindowType)Hnd; if (!eglWindow) { printf("Failed to create X window.\n"); return false; } XUndefineCursor(x_display, eglWindow); XMapRaised(x_display, eglWindow); XFlush(x_display); CreateEGLContext(); while(1) { Render(); usleep(100000); } return 0; }
Add smooth animation when window grow
The idea I have is to give animation to a window/form when it grows. For example, the calculator of Windows 7 when it displays the unit converter or new features, the window changes size with smooth animation. The problem is that I do not know which code to use when using a button to change the size (eg 200 pixels more). I'm a beginner, so I do not know how to use "Timer" which was suggested to me.
On this page, can be found whole concept (in C#). You can even download the code already done (again, in C#): http://www.vcskicks.com/size-transform.php
This is a simple implementation in C++/CLI. I used C++/CLI so I can play with the syntax. You can easily convert it to C#. AnimateWindowResize.h #pragma once using namespace System; using namespace System::IO; // Stream using namespace System::Drawing; // Bitmap using namespace System::Reflection; // Assembly using namespace System::Collections::Generic; using namespace System::Text; using namespace System::Windows::Forms; public ref class AnimateWindowResize { private: static const int DEFAULT_STEP_AMOUNT = 15; bool m_startExpanding; bool m_animationEnabled; bool m_isHorizontal; Form^ m_windowsForm; Button^ m_initiateButton; int m_minSize; int m_maxSize; Timer^ m_timer; int m_stepRate; String^ m_initButtonText; String^ m_finalButtonText; String^ m_initButtonEmbeddedImageName; String^ m_finalButtonEmbeddedImageName; Bitmap^ m_initBitmap; Bitmap^ m_finalBitmap; public: AnimateWindowResize(Form^ windowsForm, Button^ initiateButton, bool isHorizontal, int minSize, int maxSize, bool isWindowExpanded); // init[final]EmbeddedImageName are images added under Linker -> Input -> Embed Managed Resource File. AnimateWindowResize(Form^ windowsForm, Button^ initiateButton, String^ initEmbeddedImageName, String^ finalEmbeddedImageName, String^ initButtonText, String^ finalButtonText, bool isHorizontal, int minSize, int maxSize, bool isWindowExpanded); protected: void Init(Form^ windowsForm, Button^ initiateButton, String^ initEmbeddedImageName, String^ finalEmbeddedImageName, String^ initButtonText, String^ finalButtonText, bool isHorizontal, int minSize, int maxSize, bool isWindowExpanded) { m_initBitmap = nullptr; m_finalBitmap = nullptr; m_windowsForm = windowsForm; m_initiateButton = initiateButton; if (initButtonText != nullptr) m_initiateButton->Text = initButtonText; Stream^ stm = nullptr; if(initEmbeddedImageName != nullptr) stm = Assembly::GetEntryAssembly()->GetManifestResourceStream (initEmbeddedImageName); if (stm != nullptr) { m_initBitmap = gcnew Bitmap(stm); m_initiateButton->Image = m_initBitmap; } stm = nullptr; if(finalEmbeddedImageName != nullptr) stm = Assembly::GetEntryAssembly()->GetManifestResourceStream (finalEmbeddedImageName); if (stm != nullptr) m_finalBitmap = gcnew Bitmap(stm); m_minSize = minSize; m_maxSize = maxSize; m_startExpanding = isWindowExpanded; m_isHorizontal = isHorizontal; m_initButtonText = initButtonText; m_finalButtonText = finalButtonText; m_initButtonEmbeddedImageName = initEmbeddedImageName; m_finalButtonEmbeddedImageName = finalEmbeddedImageName; m_animationEnabled = true; m_stepRate = DEFAULT_STEP_AMOUNT; // Calculate the step rate m_stepRate = (int)((maxSize - minSize) / 10.0); if (m_stepRate <= 0) m_stepRate = DEFAULT_STEP_AMOUNT; m_timer = gcnew Timer(); m_timer->Interval = 1; m_timer->Enabled = false; m_timer->Tick += gcnew EventHandler(this, &AnimateWindowResize::m_timer_Tick); } void m_timer_Tick(Object^ sender, EventArgs^ e) { if (m_startExpanding) { if (m_isHorizontal) { if (m_windowsForm->Width >= m_maxSize) { m_timer->Enabled = false; } else { int tempWidth = m_windowsForm->Width + m_stepRate; if (tempWidth >= m_maxSize) { m_windowsForm->Width = m_maxSize; m_timer->Enabled = false; return; } m_windowsForm->Width += m_stepRate; } } else // Vertical { if (m_windowsForm->Height >= m_maxSize) { m_timer->Enabled = false; } else { int tempHeight = m_windowsForm->Height + m_stepRate; if (tempHeight >= m_maxSize) { m_windowsForm->Height = m_maxSize; m_timer->Enabled = false; return; } m_windowsForm->Height += m_stepRate; } } } else // Collaspe { if (m_isHorizontal) { if (m_windowsForm->Width <= m_minSize) { m_timer->Enabled = false; } else { int tempWidth = m_windowsForm->Width - m_stepRate; if (tempWidth <= m_minSize) { m_windowsForm->Width = m_minSize; m_timer->Enabled = false; return; } m_windowsForm->Width -= m_stepRate; } } else // Vertical { if (m_windowsForm->Height <= m_minSize) { m_timer->Enabled = false; } else { int tempHeight = m_windowsForm->Height - m_stepRate; if (tempHeight <= m_minSize) { m_windowsForm->Height = m_minSize; m_timer->Enabled = false; return; } m_windowsForm->Height -= m_stepRate; } } } } public: void StartAnimation() { m_timer->Enabled = m_animationEnabled; m_startExpanding = !m_startExpanding; // Change the text of the initiate button. if (m_startExpanding) { m_initiateButton->Text = m_finalButtonText == nullptr ? "Less" : m_finalButtonText; if (m_finalBitmap != nullptr) m_initiateButton->Image = m_finalBitmap; } else { m_initiateButton->Text = m_initButtonText == nullptr ? "More" : m_initButtonText; if (m_initBitmap != nullptr) m_initiateButton->Image = m_initBitmap; } if (!m_animationEnabled) ResizeWithNoAnimation(); } public: property bool AnimationEnabled { bool get() { return m_animationEnabled; } void set(bool value) { m_animationEnabled = value; } } private: void ResizeWithNoAnimation() { // Just resize the window. if (m_startExpanding) { if (m_isHorizontal) m_windowsForm->Width = m_maxSize; else m_windowsForm->Height = m_maxSize; } else { if (m_isHorizontal) m_windowsForm->Width = m_minSize; else m_windowsForm->Height = m_minSize; } } }; AnimateWindowResize.cpp #include "AnimateWindowResize.h" AnimateWindowResize::AnimateWindowResize(Form^ windowsForm, Button^ initiateButton, bool isHorizontal, int minSize, int maxSize, bool isWindowExpanded) { Init(windowsForm, initiateButton, nullptr, nullptr, nullptr, nullptr, isHorizontal, minSize, maxSize, isWindowExpanded); } // init[final]EmbeddedImageName are images added under Linker -> Input -> Embed Managed Resource File. AnimateWindowResize::AnimateWindowResize(Form^ windowsForm, Button^ initiateButton, String^ initEmbeddedImageName, String^ finalEmbeddedImageName, String^ initButtonText, String^ finalButtonText, bool isHorizontal, int minSize, int maxSize, bool isWindowExpanded) { Init(windowsForm, initiateButton, initEmbeddedImageName, finalEmbeddedImageName, initButtonText, finalButtonText, isHorizontal, minSize, maxSize, isWindowExpanded); }