Advertisement

Texture not rendering

Started by July 23, 2014 08:50 PM
1 comment, last by Topblast_ 10 years, 6 months ago

I am currently trying to build a D3D11 Renderer for Gwen gui, for some reason non of the textures render, if I change the pixel shader to only return the color, it works.


float ClearColor[4] = { 0.128f, 0.128f, 0.3f, 1.0f };
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
static Gwen::Font font;

pRenderer->Begin();
pRenderer->RenderText(&font, Gwen::Point(100, 100), "Hello World!");
pRenderer->End();

g_pSwapChain->Present(0, 0);

#include "Gwen/Renderers/DirectX11.h"
#include "Gwen/Utility.h"
#include "Gwen/Font.h"
#include "Gwen/Texture.h"
#include "Gwen/WindowProvider.h"

#include <xnamath.h>
#include <d3dx11.h>
#include <d3dcompiler.h>


#define D3DCOLOR_ARGB(a,r,g,b) \
    ((DWORD)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))

#pragma region Shaders
const char pixshader[] = {
	"sampler samp0 : register(s0);\n"
	"Texture2D tex2D : register(t0);\n"
	"struct PS_INPUT\n"
	"{\n"
	"	float4 pos : SV_POSITION;\n"
	"	float4 col : COLOR;\n"
	"	float2 tex : TEXCOORD;\n"
	"};\n"
	"float4 texmain( PS_INPUT input ) : SV_Target\n"
	"{\n"
	"	return tex2D.Sample(samp0, input.tex) * input.col;\n"
	"}\n"
	"float4 main( PS_INPUT input ) : SV_Target\n"
	"{\n"
	"	return input.col;\n"
	"}"
};

const char vertshader[] = {
	"struct VS_INPUT\n"
	"{\n"
	"	float4 pos : POSITION;\n"
	"	float4 col : COLOR;\n"
	"	float2 tex : TEXCOORD;\n"
	"};\n"
	"struct PS_INPUT\n"
	"{\n"
	"	float4 pos : SV_POSITION;\n"
	"	float4 col : COLOR;\n"
	"	float2 tex : TEXCOORD;\n"
	"};\n"
	"PS_INPUT main( VS_INPUT input )\n"
	"{\n"
	"	PS_INPUT output;\n"
	"	output.pos = input.pos;\n"
	"	output.col = input.col;\n"
	"	output.tex = input.tex;\n"
	"	return output;\n"
	"};\n"
};

inline HRESULT CompileShaderFromMemory(const char* szdata, SIZE_T len, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
{
	HRESULT hr = S_OK;

	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
	// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows 
	// the shaders to be optimized and to run exactly the way they will run in 
	// the release configuration of this program.
	dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
	
	ID3DBlob* pErrorBlob;
	hr = D3DX11CompileFromMemory(szdata, len, NULL, NULL, NULL, szEntryPoint, szShaderModel,
		dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL);

	if (FAILED(hr))
	{
		if (pErrorBlob)
			pErrorBlob->Release();
		return hr;
	}
	if (pErrorBlob)
		pErrorBlob->Release();

	return S_OK;
}
#pragma endregion
namespace Gwen
{
	namespace Renderer
	{
		class FontData
		{
		public:
			XMFLOAT4 m_fTexCoords[0x60];

			UINT32   m_TexWidth;
			UINT32   m_TexHeight;
			float   m_Spacing;
			ID3D11ShaderResourceView* m_Texture;
		};

		DirectX11::DirectX11(ID3D11Device* pDevice) : m_pDevice(pDevice), m_Buffer(256)
		{
			m_pSwapChain = NULL;
			width = height = 0;

			m_pContext = NULL;
			m_pRastState = NULL;
			m_pPixShader = NULL;
			m_pVertShader = NULL;
			m_pBlendState = NULL;
			m_pInputLayout = NULL;
			m_pTexPixShader = NULL;
			m_pCurrentTexture = NULL;

			if (m_pDevice)
				Init();
		}

		DirectX11::~DirectX11()
		{
		}

		void DirectX11::Init()
		{
			m_Valid = false;

			m_pDevice->GetImmediateContext(&m_pContext);

			ID3DBlob* pVSBlob = NULL;
			ID3DBlob* pPSBlob = NULL;
			ID3DBlob* pTexPSBlob = NULL;

			if (FAILED(CompileShaderFromMemory(vertshader, sizeof(vertshader), "main", "vs_4_0", &pVSBlob)))
				return;

			if (FAILED(CompileShaderFromMemory(pixshader, sizeof(pixshader), "main", "ps_4_0", &pPSBlob))
				|| FAILED(CompileShaderFromMemory(pixshader, sizeof(pixshader), "texmain", "ps_4_0", &pTexPSBlob)))
			{
				SafeRelease(pVSBlob);
				SafeRelease(pPSBlob);
				SafeRelease(pTexPSBlob);
				return;
			}

			if (FAILED(m_pDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &m_pVertShader))
				|| FAILED(m_pDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &m_pPixShader))
				|| FAILED(m_pDevice->CreatePixelShader(pTexPSBlob->GetBufferPointer(), pTexPSBlob->GetBufferSize(), NULL, &m_pTexPixShader)))
			{
				SafeRelease(pVSBlob);
				SafeRelease(pPSBlob);
				SafeRelease(pTexPSBlob);

				Release();
				return;
			}

			SafeRelease(pPSBlob);
			SafeRelease(pTexPSBlob);

			D3D11_INPUT_ELEMENT_DESC layout[] =
			{
				{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
				{ "COLOR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
				{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			};
			UINT numElements = ARRAYSIZE(layout);

			if (FAILED(m_pDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &m_pInputLayout)))
			{
				SafeRelease(pVSBlob);

				Release();
				return;
			}

			SafeRelease(pVSBlob);

			D3D11_BLEND_DESC blenddesc;
			blenddesc.AlphaToCoverageEnable = FALSE;
			blenddesc.IndependentBlendEnable = FALSE;
			blenddesc.RenderTarget[0].BlendEnable = TRUE;
			blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
			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_INV_SRC_ALPHA;
			blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

			if (FAILED(m_pDevice->CreateBlendState(&blenddesc, &m_pBlendState)))
			{
				Release();
				return;
			}

			D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false);

			if (FAILED(m_pDevice->CreateRasterizerState(&rastdesc, &m_pRastState)))
			{
				Release();
				return;
			}

			D3D11_VIEWPORT vp;
			UINT numViewports = 1;
			m_pContext->RSGetViewports(&numViewports, &vp);

			width = vp.Width;
			height = vp.Height;

			m_Valid = true;
		}

		void DirectX11::Release()
		{
			m_Valid = false;

			Font::List::iterator it = m_FontList.begin();

			while (it != m_FontList.end())
			{
				FreeFont(*it);
				it = m_FontList.begin();
			}

			SafeRelease(m_pRastState);
			SafeRelease(m_pPixShader);
			SafeRelease(m_pBlendState);
			SafeRelease(m_pVertShader);
			SafeRelease(m_pInputLayout);
			SafeRelease(m_pTexPixShader);
		}

		void DirectX11::Begin()
		{
			if (FAILED(m_Buffer.Begin(m_pDevice)))
				return;

			if (!m_Valid)
				Init();

			
			// Save current state
			m_pContext->OMGetBlendState(&m_pUILastBlendState, m_LastBlendFactor, &m_LastBlendMask);
			m_pContext->RSGetState(&m_pUILastRasterizerState);
			m_pContext->OMGetDepthStencilState(&m_LastDepthState, &m_LastStencilRef);
			m_pContext->IAGetInputLayout(&m_LastInputLayout);
			m_pContext->IAGetPrimitiveTopology(&m_LastTopology);
			m_pContext->IAGetVertexBuffers(0, 8, m_LastBuffers, m_LastStrides, m_LastOffsets);
			m_pContext->PSGetShaderResources(0, 8, m_pLastTexture);
			m_pContext->PSGetShader(&m_LastPSShader, NULL, 0);
			m_pContext->GSGetShader(&m_LastGSShader, NULL, 0);
			m_pContext->VSGetShader(&m_LastVSShader, NULL, 0);
			
			m_pCurrentTexture = m_pLastTexture[0];

			m_pContext->RSSetState(m_pRastState);
			m_pContext->IASetInputLayout(m_pInputLayout);
			m_pContext->OMSetBlendState(m_pBlendState, NULL, 0xFFFFFFFF);

		}

		void DirectX11::End()
		{
			m_Buffer.End();
			Present();
			
			m_pContext->OMSetBlendState(m_pUILastBlendState, m_LastBlendFactor, m_LastBlendMask);
			m_pContext->RSSetState(m_pUILastRasterizerState);
			m_pContext->OMSetDepthStencilState(m_LastDepthState, m_LastStencilRef);
			m_pContext->IASetInputLayout(m_LastInputLayout);
			m_pContext->IASetPrimitiveTopology(m_LastTopology);
			m_pContext->IASetVertexBuffers(0, 8, m_LastBuffers, m_LastStrides, m_LastOffsets);
			m_pContext->PSSetShaderResources(0, 8, m_pLastTexture);
			m_pContext->PSSetShader(m_LastPSShader, NULL, 0);
			m_pContext->GSSetShader(m_LastGSShader, NULL, 0);
			m_pContext->VSSetShader(m_LastVSShader, NULL, 0);
		}

		void DirectX11::Present()
		{
			UINT stride = sizeof(VertexFormat);
			UINT offset = 0;

			m_pContext->IASetVertexBuffers(0, 1, &m_Buffer.GetBuffer(), &stride, &offset);

			if (m_pCurrentTexture != NULL)
			{
				m_pContext->PSSetShader(m_pTexPixShader, NULL, 0);
				m_pContext->PSGetShaderResources(0, 1, &m_pCurrentTexture);
			}
			else
				m_pContext->PSSetShader(m_pPixShader, NULL, 0);

			m_pContext->VSSetShader(m_pVertShader, NULL, 0);
			m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

			m_pContext->Draw(m_Buffer.GetNumVertices(), 0);
		}

		void DirectX11::Flush()
		{
			m_Buffer.End();
			Present();
			m_Buffer.Begin(m_pDevice);
		}

		void DirectX11::AddVert(int x, int y)
		{
			float scalex = 1 / width * 2.f;
			float scaley = 1 / height * 2.f;

			VertexFormat vert = { x * scalex - 1.f, 1.f - y * scaley, 0.5f, m_Color, 0.f, 0.f };

			m_Buffer.Add(vert);
		}

		void DirectX11::AddVert(int x, int y, float u, float v)
		{
			float scalex = 1 / width * 2.f;
			float scaley = 1 / height * 2.f;

			VertexFormat vert = { x * scalex - 1.f, 1.f - y * scaley, 0.5f, m_Color, u, v };

			m_Buffer.Add(vert);
		}

		void DirectX11::DrawFilledRect(Gwen::Rect rec)
		{
			if (m_pCurrentTexture != NULL)
			{
				Flush();
				m_pCurrentTexture = NULL;
			}

			Translate(rec);

			float scalex = 1 / width * 2.f;
			float scaley = 1 / height * 2.f;

			XMFLOAT4A rect(rec.x, rec.y, rec.w, rec.h);

			rect.z = (rect.x + rect.z) * scalex - 1.f;
			rect.w = 1.f - (rect.y + rect.w) * scaley;
			rect.x = rect.x * scalex - 1.f;
			rect.y = 1.f - rect.y * scaley;

			VertexFormat verts[6] =
			{
				{ rect.x, rect.w, 0.5f, m_Color, 0.f, 0.f },
				{ rect.x, rect.y, 0.5f, m_Color, 0.f, 0.f },
				{ rect.z, rect.w, 0.5f, m_Color, 0.f, 0.f },
				{ rect.z, rect.y, 0.5f, m_Color, 0.f, 0.f },
				{ rect.z, rect.w, 0.5f, m_Color, 0.f, 0.f },
				{ rect.x, rect.y, 0.5f, m_Color, 0.f, 0.f }
			};

			m_Buffer.Add(verts, ARRAYSIZE(verts));
		}

		void DirectX11::SetDrawColor(Gwen::Color color)
		{
			m_Color = D3DCOLOR_ARGB(color.a, color.r, color.g, color.b);
		}

		void DirectX11::LoadFont(Gwen::Font* font)
		{
			font->realsize = font->size * Scale();

			DWORD texWidth, texHeight;
			if (font->realsize > 60)
				texWidth = 2048;
			else if (font->realsize > 30)
				texWidth = 1024;
			else if (font->realsize > 15)
				texWidth = 512;
			else
				texWidth = 256;

			DWORD*      pBitmapBits;
			BITMAPINFO bmi;
			ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
			bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
			bmi.bmiHeader.biWidth = texWidth;
			bmi.bmiHeader.biHeight = -static_cast<int>(texWidth);
			bmi.bmiHeader.biPlanes = 1;
			bmi.bmiHeader.biCompression = BI_RGB;
			bmi.bmiHeader.biBitCount = 32;

			HDC hDC = CreateCompatibleDC(NULL);
			HBITMAP hBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
			SetMapMode(hDC, MM_TEXT);

			HFONT hFont = CreateFontA(-font->realsize, 0, 0, 0, font->bold ? FW_BOLD : FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
				CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH, Utility::UnicodeToString(font->facename).c_str());

			if (!hFont)
				return;

			SelectObject(hDC, hBitmap);
			SelectObject(hDC, hFont);

			SetTextColor(hDC, RGB(0xFF, 0xFF, 0xFF));
			SetBkColor(hDC, 0x00000000);
			SetTextAlign(hDC, TA_TOP);

			float x = 0, y = 0;
			char str[2] = "x";
			SIZE sz;

			GetTextExtentPoint32A(hDC, " ", 1, &sz);

			float spacing = sz.cx;

			std::vector<XMFLOAT4> sizes;

			for (char c = 32; c < 127; c++)
			{
				str[0] = c;
				GetTextExtentPoint32A(hDC, str, 1, &sz);

				if (x + sz.cx > texWidth)
				{
					x = 0;
					y += sz.cy;
				}

				sizes.push_back(XMFLOAT4(x, y, x + sz.cx, y + sz.cy));

				x += sz.cx + spacing / 2;
			}

			texHeight = y + sz.cy;

			FontData* data = new FontData();

			byte c = 0;
			for each (auto& var in sizes)
			{
				str[0] = c + 32;

				ExtTextOutA(hDC, static_cast<int>(ceilf(var.x)), static_cast<int>(ceilf(var.y)), ETO_OPAQUE, NULL, str, 1, NULL);

				data->m_fTexCoords[c++] = { var.x / texWidth, var.y / texHeight, var.z / texWidth, var.w / texHeight };
			}

			data->m_Spacing = spacing;
			data->m_TexHeight = texHeight;
			data->m_TexWidth = texWidth;

			DWORD len = texWidth * texHeight;

			ID3D11Texture2D* buftex;
			D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, data->m_TexWidth, data->m_TexHeight, 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);

			if (FAILED(m_pDevice->CreateTexture2D(&texdesc, nullptr, &buftex)))
			{
				delete data;

				DeleteObject(hBitmap);
				DeleteObject(hFont);
				DeleteDC(hDC);

				return;
			}

			D3D11_MAPPED_SUBRESOURCE texmap;
			if (FAILED(m_pContext->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap)))
			{
				delete data;

				DeleteObject(hBitmap);
				DeleteObject(hFont);
				DeleteDC(hDC);
				SafeRelease(buftex);

				return;
			}
			
			BYTE bAlpha;
			DWORD* pDst32;
			BYTE* pDstRow = (BYTE*)texmap.pData;

			for (UINT32 y = 0; y < data->m_TexHeight; y++)
			{
				pDst32 = (DWORD*)pDstRow;
				for (UINT32 x = 0; x < data->m_TexWidth; x++)
				{
					bAlpha = BYTE((pBitmapBits[data->m_TexWidth * y + x] & 0xFF) >> 4);
					if (bAlpha > 0)
						*pDst32++ = ((bAlpha * 0x11) << 24) | 0xFFFFFF;
					else
						*pDst32++ = 0;
				}
				pDstRow += texmap.RowPitch;
			}

			DeleteObject(hBitmap);
			DeleteObject(hFont);
			DeleteDC(hDC);

			m_pContext->Unmap(buftex, 0);

			if (FAILED(m_pDevice->CreateShaderResourceView(buftex, nullptr, &data->m_Texture)))
			{
				delete data;

				SafeRelease(buftex);


				return;
			}


			SafeRelease(buftex);

			font->data = data;

			m_FontList.push_back(font);
		}

		void DirectX11::FreeFont(Gwen::Font* pFont)
		{
			m_FontList.remove(pFont);

			if (!pFont->data)
				return;

			FontData* pFontData = (FontData*)pFont->data;

			if (pFontData)
			{
				SafeRelease(pFontData->m_Texture);
				delete pFontData;
			}

			pFont->data = NULL;
		}

		void DirectX11::RenderText(Gwen::Font* pFont, Gwen::Point pos, const Gwen::String & text)
		{
			Flush();

			// If the font doesn't exist, or the font size should be changed
			if (!pFont->data || fabs(pFont->realsize - pFont->size * Scale()) > 2)
			{
				FreeFont(pFont);
				LoadFont(pFont);
			}

			FontData* pFontData = (FontData*)pFont->data;
			Translate(pos.x, pos.y);

			float scalex = 1 / (float)width * 2.f;
			float scaley = 1 / (float)height * 2.f;

			XMFLOAT4A loc(pos.x * scalex - 1.f, 1.f - pos.y * scaley, 100 * scalex - 1, 1 - scaley * 100);

			FontData* data = (FontData*)pFont->data;

			if (m_pCurrentTexture != data->m_Texture)
			{
				m_pCurrentTexture = data->m_Texture;
			}

			
			float fStartX = loc.x;
			
			for each(auto c in text)
			{
				if (c < 32 || c >= 128)
				{
					if (c == '\n')
					{
						loc.x = fStartX;
						loc.y += (data->m_fTexCoords[c - 32].y - data->m_fTexCoords[c - 32].w) * data->m_TexHeight * scaley;
					}
					else
						continue;
				}

				c -= 32;

				loc.z = loc.x + ((data->m_fTexCoords[c].z - data->m_fTexCoords[c].x) * data->m_TexWidth * scalex);
				loc.w = loc.y + ((data->m_fTexCoords[c].y - data->m_fTexCoords[c].w) * data->m_TexHeight * scaley);

				if (c != 0)
				{

					VertexFormat v[6];
					v[0] = { loc.x, loc.w, 0.5f, m_Color, data->m_fTexCoords[c].x, data->m_fTexCoords[c].w };
					v[1] = { loc.x, loc.y, 0.5f, m_Color, data->m_fTexCoords[c].x, data->m_fTexCoords[c].y };
					v[2] = { loc.z, loc.w, 0.5f, m_Color, data->m_fTexCoords[c].z, data->m_fTexCoords[c].w };
					v[3] = { loc.z, loc.y, 0.5f, m_Color, data->m_fTexCoords[c].z, data->m_fTexCoords[c].y };
					v[4] = v[2];
					v[5] = v[1];

					m_Buffer.Add(v, ARRAYSIZE(v));
				}
				loc.x += (loc.z - loc.x);
			}

			Flush();
		}

		void DirectX11::RenderText(Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString & text)
		{
			RenderText(pFont, pos, Utility::UnicodeToString(text));
		}

		Gwen::Point DirectX11::MeasureText(Gwen::Font* pFont, const Gwen::String & text)
		{
			// If the font doesn't exist, or the font size should be changed
			if (!pFont->data || fabs(pFont->realsize - pFont->size * Scale()) > 2)
			{
				FreeFont(pFont);
				LoadFont(pFont);
			}

			FontData* font = (FontData*)pFont->data;

			float fRowWidth = 0.0f;
			float fRowHeight = (font->m_fTexCoords[0].w - font->m_fTexCoords[0].y) * font->m_TexHeight;
			float fWidth = 0.0f;
			float fHeight = fRowHeight;

			for each(auto c in text)
			{
				if (c == '\n')
				{
					fRowWidth = 0.0f;
					fHeight += fRowHeight;
				}

				c -= 32;

				if (c < 0 || c >= 96)
					continue;


				float tx1 = font->m_fTexCoords[c].x;
				float tx2 = font->m_fTexCoords[c].z;

				fRowWidth += (tx2 - tx1)* font->m_TexWidth;

				if (fRowWidth > fWidth)
					fWidth = fRowWidth;
			}

			return Gwen::Point(fWidth, fHeight);
		}

		Gwen::Point DirectX11::MeasureText(Gwen::Font* pFont, const Gwen::UnicodeString & text)
		{
			return MeasureText(pFont, Utility::UnicodeToString(text));
		}

		void DirectX11::StartClip()
		{
			Flush();/*
			const Gwen::Rect & rect = ClipRegion();

			float scalex = 1 / width * 2.f;
			float scaley = 1 / height * 2.f;

			D3D11_RECT r;
			r.left = ceil(((float)rect.x) * Scale()) * scalex - 1.f;
			r.right = ceil(((float)(rect.x + rect.w)) * Scale()) * scalex - 1.f;
			r.top = 1.f - scaley * ceil((float)rect.y * Scale());
			r.bottom = 1.f - scaley * ceil(((float)(rect.y + rect.h)) * Scale());
			*/
	//		m_pContext->RSSetScissorRects(1, &r);
		}

		void DirectX11::EndClip()
		{
			Flush();
			//m_pContext->RSSetScissorRects(0, NULL);
		}

		void DirectX11::DrawTexturedRect(Gwen::Texture* pTexture, Gwen::Rect rec, float u1, float v1, float u2, float v2)
		{
			ID3D11ShaderResourceView* pImage = (ID3D11ShaderResourceView*)pTexture->data;

			if (!pImage)
				return DrawMissingImage(rec);

			if (m_pCurrentTexture != pImage)
			{
				Flush();
				m_pCurrentTexture = pImage;
			}

			float scalex = 1 / width * 2.f;
			float scaley = 1 / height * 2.f;

			XMFLOAT4A rect(rec.x, rec.y, rec.w, rec.h);

			rect.z = (rect.x + rect.z) * scalex - 1.f;
			rect.w = 1.f - (rect.y + rect.w) * scaley;
			rect.x = rect.x * scalex - 1.f;
			rect.y = 1.f - rect.y * scaley;

			VertexFormat verts[6] =
			{
				{ rect.x, rect.w, 0.5f, m_Color, u1, v2 },
				{ rect.x, rect.y, 0.5f, m_Color, u1, v1 },
				{ rect.z, rect.w, 0.5f, m_Color, u2, v2 },
				{ rect.z, rect.y, 0.5f, m_Color, u2, v1 },
				{ rect.z, rect.w, 0.5f, m_Color, u2, v2 },
				{ rect.x, rect.y, 0.5f, m_Color, u1, v1 }
			};

			m_Buffer.Add(verts, ARRAYSIZE(verts));
		}

		void DirectX11::LoadTexture(Gwen::Texture* pTexture)
		{
			HRESULT hr = S_OK;
			ID3D11ShaderResourceView* pTex = NULL;
			HRESULT retHR;
			D3DX11_IMAGE_INFO imgInfo;

			retHR = D3DX11GetImageInfoFromFileW(pTexture->name.GetUnicode().c_str(), NULL, &imgInfo, NULL);
			hr = D3DX11CreateShaderResourceViewFromFileW(m_pDevice, pTexture->name.GetUnicode().c_str(), NULL, NULL, &pTex, NULL);
			
			if (hr != S_OK || retHR != S_OK)
			{
				return;
			}

			pTexture->data = pTex;
			pTexture->width = imgInfo.Width;
			pTexture->height = imgInfo.Height;
		}

		void DirectX11::FreeTexture(Gwen::Texture* pTexture)
		{
			return;
		}

		Gwen::Color DirectX11::PixelColour(Gwen::Texture* pTexture, unsigned int x, unsigned int y, const Gwen::Color & col_default)
		{
			return col_default;
			/*
			ID3D11ShaderResourceView* pImage = (ID3D11ShaderResourceView*)pTexture->data;
			if (!pImage)
				return col_default;

			ID3D11Texture2D *t = NULL;
			pImage->GetResource(reinterpret_cast<ID3D11Resource**>(&t));
			
			// We have to create a staging texture to copy the texture to, because textures cannot
			// be used as shader resources and have CPU read access at the same time.

			// Furthermore, in DX11 this texture must already exist and have the same exact dimensions as the
			// source texture. So we have to create and destroy it every time, without prior knowledge of the size
			// of the incoming texture. Obviously this is really expensive.
			ID3D11Texture2D* stagingTexture = NULL;

			DXGI_SAMPLE_DESC sampleDesc = { 1, 0 };

			D3D11_TEXTURE2D_DESC tdesc;
			tdesc.Width = pTexture->width;
			tdesc.Height = pTexture->height;
			tdesc.MipLevels = 0;
			tdesc.ArraySize = 1;
			tdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
			tdesc.SampleDesc = sampleDesc;
			tdesc.Usage = D3D11_USAGE_STAGING;
			tdesc.BindFlags = 0;
			tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
			tdesc.MiscFlags = 0;
			
			if (FAILED(m_pDevice->CreateTexture2D(&tdesc, NULL, &stagingTexture)))
			{
				return col_default;
			}

			// Copy the data over to the staging texture
			m_pContext->CopyResource(stagingTexture, t);

			D3D11_MAPPED_SUBRESOURCE msr;
			if (FAILED(m_pContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &msr)))
			{
				SafeRelease(stagingTexture);
				SafeRelease(t);
				return col_default;
			}

			DWORD* pixels = (DWORD*)msr.pData;
			DWORD color = pixels[msr.RowPitch / sizeof(DWORD) * y + x];
			m_pContext->Unmap(stagingTexture, 0);

			stagingTexture->Release();
			t->Release();

			DWORD a = ((255u << 24u) & color) >> 24u;
			DWORD r = ((255u << 16u) & color) >> 16u;
			DWORD g = ((255u << 8u) & color) >> 8u;
			DWORD b = ((255u) & color);

			return Gwen::Color(r, g, b, a);*/
		}
#pragma region Experimental
		void DirectX11::FillPresentParameters(Gwen::WindowProvider* pWindow, DXGI_SWAP_CHAIN_DESC & Params)
		{
			HWND pHWND = (HWND)pWindow->GetWindow();
			RECT ClientRect;
			GetClientRect(pHWND, &ClientRect);
			ZeroMemory(&Params, sizeof(Params));


			UINT WIDTH = ClientRect.right - ClientRect.left;
			UINT HEIGHT = ClientRect.bottom - ClientRect.top;

			Params.BufferCount = 1;
			Params.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
			Params.OutputWindow = pHWND;
			Params.SampleDesc.Count = 1;
			Params.SampleDesc.Quality = 0;
			Params.Windowed = TRUE;

			Params.BufferDesc.RefreshRate = { 1, 60 };
			Params.BufferDesc.Width = WIDTH;
			Params.BufferDesc.Height = HEIGHT;
			Params.BufferDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
			Params.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
		}

		bool DirectX11::InitializeContext(Gwen::WindowProvider* pWindow)
		{
			HWND pHWND = (HWND)pWindow->GetWindow();

			D3D_DRIVER_TYPE driverTypes[] =
			{
				D3D_DRIVER_TYPE_HARDWARE,
				D3D_DRIVER_TYPE_WARP,
				D3D_DRIVER_TYPE_REFERENCE,
			};
			UINT numDriverTypes = 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
			};
			UINT numFeatureLevels = ARRAYSIZE(featureLevels);

			
			DXGI_SWAP_CHAIN_DESC Params;
			FillPresentParameters(pWindow, Params);
			HRESULT hr = S_OK;
			for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
			{
				D3D_DRIVER_TYPE driverType = driverTypes[driverTypeIndex];
				hr = D3D11CreateDeviceAndSwapChain(NULL, driverType, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, featureLevels, numFeatureLevels,
					D3D11_SDK_VERSION, &Params, &m_pSwapChain, &m_pDevice, NULL, &m_pContext);
				if (SUCCEEDED(hr))
					break;
			}
			if (FAILED(hr))
				return false;
			/*
			ID3D11Texture2D* pBackBuffer = NULL;
			hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
			if (FAILED(hr))
			{
				ShutdownContext(pWindow);
				return false;
			}

			ID3D11RenderTargetView* pRenderTargetView;
			hr = m_pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView);
			pBackBuffer->Release();
			if (FAILED(hr))
			{
				ShutdownContext(pWindow);
				return false;
			}

			m_pContext->OMSetRenderTargets(1, &pRenderTargetView, NULL);

			D3D11_VIEWPORT vp;
			vp.Width = (FLOAT)width;
			vp.Height = (FLOAT)height;
			vp.MinDepth = 0.0f;
			vp.MaxDepth = 1.0f;
			vp.TopLeftX = 0;
			vp.TopLeftY = 0;

			m_pContext->RSSetViewports(1, &vp);
			*/
			return true;
		}

		bool DirectX11::ShutdownContext(Gwen::WindowProvider* pWindow)
		{
			ID3D11RenderTargetView* pRenderTargetView;
			m_pContext->OMGetRenderTargets(1, &pRenderTargetView, 0);
			SafeRelease(pRenderTargetView);
			SafeRelease(m_pSwapChain);
			SafeRelease(m_pContext);
			SafeRelease(m_pDevice);
			return true;
		}

		bool DirectX11::PresentContext(Gwen::WindowProvider* pWindow)
		{
			m_pSwapChain->Present(1, 0);
			return true;
		}

		bool DirectX11::ResizedContext(Gwen::WindowProvider* pWindow, int w, int h)
		{

			ID3D11RenderTargetView* pRenderTargetView;
			m_pContext->OMGetRenderTargets(1, &pRenderTargetView, 0);
			SafeRelease(pRenderTargetView);

			m_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);

			ID3D11Texture2D* pBuffer;
			m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
				(void**)&pBuffer);

			m_pDevice->CreateRenderTargetView(pBuffer, NULL,
				&pRenderTargetView);
			// Perform error handling here!
			SafeRelease(pBuffer);

			m_pContext->OMSetRenderTargets(1, &pRenderTargetView, NULL);
			SafeRelease(pRenderTargetView);
			return true;
		}

		bool DirectX11::BeginContext(Gwen::WindowProvider* pWindow)
		{
			float ClearColor[4] = { 0.128f, 0.128f, 0.128, 1.0f }; // red,green,blue,alpha


			ID3D11RenderTargetView* pRenderTargetView;
			m_pContext->OMGetRenderTargets(1, &pRenderTargetView, 0);
			m_pContext->ClearRenderTargetView(pRenderTargetView, ClearColor);
			pRenderTargetView->Release();
			return true;
		}

		bool DirectX11::EndContext(Gwen::WindowProvider* pWindow)
		{
			return true;
		}

#pragma endregion
	}
}

“m_pContext->PSGetShaderResources(0, 1, &m_pCurrentTexture);”
You are calling PSGetShaderResources() instead of PSSetShaderResources().

Also, you should post in the DirectX and XNA section if you have a question about DirectX or XNA.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Advertisement

“m_pContext->PSGetShaderResources(0, 1, &m_pCurrentTexture);”
You are calling PSGetShaderResources() instead of PSSetShaderResources().

Also, you should post in the DirectX and XNA section if you have a question about DirectX or XNA.


L. Spiro

Thank you, so very much. You just saved me a few more hrs of endless searching.

This topic is closed to new replies.

Advertisement