2015-05-06 01:27:59 -04:00
|
|
|
#include "PixelBufferView.h"
|
|
|
|
#include <assert.h>
|
|
|
|
#include <vector>
|
2017-09-13 16:37:04 -04:00
|
|
|
#include <D3Dcompiler.h>
|
2015-05-06 01:27:59 -04:00
|
|
|
#include "../resource.h"
|
2016-10-17 19:52:17 -04:00
|
|
|
#include "../D3D9TextureUtils.h"
|
2015-05-06 01:27:59 -04:00
|
|
|
#include "win32/FileDialog.h"
|
|
|
|
#include "bitmap/BMP.h"
|
|
|
|
#include "StdStreamUtils.h"
|
|
|
|
#include "string_format.h"
|
|
|
|
|
|
|
|
CPixelBufferView::CPixelBufferView(HWND parent, const RECT& rect)
|
2018-04-30 21:01:23 +01:00
|
|
|
: CDirectXControl(parent)
|
|
|
|
, m_zoomFactor(1)
|
|
|
|
, m_panX(0)
|
|
|
|
, m_panY(0)
|
|
|
|
, m_dragging(false)
|
|
|
|
, m_dragBaseX(0)
|
|
|
|
, m_dragBaseY(0)
|
|
|
|
, m_panXDragBase(0)
|
|
|
|
, m_panYDragBase(0)
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
|
|
|
m_overlay = std::make_unique<CPixelBufferViewOverlay>(m_hWnd);
|
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
m_checkerboardVertexShader = CreateVertexShaderFromResource(MAKEINTRESOURCE(IDR_CHECKERBOARD_VERTEXSHADER));
|
|
|
|
m_checkerboardPixelShader = CreatePixelShaderFromResource(MAKEINTRESOURCE(IDR_CHECKERBOARD_PIXELSHADER));
|
|
|
|
m_pixelBufferViewVertexShader = CreateVertexShaderFromResource(MAKEINTRESOURCE(IDR_PIXELBUFFERVIEW_VERTEXSHADER));
|
|
|
|
m_pixelBufferViewPixelShader = CreatePixelShaderFromResource(MAKEINTRESOURCE(IDR_PIXELBUFFERVIEW_PIXELSHADER));
|
2015-05-06 01:27:59 -04:00
|
|
|
SetSizePosition(rect);
|
|
|
|
}
|
|
|
|
|
2016-10-28 18:39:46 -04:00
|
|
|
void CPixelBufferView::SetPixelBuffers(PixelBufferArray pixelBuffers)
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
2016-10-28 18:39:46 -04:00
|
|
|
m_pixelBuffers = std::move(pixelBuffers);
|
|
|
|
//Update buffer titles
|
|
|
|
{
|
|
|
|
CPixelBufferViewOverlay::StringList titles;
|
|
|
|
for(const auto& pixelBuffer : m_pixelBuffers)
|
|
|
|
{
|
|
|
|
titles.push_back(pixelBuffer.first);
|
|
|
|
}
|
2017-04-08 21:38:42 -04:00
|
|
|
//Save previously selected index
|
|
|
|
int selectedIndex = m_overlay->GetSelectedPixelBufferIndex();
|
|
|
|
auto titleCount = titles.size();
|
2016-10-28 18:39:46 -04:00
|
|
|
m_overlay->SetPixelBufferTitles(std::move(titles));
|
2017-04-08 21:38:42 -04:00
|
|
|
//Restore selected index
|
|
|
|
if((selectedIndex != -1) && (selectedIndex < titleCount))
|
|
|
|
{
|
|
|
|
m_overlay->SetSelectedPixelBufferIndex(selectedIndex);
|
|
|
|
}
|
2016-10-28 18:39:46 -04:00
|
|
|
}
|
|
|
|
CreateSelectedPixelBufferTexture();
|
2015-05-06 01:27:59 -04:00
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPixelBufferView::Refresh()
|
|
|
|
{
|
|
|
|
if(m_device.IsEmpty()) return;
|
|
|
|
if(!TestDevice()) return;
|
|
|
|
|
|
|
|
D3DCOLOR backgroundColor = D3DCOLOR_XRGB(0x00, 0x00, 0x00);
|
|
|
|
|
|
|
|
m_device->Clear(0, NULL, D3DCLEAR_TARGET, backgroundColor, 1.0f, 0);
|
|
|
|
m_device->BeginScene();
|
|
|
|
|
|
|
|
DrawCheckerboard();
|
|
|
|
DrawPixelBuffer();
|
|
|
|
|
|
|
|
m_device->EndScene();
|
|
|
|
m_device->Present(NULL, NULL, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPixelBufferView::DrawCheckerboard()
|
|
|
|
{
|
2017-09-13 16:37:04 -04:00
|
|
|
HRESULT result = S_OK;
|
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
m_device->SetVertexDeclaration(m_quadVertexDecl);
|
|
|
|
m_device->SetStreamSource(0, m_quadVertexBuffer, 0, sizeof(VERTEX));
|
|
|
|
|
|
|
|
RECT clientRect = GetClientRect();
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
float screenSizeVector[4] =
|
|
|
|
{
|
|
|
|
static_cast<float>(clientRect.right),
|
|
|
|
static_cast<float>(clientRect.bottom),
|
|
|
|
0,
|
|
|
|
0};
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
m_device->SetVertexShader(m_checkerboardVertexShader);
|
|
|
|
m_device->SetPixelShader(m_checkerboardPixelShader);
|
|
|
|
m_device->SetVertexShaderConstantF(0, screenSizeVector, 1);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
result = m_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
|
|
|
assert(SUCCEEDED(result));
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPixelBufferView::DrawPixelBuffer()
|
|
|
|
{
|
2016-10-28 18:39:46 -04:00
|
|
|
auto pixelBuffer = GetSelectedPixelBuffer();
|
|
|
|
if(!pixelBuffer) return;
|
|
|
|
const auto& pixelBufferBitmap = pixelBuffer->second;
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
HRESULT result = S_OK;
|
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
m_device->SetVertexDeclaration(m_quadVertexDecl);
|
|
|
|
m_device->SetStreamSource(0, m_quadVertexBuffer, 0, sizeof(VERTEX));
|
|
|
|
|
|
|
|
RECT clientRect = GetClientRect();
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
float screenSizeVector[4] =
|
|
|
|
{
|
|
|
|
static_cast<float>(clientRect.right),
|
|
|
|
static_cast<float>(clientRect.bottom),
|
|
|
|
0,
|
|
|
|
0};
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
float bufferSizeVector[4] =
|
2018-04-30 21:01:23 +01:00
|
|
|
{
|
|
|
|
static_cast<float>(pixelBufferBitmap.GetWidth()),
|
|
|
|
static_cast<float>(pixelBufferBitmap.GetHeight()),
|
|
|
|
0,
|
|
|
|
0};
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
float panOffsetVector[4] = {m_panX, m_panY, 0, 0};
|
|
|
|
float zoomFactorVector[4] = {m_zoomFactor, 0, 0, 0};
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
m_device->SetVertexShader(m_pixelBufferViewVertexShader);
|
|
|
|
m_device->SetPixelShader(m_pixelBufferViewPixelShader);
|
|
|
|
m_device->SetVertexShaderConstantF(0, screenSizeVector, 1);
|
|
|
|
m_device->SetVertexShaderConstantF(1, bufferSizeVector, 1);
|
|
|
|
m_device->SetVertexShaderConstantF(2, panOffsetVector, 1);
|
|
|
|
m_device->SetVertexShaderConstantF(3, zoomFactorVector, 1);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
m_device->SetTexture(0, m_pixelBufferTexture);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
result = m_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
|
|
|
assert(SUCCEEDED(result));
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
long CPixelBufferView::OnCommand(unsigned short id, unsigned short cmd, HWND hwndFrom)
|
|
|
|
{
|
|
|
|
if(CWindow::IsCommandSource(m_overlay.get(), hwndFrom))
|
|
|
|
{
|
|
|
|
switch(cmd)
|
|
|
|
{
|
|
|
|
case CPixelBufferViewOverlay::COMMAND_SAVE:
|
|
|
|
OnSaveBitmap();
|
|
|
|
break;
|
|
|
|
case CPixelBufferViewOverlay::COMMAND_FIT:
|
|
|
|
FitBitmap();
|
|
|
|
break;
|
2016-10-28 18:39:46 -04:00
|
|
|
case CPixelBufferViewOverlay::COMMAND_PIXELBUFFER_CHANGED:
|
|
|
|
CreateSelectedPixelBufferTexture();
|
|
|
|
Refresh();
|
|
|
|
break;
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
long CPixelBufferView::OnSize(unsigned int type, unsigned int x, unsigned int y)
|
|
|
|
{
|
|
|
|
long result = CDirectXControl::OnSize(type, x, y);
|
|
|
|
Refresh();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
long CPixelBufferView::OnLeftButtonDown(int x, int y)
|
|
|
|
{
|
|
|
|
SetCapture(m_hWnd);
|
|
|
|
m_dragBaseX = x;
|
|
|
|
m_dragBaseY = y;
|
|
|
|
m_panXDragBase = m_panX;
|
|
|
|
m_panYDragBase = m_panY;
|
|
|
|
m_dragging = true;
|
|
|
|
return CDirectXControl::OnLeftButtonDown(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
long CPixelBufferView::OnLeftButtonUp(int x, int y)
|
|
|
|
{
|
|
|
|
m_dragging = false;
|
|
|
|
ReleaseCapture();
|
|
|
|
return CDirectXControl::OnLeftButtonUp(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
long CPixelBufferView::OnMouseMove(WPARAM wparam, int x, int y)
|
|
|
|
{
|
|
|
|
if(m_dragging)
|
|
|
|
{
|
|
|
|
RECT clientRect = GetClientRect();
|
|
|
|
m_panX = m_panXDragBase + (static_cast<float>(x - m_dragBaseX) / static_cast<float>(clientRect.right / 2)) / m_zoomFactor;
|
|
|
|
m_panY = m_panYDragBase - (static_cast<float>(y - m_dragBaseY) / static_cast<float>(clientRect.bottom / 2)) / m_zoomFactor;
|
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
return CDirectXControl::OnMouseMove(wparam, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
long CPixelBufferView::OnMouseWheel(int x, int y, short z)
|
|
|
|
{
|
|
|
|
float newZoom = 0;
|
|
|
|
z /= WHEEL_DELTA;
|
|
|
|
if(z <= -1)
|
|
|
|
{
|
|
|
|
newZoom = m_zoomFactor / 2;
|
|
|
|
}
|
|
|
|
else if(z >= 1)
|
|
|
|
{
|
|
|
|
newZoom = m_zoomFactor * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(newZoom != 0)
|
|
|
|
{
|
|
|
|
auto clientRect = GetClientRect();
|
2018-04-30 21:01:23 +01:00
|
|
|
POINT mousePoint = {x, y};
|
2015-05-06 01:27:59 -04:00
|
|
|
ScreenToClient(m_hWnd, &mousePoint);
|
|
|
|
float relPosX = static_cast<float>(mousePoint.x) / static_cast<float>(clientRect.Right());
|
|
|
|
float relPosY = static_cast<float>(mousePoint.y) / static_cast<float>(clientRect.Bottom());
|
2018-04-30 21:01:23 +01:00
|
|
|
relPosX = std::max(relPosX, 0.f);
|
|
|
|
relPosX = std::min(relPosX, 1.f);
|
|
|
|
relPosY = std::max(relPosY, 0.f);
|
|
|
|
relPosY = std::min(relPosY, 1.f);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
|
|
|
relPosX = (relPosX - 0.5f) * 2;
|
|
|
|
relPosY = (relPosY - 0.5f) * 2;
|
|
|
|
|
|
|
|
float panModX = (1 - newZoom / m_zoomFactor) * relPosX;
|
|
|
|
float panModY = (1 - newZoom / m_zoomFactor) * relPosY;
|
|
|
|
m_panX += panModX;
|
|
|
|
m_panY -= panModY;
|
|
|
|
|
|
|
|
m_zoomFactor = newZoom;
|
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPixelBufferView::OnDeviceReset()
|
|
|
|
{
|
|
|
|
CreateResources();
|
2016-10-28 18:39:46 -04:00
|
|
|
CreateSelectedPixelBufferTexture();
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPixelBufferView::OnDeviceResetting()
|
|
|
|
{
|
|
|
|
m_quadVertexBuffer.Reset();
|
|
|
|
m_quadVertexDecl.Reset();
|
|
|
|
m_pixelBufferTexture.Reset();
|
|
|
|
}
|
|
|
|
|
2016-10-28 18:39:46 -04:00
|
|
|
const CPixelBufferView::PixelBuffer* CPixelBufferView::GetSelectedPixelBuffer()
|
|
|
|
{
|
|
|
|
if(m_pixelBuffers.empty()) return nullptr;
|
2018-04-30 21:01:23 +01:00
|
|
|
|
2016-10-28 18:39:46 -04:00
|
|
|
int selectedPixelBufferIndex = m_overlay->GetSelectedPixelBufferIndex();
|
|
|
|
if(selectedPixelBufferIndex < 0) return nullptr;
|
|
|
|
|
|
|
|
assert(selectedPixelBufferIndex < m_pixelBuffers.size());
|
|
|
|
if(selectedPixelBufferIndex >= m_pixelBuffers.size()) return nullptr;
|
|
|
|
|
|
|
|
return &m_pixelBuffers[selectedPixelBufferIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPixelBufferView::CreateSelectedPixelBufferTexture()
|
|
|
|
{
|
|
|
|
m_pixelBufferTexture.Reset();
|
|
|
|
|
|
|
|
auto pixelBuffer = GetSelectedPixelBuffer();
|
|
|
|
if(!pixelBuffer) return;
|
|
|
|
|
|
|
|
m_pixelBufferTexture = CreateTextureFromBitmap(pixelBuffer->second);
|
|
|
|
}
|
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
void CPixelBufferView::OnSaveBitmap()
|
|
|
|
{
|
2016-10-28 18:39:46 -04:00
|
|
|
auto pixelBuffer = GetSelectedPixelBuffer();
|
|
|
|
if(!pixelBuffer) return;
|
2016-11-07 10:24:40 -05:00
|
|
|
auto pixelBufferBitmap = pixelBuffer->second;
|
|
|
|
|
|
|
|
auto bpp = pixelBufferBitmap.GetBitsPerPixel();
|
|
|
|
if((bpp == 24) || (bpp == 32))
|
|
|
|
{
|
|
|
|
pixelBufferBitmap = ConvertBGRToRGB(std::move(pixelBufferBitmap));
|
|
|
|
}
|
2016-10-28 18:39:46 -04:00
|
|
|
|
|
|
|
Framework::Win32::CFileDialog openFileDialog;
|
|
|
|
openFileDialog.m_OFN.lpstrFilter = _T("Windows Bitmap Files (*.bmp)\0*.bmp");
|
|
|
|
int result = openFileDialog.SummonSave(m_hWnd);
|
|
|
|
if(result == IDOK)
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
2016-10-28 18:39:46 -04:00
|
|
|
try
|
|
|
|
{
|
|
|
|
auto outputStream = Framework::CreateOutputStdStream(std::tstring(openFileDialog.m_OFN.lpstrFile));
|
|
|
|
Framework::CBMP::WriteBitmap(pixelBufferBitmap, outputStream);
|
|
|
|
}
|
|
|
|
catch(const std::exception& exception)
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
2016-10-28 18:39:46 -04:00
|
|
|
auto message = string_format("Failed to save buffer to file:\r\n\r\n%s", exception.what());
|
|
|
|
MessageBoxA(m_hWnd, message.c_str(), nullptr, MB_ICONHAND);
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-07 10:24:40 -05:00
|
|
|
Framework::CBitmap CPixelBufferView::ConvertBGRToRGB(Framework::CBitmap bitmap)
|
|
|
|
{
|
|
|
|
for(int32 y = 0; y < bitmap.GetHeight(); y++)
|
|
|
|
{
|
|
|
|
for(int32 x = 0; x < bitmap.GetWidth(); x++)
|
|
|
|
{
|
|
|
|
auto color = bitmap.GetPixel(x, y);
|
|
|
|
std::swap(color.r, color.b);
|
|
|
|
bitmap.SetPixel(x, y, color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::move(bitmap);
|
|
|
|
}
|
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
void CPixelBufferView::FitBitmap()
|
|
|
|
{
|
2016-10-28 18:39:46 -04:00
|
|
|
auto pixelBuffer = GetSelectedPixelBuffer();
|
|
|
|
if(!pixelBuffer) return;
|
|
|
|
const auto& pixelBufferBitmap = pixelBuffer->second;
|
2015-05-06 01:27:59 -04:00
|
|
|
|
|
|
|
Framework::Win32::CRect clientRect = GetClientRect();
|
|
|
|
unsigned int marginSize = 50;
|
2016-10-28 18:39:46 -04:00
|
|
|
float normalizedSizeX = static_cast<float>(pixelBufferBitmap.GetWidth()) / static_cast<float>(clientRect.Right() - marginSize);
|
|
|
|
float normalizedSizeY = static_cast<float>(pixelBufferBitmap.GetHeight()) / static_cast<float>(clientRect.Bottom() - marginSize);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
|
|
|
float normalizedSize = std::max<float>(normalizedSizeX, normalizedSizeY);
|
|
|
|
|
|
|
|
m_zoomFactor = 1 / normalizedSize;
|
|
|
|
m_panX = 0;
|
|
|
|
m_panY = 0;
|
|
|
|
|
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPixelBufferView::CreateResources()
|
|
|
|
{
|
|
|
|
static const VERTEX g_quadVertexBufferVertices[4] =
|
2018-04-30 21:01:23 +01:00
|
|
|
{
|
|
|
|
{-1, -1, 0, 0, 1},
|
|
|
|
{-1, 1, 0, 0, 0},
|
|
|
|
{1, -1, 0, 1, 1},
|
|
|
|
{1, 1, 0, 1, 0},
|
|
|
|
};
|
2015-05-06 01:27:59 -04:00
|
|
|
|
|
|
|
HRESULT result = S_OK;
|
2018-04-30 21:01:23 +01:00
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
result = m_device->CreateVertexBuffer(sizeof(g_quadVertexBufferVertices), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_quadVertexBuffer, nullptr);
|
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
|
|
|
|
{
|
|
|
|
void* vertexBufferData(nullptr);
|
|
|
|
result = m_quadVertexBuffer->Lock(0, 0, &vertexBufferData, 0);
|
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
|
|
|
|
memcpy(vertexBufferData, g_quadVertexBufferVertices, sizeof(g_quadVertexBufferVertices));
|
|
|
|
|
|
|
|
result = m_quadVertexBuffer->Unlock();
|
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::vector<D3DVERTEXELEMENT9> vertexElements;
|
2018-04-30 21:01:23 +01:00
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
|
|
|
D3DVERTEXELEMENT9 element = {};
|
2018-04-30 21:01:23 +01:00
|
|
|
element.Offset = offsetof(VERTEX, position);
|
|
|
|
element.Type = D3DDECLTYPE_FLOAT3;
|
|
|
|
element.Usage = D3DDECLUSAGE_POSITION;
|
2015-05-06 01:27:59 -04:00
|
|
|
vertexElements.push_back(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
D3DVERTEXELEMENT9 element = {};
|
2018-04-30 21:01:23 +01:00
|
|
|
element.Offset = offsetof(VERTEX, texCoord);
|
|
|
|
element.Type = D3DDECLTYPE_FLOAT2;
|
|
|
|
element.Usage = D3DDECLUSAGE_TEXCOORD;
|
2015-05-06 01:27:59 -04:00
|
|
|
vertexElements.push_back(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
D3DVERTEXELEMENT9 element = D3DDECL_END();
|
|
|
|
vertexElements.push_back(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
result = m_device->CreateVertexDeclaration(vertexElements.data(), &m_quadVertexDecl);
|
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
CPixelBufferView::VertexShaderPtr CPixelBufferView::CreateVertexShaderFromResource(const TCHAR* resourceName)
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
|
|
|
HRESULT result = S_OK;
|
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
auto shaderResourceInfo = FindResource(GetModuleHandle(nullptr), resourceName, _T("TEXTFILE"));
|
2015-05-06 01:27:59 -04:00
|
|
|
assert(shaderResourceInfo != nullptr);
|
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
auto shaderResourceHandle = LoadResource(GetModuleHandle(nullptr), shaderResourceInfo);
|
|
|
|
auto shaderResourceSize = SizeofResource(GetModuleHandle(nullptr), shaderResourceInfo);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
auto shaderResource = reinterpret_cast<const char*>(LockResource(shaderResourceHandle));
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
UINT compileFlags = 0;
|
|
|
|
#ifdef _DEBUG
|
|
|
|
compileFlags |= D3DCOMPILE_DEBUG;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Framework::Win32::CComPtr<ID3DBlob> shaderBinary;
|
|
|
|
Framework::Win32::CComPtr<ID3DBlob> compileErrors;
|
2018-04-30 21:01:23 +01:00
|
|
|
result = D3DCompile(shaderResource, shaderResourceSize, "vs", nullptr, nullptr, "main",
|
|
|
|
"vs_3_0", compileFlags, 0, &shaderBinary, &compileErrors);
|
2015-05-06 01:27:59 -04:00
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
VertexShaderPtr shader;
|
|
|
|
result = m_device->CreateVertexShader(reinterpret_cast<DWORD*>(shaderBinary->GetBufferPointer()), &shader);
|
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
|
|
|
|
return shader;
|
|
|
|
}
|
|
|
|
|
|
|
|
CPixelBufferView::PixelShaderPtr CPixelBufferView::CreatePixelShaderFromResource(const TCHAR* resourceName)
|
|
|
|
{
|
|
|
|
HRESULT result = S_OK;
|
|
|
|
|
|
|
|
auto shaderResourceInfo = FindResource(GetModuleHandle(nullptr), resourceName, _T("TEXTFILE"));
|
|
|
|
assert(shaderResourceInfo != nullptr);
|
|
|
|
|
|
|
|
auto shaderResourceHandle = LoadResource(GetModuleHandle(nullptr), shaderResourceInfo);
|
|
|
|
auto shaderResourceSize = SizeofResource(GetModuleHandle(nullptr), shaderResourceInfo);
|
|
|
|
|
|
|
|
auto shaderResource = reinterpret_cast<const char*>(LockResource(shaderResourceHandle));
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2017-09-13 16:37:04 -04:00
|
|
|
UINT compileFlags = 0;
|
|
|
|
#ifdef _DEBUG
|
|
|
|
compileFlags |= D3DCOMPILE_DEBUG;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Framework::Win32::CComPtr<ID3DBlob> shaderBinary;
|
|
|
|
Framework::Win32::CComPtr<ID3DBlob> compileErrors;
|
2018-04-30 21:01:23 +01:00
|
|
|
result = D3DCompile(shaderResource, shaderResourceSize, "ps", nullptr, nullptr, "main",
|
|
|
|
"ps_3_0", compileFlags, 0, &shaderBinary, &compileErrors);
|
2017-09-13 16:37:04 -04:00
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
|
|
|
|
PixelShaderPtr shader;
|
|
|
|
result = m_device->CreatePixelShader(reinterpret_cast<DWORD*>(shaderBinary->GetBufferPointer()), &shader);
|
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
|
|
|
|
return shader;
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
CPixelBufferView::TexturePtr CPixelBufferView::CreateTextureFromBitmap(const Framework::CBitmap& bitmap)
|
|
|
|
{
|
|
|
|
TexturePtr texture;
|
|
|
|
|
|
|
|
if(!bitmap.IsEmpty())
|
|
|
|
{
|
2016-10-17 19:52:17 -04:00
|
|
|
D3DFORMAT textureFormat =
|
2018-04-30 21:01:23 +01:00
|
|
|
[bitmap]() {
|
|
|
|
switch(bitmap.GetBitsPerPixel())
|
|
|
|
{
|
|
|
|
case 8:
|
|
|
|
return D3DFMT_L8;
|
|
|
|
case 16:
|
|
|
|
return D3DFMT_A1R5G5B5;
|
|
|
|
case 32:
|
|
|
|
default:
|
|
|
|
return D3DFMT_A8R8G8B8;
|
|
|
|
}
|
|
|
|
}();
|
2016-10-17 19:52:17 -04:00
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
HRESULT result = S_OK;
|
2016-10-17 19:52:17 -04:00
|
|
|
result = m_device->CreateTexture(bitmap.GetWidth(), bitmap.GetHeight(), 1, D3DUSAGE_DYNAMIC, textureFormat, D3DPOOL_DEFAULT, &texture, nullptr);
|
2015-05-06 01:27:59 -04:00
|
|
|
assert(SUCCEEDED(result));
|
|
|
|
|
2016-10-17 19:52:17 -04:00
|
|
|
switch(bitmap.GetBitsPerPixel())
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
2016-10-17 19:52:17 -04:00
|
|
|
case 8:
|
|
|
|
CopyBitmapToTexture<uint8>(texture, 0, bitmap);
|
|
|
|
break;
|
2016-12-22 11:47:23 -05:00
|
|
|
case 16:
|
|
|
|
CopyBitmapToTexture<uint16>(texture, 0, bitmap);
|
|
|
|
break;
|
2016-10-17 19:52:17 -04:00
|
|
|
case 32:
|
|
|
|
CopyBitmapToTexture<uint32>(texture, 0, bitmap);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(false);
|
|
|
|
break;
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return texture;
|
|
|
|
}
|