chore: overhaul renderer decompilation to match as closely as possible to the original
Co-authored-by: la <76826837+3UR@users.noreply.github.com>
This commit is contained in:
committed by
la
co-authored by
la
parent
cc6aade337
commit
39339e821e
@@ -27,11 +27,20 @@ SOFTWARE.
|
||||
// requires linking Minecraft.Client against Ws2_32.lib
|
||||
// stats are available at http://127.0.0.1:1338/
|
||||
|
||||
//#define ENABLE_PROFILING
|
||||
#define ENABLE_PROFILING
|
||||
|
||||
#ifdef ENABLE_PROFILING
|
||||
#include "microprofile/microprofile.h"
|
||||
#define PROFILER_INIT() \
|
||||
do \
|
||||
{ \
|
||||
MicroProfileOnThreadCreate("MainRenderThread"); \
|
||||
MicroProfileSetEnableAllGroups(true); \
|
||||
} while (0)
|
||||
#define PROFILER_FLIP() MicroProfileFlip(NULL);
|
||||
#define PROFILER_SCOPE(group, name, color) MICROPROFILE_SCOPEI(group, name, color);
|
||||
#else
|
||||
#define PROFILER_INIT() ((void)0);
|
||||
#define PROFILER_FLIP() ((void)0);
|
||||
#define PROFILER_SCOPE(group, name, color) ((void)0);
|
||||
#endif
|
||||
@@ -350,7 +350,7 @@ public:
|
||||
|
||||
ID3D11DeviceContext *m_pDeviceContext;
|
||||
ID3DUserDefinedAnnotation *userAnnotation;
|
||||
DWORD annotateDepth;
|
||||
int annotateDepth;
|
||||
DirectX::XMMATRIX matrixStacks[MATRIX_MODE_MODELVIEW_MAX][STACK_SIZE];
|
||||
bool matrixDirty[MATRIX_MODE_MODELVIEW_MAX];
|
||||
DWORD stackPos[MATRIX_MODE_MODELVIEW_MAX];
|
||||
@@ -416,6 +416,7 @@ public:
|
||||
static DXGI_FORMAT textureFormats[];
|
||||
static D3D_PRIMITIVE_TOPOLOGY g_topologies[];
|
||||
static int totalAlloc;
|
||||
static const float PI;
|
||||
|
||||
float m_fClearColor[4];
|
||||
ID3D11Device *m_pDevice;
|
||||
@@ -457,9 +458,9 @@ public:
|
||||
DWORD reservedRendererDword1;
|
||||
int16_t *m_commandHandleToIndex;
|
||||
CommandBuffer **m_commandBuffers;
|
||||
uint8_t *m_commandPrimitiveTypes;
|
||||
DirectX::XMMATRIX *m_commandMatrices;
|
||||
int *m_commandIndexToHandle;
|
||||
uint8_t *m_commandPrimitiveTypes;
|
||||
uint8_t *m_commandVertexTypes;
|
||||
DWORD reservedRendererDword2;
|
||||
DWORD reservedRendererDword3;
|
||||
|
||||
@@ -37,7 +37,7 @@ Renderer::CommandBuffer::CommandBuffer(bool full)
|
||||
, m_allocated(0x1000)
|
||||
, isActive(full ? 1 : 0)
|
||||
{
|
||||
m_vertexData = malloc(m_allocated);
|
||||
m_vertexData = std::malloc(m_allocated);
|
||||
EnterCriticalSection(&Renderer::totalAllocCS);
|
||||
Renderer::totalAlloc += static_cast<int>(m_allocated);
|
||||
LeaveCriticalSection(&Renderer::totalAllocCS);
|
||||
@@ -48,54 +48,24 @@ Renderer::CommandBuffer::~CommandBuffer()
|
||||
if (m_vertexBuffer)
|
||||
m_vertexBuffer->Release();
|
||||
|
||||
free(m_vertexData);
|
||||
std::free(m_vertexData);
|
||||
|
||||
EnterCriticalSection(&Renderer::totalAllocCS);
|
||||
Renderer::totalAlloc -= static_cast<int>(m_allocated);
|
||||
LeaveCriticalSection(&Renderer::totalAllocCS);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::StartRecording() {}
|
||||
|
||||
void Renderer::CommandBuffer::EndRecording(ID3D11Device *device)
|
||||
{
|
||||
if (m_vertexDataLength != 0)
|
||||
{
|
||||
D3D11_BUFFER_DESC desc = {};
|
||||
desc.ByteWidth = static_cast<UINT>(m_vertexDataLength);
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA data = {};
|
||||
data.pSysMem = m_vertexData;
|
||||
device->CreateBuffer(&desc, &data, &m_vertexBuffer);
|
||||
}
|
||||
|
||||
free(m_vertexData);
|
||||
m_vertexData = NULL;
|
||||
}
|
||||
|
||||
std::uint64_t Renderer::CommandBuffer::GetAllocated()
|
||||
{
|
||||
return m_allocated;
|
||||
}
|
||||
|
||||
bool Renderer::CommandBuffer::IsBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::AddMatrix(const float *matrix)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_ADD_MATRIX;
|
||||
memcpy(command.add_matrix.m_matrix, matrix, sizeof(command.add_matrix.m_matrix));
|
||||
std::memcpy(command.add_matrix.m_matrix, matrix, sizeof(command.add_matrix.m_matrix));
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::AddVertices(unsigned int stride, unsigned int count, void *dataIn, Renderer::Context &c)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::CommandBuffer::AddVertices", "AddVertices", MP_ORANGE)
|
||||
PROFILER_SCOPE("Renderer::CommandBuffer::AddVertices", "AddVertices", MP_ORANGE);
|
||||
|
||||
if (c.matrixDirty[MATRIX_MODE_MODELVIEW_CBUFF])
|
||||
{
|
||||
@@ -108,7 +78,7 @@ void Renderer::CommandBuffer::AddVertices(unsigned int stride, unsigned int coun
|
||||
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_ADD_VERTICES;
|
||||
command.add_vertices.m_vertex_index_start = (unsigned int)vertexOffset;
|
||||
command.add_vertices.m_vertex_index_start = static_cast<unsigned int>(vertexOffset);
|
||||
command.add_vertices.m_vertex_count = count;
|
||||
|
||||
m_vertexDataLength = vertexOffset + copySize;
|
||||
@@ -127,7 +97,7 @@ void Renderer::CommandBuffer::AddVertices(unsigned int stride, unsigned int coun
|
||||
}
|
||||
|
||||
const std::size_t byteCount = std::size_t(stride) * std::size_t(count);
|
||||
memcpy(static_cast<std::uint8_t *>(m_vertexData) + vertexOffset, dataIn, byteCount);
|
||||
std::memcpy(static_cast<std::uint8_t*>(m_vertexData) + vertexOffset, dataIn, byteCount);
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
@@ -139,356 +109,6 @@ void Renderer::CommandBuffer::BindTexture(int idx)
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetColor(float r, float g, float b, float a)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_COLOR;
|
||||
command.set_color.m_color[0] = r;
|
||||
command.set_color.m_color[1] = g;
|
||||
command.set_color.m_color[2] = b;
|
||||
command.set_color.m_color[3] = a;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetDepthFunc(int func)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_DEPTH_FUNC;
|
||||
command.set_depth_func.m_depth_func = func;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetDepthMask(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_DEPTH_MASK;
|
||||
command.set_depth_mask.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetDepthTestEnable(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_DEPTH_TEST;
|
||||
command.set_depth_test.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightingEnable(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHTING_ENABLE;
|
||||
command.set_lighting_enable.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightEnable(int light, bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_ENABLE;
|
||||
command.set_light_enable.m_light_index = light;
|
||||
command.set_light_enable.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightDirection(int light, float x, float y, float z)
|
||||
{
|
||||
Renderer::Context &c = InternalRenderManager.getContext();
|
||||
const std::uint32_t depth = c.stackPos[MATRIX_MODE_MODELVIEW_CBUFF];
|
||||
const DirectX::XMMATRIX &matrix = c.matrixStacks[MATRIX_MODE_MODELVIEW_CBUFF][depth];
|
||||
|
||||
DirectX::XMVECTOR direction = DirectX::XMVectorSet(x, y, z, 0.0f);
|
||||
direction = DirectX::XMVector3TransformNormal(direction, matrix);
|
||||
direction = DirectX::XMVector3Normalize(direction);
|
||||
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_DIRECTION;
|
||||
command.set_light_direction.m_light_index = light;
|
||||
DirectX::XMFLOAT4 outDirection;
|
||||
DirectX::XMStoreFloat4(&outDirection, direction);
|
||||
command.set_light_direction.m_direction[0] = outDirection.x;
|
||||
command.set_light_direction.m_direction[1] = outDirection.y;
|
||||
command.set_light_direction.m_direction[2] = outDirection.z;
|
||||
command.set_light_direction.m_direction[3] = outDirection.w;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightColour(int light, float r, float g, float b)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_COLOUR;
|
||||
command.set_light_colour.m_light_index = light;
|
||||
command.set_light_colour.m_color[0] = r;
|
||||
command.set_light_colour.m_color[1] = g;
|
||||
command.set_light_colour.m_color[2] = b;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightAmbientColour(float r, float g, float b)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_AMBIENT_COLOUR;
|
||||
command.set_light_ambient_colour.m_color[0] = r;
|
||||
command.set_light_ambient_colour.m_color[1] = g;
|
||||
command.set_light_ambient_colour.m_color[2] = b;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetBlendEnable(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_BLEND_ENABLE;
|
||||
command.set_blend_enable.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetBlendFunc(int src, int dst)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_BLEND_FUNC;
|
||||
command.set_blend_func.m_src = src;
|
||||
command.set_blend_func.m_dst = dst;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetBlendFactor(unsigned int factor)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_BLEND_FACTOR;
|
||||
command.set_blend_factor.m_blend_factor = factor;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetFaceCull(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_FACE_CULL;
|
||||
command.set_face_cull.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Context &c, int primitiveType)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::CommandBuffer::Render", "Render", MP_ORANGE)
|
||||
|
||||
if (!m_vertexBuffer)
|
||||
return;
|
||||
|
||||
int drawVertexType = vType;
|
||||
int shaderVertexType = drawVertexType;
|
||||
bool matrixOverride = false;
|
||||
|
||||
for (const Command &command : m_commands)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::CommandBuffer::Render", "ProcessCommand", MP_ORANGE)
|
||||
|
||||
switch (command.m_command_type)
|
||||
{
|
||||
case COMMAND_ADD_MATRIX:
|
||||
{
|
||||
if (drawVertexType == C4JRender::VERTEX_TYPE_COMPRESSED)
|
||||
{
|
||||
const float row[4] = {
|
||||
command.add_matrix.m_matrix[12], command.add_matrix.m_matrix[13],
|
||||
command.add_matrix.m_matrix[14], command.add_matrix.m_matrix[15]
|
||||
};
|
||||
D3D11_MAPPED_SUBRESOURCE mappedAux0 = {};
|
||||
c.m_pDeviceContext->Map(c.m_compressedTranslationBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedAux0);
|
||||
memcpy(mappedAux0.pData, row, sizeof(row));
|
||||
c.m_pDeviceContext->Unmap(c.m_compressedTranslationBuffer, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedMatrix1 = {};
|
||||
c.m_pDeviceContext->Map(c.m_localTransformMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix1);
|
||||
memcpy(mappedMatrix1.pData, command.add_matrix.m_matrix, sizeof(command.add_matrix.m_matrix));
|
||||
c.m_pDeviceContext->Unmap(c.m_localTransformMatrix, 0);
|
||||
matrixOverride = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_ADD_VERTICES:
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
InternalRenderManager.UpdateLightingState();
|
||||
|
||||
if (drawVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1)
|
||||
{
|
||||
if (c.lightingEnabled)
|
||||
{
|
||||
drawVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT;
|
||||
shaderVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT;
|
||||
}
|
||||
}
|
||||
else if (drawVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT && !c.lightingEnabled)
|
||||
{
|
||||
drawVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1;
|
||||
shaderVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1;
|
||||
}
|
||||
|
||||
if (static_cast<DWORD>(drawVertexType) != InternalRenderManager.activeVertexType)
|
||||
{
|
||||
c.m_pDeviceContext->VSSetShader(InternalRenderManager.vertexShaderTable[shaderVertexType], NULL, 0);
|
||||
c.m_pDeviceContext->IASetInputLayout(InternalRenderManager.inputLayoutTable[shaderVertexType]);
|
||||
InternalRenderManager.activeVertexType = drawVertexType;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int drawCount = command.add_vertices.m_vertex_count;
|
||||
bool drawIndexed = false;
|
||||
if (primitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST)
|
||||
{
|
||||
drawCount = (drawCount * 6) / 4;
|
||||
drawIndexed = true;
|
||||
}
|
||||
else if (primitiveType == C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN)
|
||||
{
|
||||
drawCount = (drawCount - 2) * 3;
|
||||
drawIndexed = true;
|
||||
}
|
||||
|
||||
ID3D11Buffer *buffer = m_vertexBuffer;
|
||||
const UINT stride = InternalRenderManager.vertexStrideTable[drawVertexType];
|
||||
const UINT offset = command.add_vertices.m_vertex_index_start;
|
||||
c.m_pDeviceContext->IASetVertexBuffers(0, 1, &buffer, &stride, &offset);
|
||||
|
||||
if (drawIndexed)
|
||||
c.m_pDeviceContext->DrawIndexed(drawCount, 0, 0);
|
||||
else
|
||||
c.m_pDeviceContext->Draw(drawCount, 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_BIND_TEXTURE:
|
||||
{
|
||||
c.textureIdx = command.bind_texture.m_texture_index;
|
||||
ID3D11ShaderResourceView *view = InternalRenderManager.m_textures[c.textureIdx].view;
|
||||
c.m_pDeviceContext->PSSetShaderResources(0, 1, &view);
|
||||
InternalRenderManager.UpdateTextureState(false);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_COLOR:
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedColour = {};
|
||||
c.m_pDeviceContext->Map(c.m_tintColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedColour);
|
||||
memcpy(mappedColour.pData, command.set_color.m_color, sizeof(command.set_color.m_color));
|
||||
c.m_pDeviceContext->Unmap(c.m_tintColorBuffer, 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_DEPTH_FUNC:
|
||||
{
|
||||
c.depthStencilDesc.DepthFunc = static_cast<D3D11_COMPARISON_FUNC>(command.set_depth_func.m_depth_func);
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_DEPTH_MASK:
|
||||
{
|
||||
c.depthWriteEnabled = command.set_depth_mask.m_enable;
|
||||
c.depthStencilDesc.DepthWriteMask = command.set_depth_mask.m_enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_DEPTH_TEST:
|
||||
{
|
||||
c.depthTestEnabled = command.set_depth_test.m_enable;
|
||||
c.depthStencilDesc.DepthEnable = command.set_depth_test.m_enable;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHTING_ENABLE:
|
||||
{
|
||||
c.lightingEnabled = command.set_lighting_enable.m_enable;
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_ENABLE:
|
||||
{
|
||||
const int light = command.set_light_enable.m_light_index;
|
||||
if (light >= 0 && light < 2)
|
||||
{
|
||||
c.lightEnabled[light] = command.set_light_enable.m_enable;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_DIRECTION:
|
||||
{
|
||||
const int light = command.set_light_direction.m_light_index;
|
||||
if (light >= 0 && light < 2)
|
||||
{
|
||||
c.lightDirection[light].x = command.set_light_direction.m_direction[0];
|
||||
c.lightDirection[light].y = command.set_light_direction.m_direction[1];
|
||||
c.lightDirection[light].z = command.set_light_direction.m_direction[2];
|
||||
c.lightDirection[light].w = command.set_light_direction.m_direction[3];
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_COLOUR:
|
||||
{
|
||||
const int light = command.set_light_colour.m_light_index;
|
||||
if (light >= 0 && light < 2)
|
||||
{
|
||||
c.lightColour[light].x = command.set_light_colour.m_color[0];
|
||||
c.lightColour[light].y = command.set_light_colour.m_color[1];
|
||||
c.lightColour[light].z = command.set_light_colour.m_color[2];
|
||||
c.lightColour[light].w = 1.0f;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_AMBIENT_COLOUR:
|
||||
{
|
||||
c.lightAmbientColour.x = command.set_light_ambient_colour.m_color[0];
|
||||
c.lightAmbientColour.y = command.set_light_ambient_colour.m_color[1];
|
||||
c.lightAmbientColour.z = command.set_light_ambient_colour.m_color[2];
|
||||
c.lightAmbientColour.w = 1.0f;
|
||||
c.lightingDirty = true;
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_BLEND_ENABLE:
|
||||
{
|
||||
c.blendDesc.RenderTarget[0].BlendEnable = command.set_blend_enable.m_enable;
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_BLEND_FUNC:
|
||||
{
|
||||
c.blendDesc.RenderTarget[0].SrcBlend = static_cast<D3D11_BLEND>(command.set_blend_func.m_src);
|
||||
c.blendDesc.RenderTarget[0].DestBlend = static_cast<D3D11_BLEND>(command.set_blend_func.m_dst);
|
||||
c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_BLEND_FACTOR:
|
||||
{
|
||||
const unsigned int factor = command.set_blend_factor.m_blend_factor;
|
||||
c.blendFactor[0] = float((factor >> 0) & 0xFF) / 255.0f;
|
||||
c.blendFactor[1] = float((factor >> 8) & 0xFF) / 255.0f;
|
||||
c.blendFactor[2] = float((factor >> 16) & 0xFF) / 255.0f;
|
||||
c.blendFactor[3] = float((factor >> 24) & 0xFF) / 255.0f;
|
||||
c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_FACE_CULL:
|
||||
{
|
||||
c.rasterizerDesc.CullMode = command.set_face_cull.m_enable ? D3D11_CULL_BACK : D3D11_CULL_NONE;
|
||||
c.m_pDeviceContext->RSSetState(InternalRenderManager.GetManagedRasterizerState());
|
||||
c.faceCullEnabled = command.set_face_cull.m_enable;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matrixOverride)
|
||||
{
|
||||
const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();
|
||||
D3D11_MAPPED_SUBRESOURCE mappedIdentity = {};
|
||||
c.m_pDeviceContext->Map(c.m_localTransformMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedIdentity);
|
||||
memcpy(mappedIdentity.pData, &identity, sizeof(identity));
|
||||
c.m_pDeviceContext->Unmap(c.m_localTransformMatrix, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool Renderer::CBuffCall(int index, bool full)
|
||||
{
|
||||
EnterCriticalSection(&m_commandBufferCS);
|
||||
@@ -507,7 +127,7 @@ bool Renderer::CBuffCall(int index, bool full)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedMatrix0 = {};
|
||||
c.m_pDeviceContext->Map(c.m_modelViewMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix0);
|
||||
memcpy(mappedMatrix0.pData, MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(DirectX::XMMATRIX));
|
||||
std::memcpy(mappedMatrix0.pData, MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(DirectX::XMMATRIX));
|
||||
c.m_pDeviceContext->Unmap(c.m_modelViewMatrix, 0);
|
||||
c.matrixDirty[MATRIX_MODE_MODELVIEW] = false;
|
||||
}
|
||||
@@ -516,7 +136,7 @@ bool Renderer::CBuffCall(int index, bool full)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedMatrix2 = {};
|
||||
c.m_pDeviceContext->Map(c.m_projectionMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix2);
|
||||
memcpy(mappedMatrix2.pData, MatrixGet(MATRIX_MODE_MODELVIEW_PROJECTION), sizeof(DirectX::XMMATRIX));
|
||||
std::memcpy(mappedMatrix2.pData, MatrixGet(MATRIX_MODE_MODELVIEW_PROJECTION), sizeof(DirectX::XMMATRIX));
|
||||
c.m_pDeviceContext->Unmap(c.m_projectionMatrix, 0);
|
||||
c.matrixDirty[MATRIX_MODE_MODELVIEW_PROJECTION] = false;
|
||||
}
|
||||
@@ -525,7 +145,7 @@ bool Renderer::CBuffCall(int index, bool full)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedMatrix3 = {};
|
||||
c.m_pDeviceContext->Map(c.m_textureMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix3);
|
||||
memcpy(mappedMatrix3.pData, MatrixGet(MATRIX_MODE_MODELVIEW_TEXTURE), sizeof(DirectX::XMMATRIX));
|
||||
std::memcpy(mappedMatrix3.pData, MatrixGet(MATRIX_MODE_MODELVIEW_TEXTURE), sizeof(DirectX::XMMATRIX));
|
||||
c.m_pDeviceContext->Unmap(c.m_textureMatrix, 0);
|
||||
c.matrixDirty[MATRIX_MODE_MODELVIEW_TEXTURE] = false;
|
||||
}
|
||||
@@ -548,7 +168,7 @@ bool Renderer::CBuffCall(int index, bool full)
|
||||
const float forcedLod[4] = {static_cast<float>(static_cast<int>(c.forcedLOD)), 0.0f, 0.0f, 0.0f};
|
||||
D3D11_MAPPED_SUBRESOURCE mappedAux4 = {};
|
||||
c.m_pDeviceContext->Map(c.m_forcedLODBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedAux4);
|
||||
memcpy(mappedAux4.pData, forcedLod, sizeof(forcedLod));
|
||||
std::memcpy(mappedAux4.pData, forcedLod, sizeof(forcedLod));
|
||||
c.m_pDeviceContext->Unmap(c.m_forcedLODBuffer, 0);
|
||||
pixelType = C4JRender::PIXEL_SHADER_TYPE_FORCELOD;
|
||||
}
|
||||
@@ -590,7 +210,7 @@ void Renderer::CBuffClear(int index)
|
||||
{
|
||||
EnterCriticalSection(&m_commandBufferCS);
|
||||
|
||||
std::int16_t *externalToInternal = static_cast<std::int16_t *>(m_commandHandleToIndex);
|
||||
std::int16_t *externalToInternal = static_cast<std::int16_t*>(m_commandHandleToIndex);
|
||||
const int internalIndex = externalToInternal[index];
|
||||
if (internalIndex >= 0)
|
||||
{
|
||||
@@ -791,16 +411,29 @@ void Renderer::CBuffTick()
|
||||
{
|
||||
EnterCriticalSection(&m_commandBufferCS);
|
||||
|
||||
const int firstPending = MAX_COMMAND_BUFFERS - static_cast<int>(reservedRendererDword3);
|
||||
for (int i = firstPending; i < MAX_COMMAND_BUFFERS; ++i)
|
||||
int completedDeletes = 0;
|
||||
if (reservedRendererDword3 > 0)
|
||||
{
|
||||
Renderer::CommandBuffer *buffer = m_commandBuffers[i];
|
||||
if (buffer)
|
||||
delete buffer;
|
||||
m_commandBuffers[i] = NULL;
|
||||
int tailSlot = MAX_COMMAND_BUFFERS - 1;
|
||||
do
|
||||
{
|
||||
Renderer::CommandBuffer *buffer = m_commandBuffers[tailSlot];
|
||||
if (buffer)
|
||||
delete buffer;
|
||||
m_commandBuffers[tailSlot] = NULL;
|
||||
|
||||
if (--reservedRendererDword3 == 0)
|
||||
{
|
||||
++completedDeletes;
|
||||
--tailSlot;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_commandBuffers[tailSlot] = m_commandBuffers[(MAX_COMMAND_BUFFERS - 1) - static_cast<int>(reservedRendererDword3)];
|
||||
}
|
||||
} while (completedDeletes < static_cast<int>(reservedRendererDword3));
|
||||
}
|
||||
|
||||
reservedRendererDword3 = 0;
|
||||
LeaveCriticalSection(&m_commandBufferCS);
|
||||
}
|
||||
|
||||
@@ -829,4 +462,384 @@ void Renderer::DeleteInternalBuffer(int index)
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_commandBufferCS);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::EndRecording(ID3D11Device *device)
|
||||
{
|
||||
if (m_vertexDataLength != 0)
|
||||
{
|
||||
D3D11_BUFFER_DESC desc = {};
|
||||
desc.ByteWidth = static_cast<UINT>(m_vertexDataLength);
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA data = {};
|
||||
data.pSysMem = m_vertexData;
|
||||
device->CreateBuffer(&desc, &data, &m_vertexBuffer);
|
||||
}
|
||||
|
||||
std::free(m_vertexData);
|
||||
m_vertexData = NULL;
|
||||
}
|
||||
|
||||
std::uint64_t Renderer::CommandBuffer::GetAllocated()
|
||||
{
|
||||
return m_allocated;
|
||||
}
|
||||
|
||||
bool Renderer::CommandBuffer::IsBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Context &c, int primitiveType)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::CommandBuffer::Render", "Render", MP_ORANGE);
|
||||
|
||||
if (!m_vertexBuffer)
|
||||
return;
|
||||
|
||||
int drawVertexType = vType;
|
||||
int shaderVertexType = drawVertexType;
|
||||
bool matrixOverride = false;
|
||||
|
||||
for (const Command &command : m_commands)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::CommandBuffer::Render", "ProcessCommand", MP_ORANGE);
|
||||
|
||||
switch (command.m_command_type)
|
||||
{
|
||||
case COMMAND_ADD_MATRIX:
|
||||
{
|
||||
if (drawVertexType == C4JRender::VERTEX_TYPE_COMPRESSED)
|
||||
{
|
||||
const float row[4] = {
|
||||
command.add_matrix.m_matrix[12], command.add_matrix.m_matrix[13],
|
||||
command.add_matrix.m_matrix[14], command.add_matrix.m_matrix[15]
|
||||
};
|
||||
D3D11_MAPPED_SUBRESOURCE mappedAux0 = {};
|
||||
c.m_pDeviceContext->Map(c.m_compressedTranslationBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedAux0);
|
||||
std::memcpy(mappedAux0.pData, row, sizeof(row));
|
||||
c.m_pDeviceContext->Unmap(c.m_compressedTranslationBuffer, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedMatrix1 = {};
|
||||
c.m_pDeviceContext->Map(c.m_localTransformMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix1);
|
||||
std::memcpy(mappedMatrix1.pData, command.add_matrix.m_matrix, sizeof(command.add_matrix.m_matrix));
|
||||
c.m_pDeviceContext->Unmap(c.m_localTransformMatrix, 0);
|
||||
matrixOverride = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_ADD_VERTICES:
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
InternalRenderManager.UpdateLightingState();
|
||||
|
||||
if (drawVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1)
|
||||
{
|
||||
if (c.lightingEnabled)
|
||||
{
|
||||
drawVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT;
|
||||
shaderVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT;
|
||||
}
|
||||
}
|
||||
else if (drawVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT && !c.lightingEnabled)
|
||||
{
|
||||
drawVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1;
|
||||
shaderVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1;
|
||||
}
|
||||
|
||||
if (static_cast<DWORD>(drawVertexType) != InternalRenderManager.activeVertexType)
|
||||
{
|
||||
c.m_pDeviceContext->VSSetShader(InternalRenderManager.vertexShaderTable[shaderVertexType], NULL, 0);
|
||||
c.m_pDeviceContext->IASetInputLayout(InternalRenderManager.inputLayoutTable[shaderVertexType]);
|
||||
InternalRenderManager.activeVertexType = drawVertexType;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int drawCount = command.add_vertices.m_vertex_count;
|
||||
bool drawIndexed = false;
|
||||
if (primitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST)
|
||||
{
|
||||
drawCount = (drawCount * 6) / 4;
|
||||
drawIndexed = true;
|
||||
}
|
||||
else if (primitiveType == C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN)
|
||||
{
|
||||
drawCount = (drawCount - 2) * 3;
|
||||
drawIndexed = true;
|
||||
}
|
||||
|
||||
ID3D11Buffer *buffer = m_vertexBuffer;
|
||||
const UINT stride = InternalRenderManager.vertexStrideTable[drawVertexType];
|
||||
const UINT offset = command.add_vertices.m_vertex_index_start;
|
||||
c.m_pDeviceContext->IASetVertexBuffers(0, 1, &buffer, &stride, &offset);
|
||||
|
||||
if (drawIndexed)
|
||||
c.m_pDeviceContext->DrawIndexed(drawCount, 0, 0);
|
||||
else
|
||||
c.m_pDeviceContext->Draw(drawCount, 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_BIND_TEXTURE:
|
||||
{
|
||||
c.textureIdx = command.bind_texture.m_texture_index;
|
||||
ID3D11ShaderResourceView *view = InternalRenderManager.m_textures[c.textureIdx].view;
|
||||
c.m_pDeviceContext->PSSetShaderResources(0, 1, &view);
|
||||
InternalRenderManager.UpdateTextureState(false);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_COLOR:
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedColour = {};
|
||||
c.m_pDeviceContext->Map(c.m_tintColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedColour);
|
||||
std::memcpy(mappedColour.pData, command.set_color.m_color, sizeof(command.set_color.m_color));
|
||||
c.m_pDeviceContext->Unmap(c.m_tintColorBuffer, 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_DEPTH_FUNC:
|
||||
{
|
||||
c.depthStencilDesc.DepthFunc = static_cast<D3D11_COMPARISON_FUNC>(command.set_depth_func.m_depth_func);
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_DEPTH_MASK:
|
||||
{
|
||||
c.depthWriteEnabled = command.set_depth_mask.m_enable;
|
||||
c.depthStencilDesc.DepthWriteMask = command.set_depth_mask.m_enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_DEPTH_TEST:
|
||||
{
|
||||
c.depthTestEnabled = command.set_depth_test.m_enable;
|
||||
c.depthStencilDesc.DepthEnable = command.set_depth_test.m_enable;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHTING_ENABLE:
|
||||
{
|
||||
c.lightingEnabled = command.set_lighting_enable.m_enable;
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_ENABLE:
|
||||
{
|
||||
const int light = command.set_light_enable.m_light_index;
|
||||
if (light >= 0 && light < 2)
|
||||
{
|
||||
c.lightEnabled[light] = command.set_light_enable.m_enable;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_DIRECTION:
|
||||
{
|
||||
const int light = command.set_light_direction.m_light_index;
|
||||
if (light >= 0 && light < 2)
|
||||
{
|
||||
c.lightDirection[light].x = command.set_light_direction.m_direction[0];
|
||||
c.lightDirection[light].y = command.set_light_direction.m_direction[1];
|
||||
c.lightDirection[light].z = command.set_light_direction.m_direction[2];
|
||||
c.lightDirection[light].w = command.set_light_direction.m_direction[3];
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_COLOUR:
|
||||
{
|
||||
const int light = command.set_light_colour.m_light_index;
|
||||
if (light >= 0 && light < 2)
|
||||
{
|
||||
c.lightColour[light].x = command.set_light_colour.m_color[0];
|
||||
c.lightColour[light].y = command.set_light_colour.m_color[1];
|
||||
c.lightColour[light].z = command.set_light_colour.m_color[2];
|
||||
c.lightColour[light].w = 1.0f;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_LIGHT_AMBIENT_COLOUR:
|
||||
{
|
||||
c.lightAmbientColour.x = command.set_light_ambient_colour.m_color[0];
|
||||
c.lightAmbientColour.y = command.set_light_ambient_colour.m_color[1];
|
||||
c.lightAmbientColour.z = command.set_light_ambient_colour.m_color[2];
|
||||
c.lightAmbientColour.w = 1.0f;
|
||||
c.lightingDirty = true;
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_BLEND_ENABLE:
|
||||
{
|
||||
c.blendDesc.RenderTarget[0].BlendEnable = command.set_blend_enable.m_enable;
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_BLEND_FUNC:
|
||||
{
|
||||
c.blendDesc.RenderTarget[0].SrcBlend = static_cast<D3D11_BLEND>(command.set_blend_func.m_src);
|
||||
c.blendDesc.RenderTarget[0].DestBlend = static_cast<D3D11_BLEND>(command.set_blend_func.m_dst);
|
||||
c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_BLEND_FACTOR:
|
||||
{
|
||||
const unsigned int factor = command.set_blend_factor.m_blend_factor;
|
||||
c.blendFactor[0] = float((factor >> 0) & 0xFF) / 255.0f;
|
||||
c.blendFactor[1] = float((factor >> 8) & 0xFF) / 255.0f;
|
||||
c.blendFactor[2] = float((factor >> 16) & 0xFF) / 255.0f;
|
||||
c.blendFactor[3] = float((factor >> 24) & 0xFF) / 255.0f;
|
||||
c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
break;
|
||||
}
|
||||
case COMMAND_SET_FACE_CULL:
|
||||
{
|
||||
c.rasterizerDesc.CullMode = command.set_face_cull.m_enable ? D3D11_CULL_BACK : D3D11_CULL_NONE;
|
||||
c.m_pDeviceContext->RSSetState(InternalRenderManager.GetManagedRasterizerState());
|
||||
c.faceCullEnabled = command.set_face_cull.m_enable;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matrixOverride)
|
||||
{
|
||||
const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();
|
||||
D3D11_MAPPED_SUBRESOURCE mappedIdentity = {};
|
||||
c.m_pDeviceContext->Map(c.m_localTransformMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedIdentity);
|
||||
std::memcpy(mappedIdentity.pData, &identity, sizeof(identity));
|
||||
c.m_pDeviceContext->Unmap(c.m_localTransformMatrix, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetBlendEnable(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_BLEND_ENABLE;
|
||||
command.set_blend_enable.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetBlendFactor(unsigned int factor)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_BLEND_FACTOR;
|
||||
command.set_blend_factor.m_blend_factor = factor;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetBlendFunc(int src, int dst)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_BLEND_FUNC;
|
||||
command.set_blend_func.m_src = src;
|
||||
command.set_blend_func.m_dst = dst;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetColor(float r, float g, float b, float a)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_COLOR;
|
||||
command.set_color.m_color[0] = r;
|
||||
command.set_color.m_color[1] = g;
|
||||
command.set_color.m_color[2] = b;
|
||||
command.set_color.m_color[3] = a;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetDepthFunc(int func)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_DEPTH_FUNC;
|
||||
command.set_depth_func.m_depth_func = func;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetDepthMask(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_DEPTH_MASK;
|
||||
command.set_depth_mask.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetDepthTestEnable(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_DEPTH_TEST;
|
||||
command.set_depth_test.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetFaceCull(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_FACE_CULL;
|
||||
command.set_face_cull.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightAmbientColour(float r, float g, float b)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_AMBIENT_COLOUR;
|
||||
command.set_light_ambient_colour.m_color[0] = r;
|
||||
command.set_light_ambient_colour.m_color[1] = g;
|
||||
command.set_light_ambient_colour.m_color[2] = b;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightColour(int light, float r, float g, float b)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_COLOUR;
|
||||
command.set_light_colour.m_light_index = light;
|
||||
command.set_light_colour.m_color[0] = r;
|
||||
command.set_light_colour.m_color[1] = g;
|
||||
command.set_light_colour.m_color[2] = b;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightDirection(int light, float x, float y, float z)
|
||||
{
|
||||
Renderer::Context &c = InternalRenderManager.getContext();
|
||||
const std::uint32_t depth = c.stackPos[MATRIX_MODE_MODELVIEW_CBUFF];
|
||||
const DirectX::XMMATRIX &matrix = c.matrixStacks[MATRIX_MODE_MODELVIEW_CBUFF][depth];
|
||||
|
||||
DirectX::XMVECTOR direction = DirectX::XMVectorSet(x, y, z, 0.0f);
|
||||
direction = DirectX::XMVector3TransformNormal(direction, matrix);
|
||||
direction = DirectX::XMVector3Normalize(direction);
|
||||
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_DIRECTION;
|
||||
command.set_light_direction.m_light_index = light;
|
||||
DirectX::XMFLOAT4 outDirection;
|
||||
DirectX::XMStoreFloat4(&outDirection, direction);
|
||||
command.set_light_direction.m_direction[0] = outDirection.x;
|
||||
command.set_light_direction.m_direction[1] = outDirection.y;
|
||||
command.set_light_direction.m_direction[2] = outDirection.z;
|
||||
command.set_light_direction.m_direction[3] = outDirection.w;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightEnable(int light, bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHT_ENABLE;
|
||||
command.set_light_enable.m_light_index = light;
|
||||
command.set_light_enable.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::SetLightingEnable(bool enable)
|
||||
{
|
||||
Command command = {};
|
||||
command.m_command_type = COMMAND_SET_LIGHTING_ENABLE;
|
||||
command.set_lighting_enable.m_enable = enable;
|
||||
m_commands.push_back(command);
|
||||
}
|
||||
|
||||
void Renderer::CommandBuffer::StartRecording() {}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,8 @@ const float *Renderer::MatrixGet(int type)
|
||||
{
|
||||
Context &c = getContext();
|
||||
const int depth = c.stackPos[type];
|
||||
return reinterpret_cast<const float *>(&c.matrixStacks[type][depth]);
|
||||
const DirectX::XMMATRIX &matrix = c.matrixStacks[type][depth];
|
||||
return &matrix.r[0].m128_f32[0];
|
||||
}
|
||||
|
||||
void Renderer::MatrixMode(int type)
|
||||
@@ -57,7 +58,7 @@ void Renderer::MatrixOrthogonal(float left, float right, float bottom, float top
|
||||
|
||||
void Renderer::MatrixPerspective(float fovy, float aspect, float zNear, float zFar)
|
||||
{
|
||||
const float fovRadians = fovy * (3.14159274f / 180.0f);
|
||||
const float fovRadians = fovy * (PI / 180.0f);
|
||||
const DirectX::XMMATRIX matrix = DirectX::XMMatrixPerspectiveFovRH(fovRadians, aspect, zNear, zFar);
|
||||
MultWithStack(matrix);
|
||||
}
|
||||
|
||||
@@ -28,9 +28,10 @@ SOFTWARE.
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
|
||||
ID3D11BlendState *Renderer::GetManagedBlendState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::GetManagedBlendState", "GetManagedBlendState", MP_ORCHID1)
|
||||
PROFILER_SCOPE("Renderer::GetManagedBlendState", "GetManagedBlendState", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
const D3D11_RENDER_TARGET_BLEND_DESC &rtBlend = c.blendDesc.RenderTarget[0];
|
||||
|
||||
@@ -47,9 +48,10 @@ ID3D11BlendState *Renderer::GetManagedBlendState()
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
ID3D11DepthStencilState *Renderer::GetManagedDepthStencilState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::GetManagedBlendState", "GetManagedDepthStencilState", MP_ORCHID1)
|
||||
PROFILER_SCOPE("Renderer::GetManagedBlendState", "GetManagedDepthStencilState", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
|
||||
const int key = (c.depthStencilDesc.DepthEnable ? 2 : 0) | ((static_cast<int>(c.depthStencilDesc.DepthFunc) & 0x0F) << 2) |
|
||||
@@ -65,9 +67,10 @@ ID3D11DepthStencilState *Renderer::GetManagedDepthStencilState()
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
ID3D11RasterizerState *Renderer::GetManagedRasterizerState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::GetManagedRasterizerState", "GetManagedRasterizerState", MP_ORCHID1)
|
||||
PROFILER_SCOPE("Renderer::GetManagedRasterizerState", "GetManagedRasterizerState", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
|
||||
const int key = (static_cast<std::uint8_t>(c.rasterizerDesc.DepthBias)) |
|
||||
@@ -84,9 +87,10 @@ ID3D11RasterizerState *Renderer::GetManagedRasterizerState()
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
ID3D11SamplerState *Renderer::GetManagedSamplerState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::GetManagedSamplerState", "GetManagedSamplerState", MP_ORCHID1)
|
||||
PROFILER_SCOPE("Renderer::GetManagedSamplerState", "GetManagedSamplerState", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
const int key = m_textures[c.textureIdx].samplerParams;
|
||||
|
||||
@@ -104,10 +108,10 @@ ID3D11SamplerState *Renderer::GetManagedSamplerState()
|
||||
desc.Filter = static_cast<D3D11_FILTER>(filterBits >> 1);
|
||||
desc.AddressU = clampU ? D3D11_TEXTURE_ADDRESS_CLAMP : D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = clampV ? D3D11_TEXTURE_ADDRESS_CLAMP : D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = static_cast<D3D11_TEXTURE_ADDRESS_MODE>(3);
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.MipLODBias = 0.0f;
|
||||
desc.MaxAnisotropy = 16;
|
||||
desc.ComparisonFunc = static_cast<D3D11_COMPARISON_FUNC>(1);
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
desc.BorderColor[0] = 0.0f;
|
||||
desc.BorderColor[1] = 0.0f;
|
||||
desc.BorderColor[2] = 0.0f;
|
||||
@@ -121,36 +125,184 @@ ID3D11SamplerState *Renderer::GetManagedSamplerState()
|
||||
return state;
|
||||
}
|
||||
|
||||
void Renderer::StateSetFogEnable(bool enable)
|
||||
|
||||
void Renderer::StateSetAlphaFunc(int, float param)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogEnabled = enable;
|
||||
c.alphaReference = param;
|
||||
|
||||
const float alpha[4] = {0.0f, 0.0f, 0.0f, c.alphaTestEnabled ? c.alphaReference : 0.0f};
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_alphaTestBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, alpha, sizeof(alpha));
|
||||
c.m_pDeviceContext->Unmap(c.m_alphaTestBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::StateSetFogMode(int mode)
|
||||
|
||||
void Renderer::StateSetAlphaTestEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogMode = mode;
|
||||
c.alphaTestEnabled = enable;
|
||||
|
||||
const float alpha[4] = {0.0f, 0.0f, 0.0f, enable ? c.alphaReference : 0.0f};
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_alphaTestBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, alpha, sizeof(alpha));
|
||||
c.m_pDeviceContext->Unmap(c.m_alphaTestBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::StateSetFogNearDistance(float dist)
|
||||
|
||||
void Renderer::StateSetBlendEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogNearDistance = dist;
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetBlendEnable(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.blendDesc.RenderTarget[0].BlendEnable = enable;
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Renderer::StateSetFogFarDistance(float dist)
|
||||
|
||||
void Renderer::StateSetBlendFactor(unsigned int colour)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogFarDistance = dist;
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetBlendFactor(colour);
|
||||
return;
|
||||
}
|
||||
|
||||
const float scale = 255.0f;
|
||||
c.blendFactor[0] = static_cast<float>((colour >> 0) & 0xFF) / scale;
|
||||
c.blendFactor[1] = static_cast<float>((colour >> 8) & 0xFF) / scale;
|
||||
c.blendFactor[2] = static_cast<float>((colour >> 16) & 0xFF) / scale;
|
||||
c.blendFactor[3] = static_cast<float>((colour >> 24) & 0xFF) / scale;
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Renderer::StateSetFogDensity(float density)
|
||||
|
||||
void Renderer::StateSetBlendFunc(int src, int dst)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogDensity = density;
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetBlendFunc(src, dst);
|
||||
return;
|
||||
}
|
||||
|
||||
c.blendDesc.RenderTarget[0].SrcBlend = static_cast<D3D11_BLEND>(src);
|
||||
c.blendDesc.RenderTarget[0].DestBlend = static_cast<D3D11_BLEND>(dst);
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetColour(float r, float g, float b, float a)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetColor(r, g, b, a);
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
|
||||
const float colour[4] = {r, g, b, a};
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
d3d11->Map(c.m_tintColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, colour, sizeof(colour));
|
||||
d3d11->Unmap(c.m_tintColorBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetDepthFunc(int func)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetDepthFunc(func);
|
||||
return;
|
||||
}
|
||||
|
||||
c.depthStencilDesc.DepthFunc = static_cast<D3D11_COMPARISON_FUNC>(func);
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetDepthMask(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetDepthMask(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.depthStencilDesc.DepthWriteMask = enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
|
||||
c.depthWriteEnabled = enable;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetDepthSlopeAndBias(float slope, float bias)
|
||||
{
|
||||
Context &c = getContext();
|
||||
|
||||
const float scale = 65536.0f;
|
||||
c.rasterizerDesc.DepthBias = static_cast<int>(bias * scale);
|
||||
c.rasterizerDesc.SlopeScaledDepthBias = slope * scale;
|
||||
c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetDepthTestEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetDepthTestEnable(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.depthStencilDesc.DepthEnable = enable;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
|
||||
c.depthTestEnabled = enable;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetEnableViewportClipPlanes(bool) {}
|
||||
|
||||
|
||||
void Renderer::StateSetFaceCull(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetFaceCull(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_NONE;
|
||||
c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
|
||||
c.faceCullEnabled = enable;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetFaceCullCW(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.faceCullEnabled)
|
||||
c.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_FRONT;
|
||||
else
|
||||
c.rasterizerDesc.CullMode = D3D11_CULL_NONE;
|
||||
|
||||
c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetFogColour(float red, float green, float blue)
|
||||
{
|
||||
Context &c = getContext();
|
||||
@@ -159,20 +311,66 @@ void Renderer::StateSetFogColour(float red, float green, float blue)
|
||||
c.fogColourGreen = green;
|
||||
}
|
||||
|
||||
void Renderer::UpdateViewportState() {}
|
||||
|
||||
void Renderer::StateSetLightingEnable(bool enable)
|
||||
void Renderer::StateSetFogDensity(float density)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogDensity = density;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetFogEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogEnabled = enable;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetFogFarDistance(float dist)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogFarDistance = dist;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetFogMode(int mode)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogMode = mode;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetFogNearDistance(float dist)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.fogNearDistance = dist;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetForceLOD(int LOD)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.forcedLOD = LOD;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetLightAmbientColour(float red, float green, float blue)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetLightingEnable(enable);
|
||||
c.commandBuffer->SetLightAmbientColour(red, green, blue);
|
||||
return;
|
||||
}
|
||||
|
||||
c.lightingEnabled = enable;
|
||||
c.lightAmbientColour.x = red;
|
||||
c.lightAmbientColour.y = green;
|
||||
c.lightAmbientColour.z = blue;
|
||||
c.lightAmbientColour.w = 1.0f;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetLightColour(int light, float red, float green, float blue)
|
||||
{
|
||||
if (light >= 2)
|
||||
@@ -192,301 +390,6 @@ void Renderer::StateSetLightColour(int light, float red, float green, float blue
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
|
||||
void Renderer::StateSetLightAmbientColour(float red, float green, float blue)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetLightAmbientColour(red, green, blue);
|
||||
return;
|
||||
}
|
||||
|
||||
c.lightAmbientColour.x = red;
|
||||
c.lightAmbientColour.y = green;
|
||||
c.lightAmbientColour.z = blue;
|
||||
c.lightAmbientColour.w = 1.0f;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
|
||||
void Renderer::StateSetLightEnable(int light, bool enable)
|
||||
{
|
||||
if (light >= 2)
|
||||
return;
|
||||
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetLightEnable(light, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.lightEnabled[light] = enable;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
|
||||
void Renderer::StateSetColour(float r, float g, float b, float a)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetColor(r, g, b, a);
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
|
||||
const float colour[4] = {r, g, b, a};
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
d3d11->Map(c.m_tintColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, colour, sizeof(colour));
|
||||
d3d11->Unmap(c.m_tintColorBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::StateSetDepthMask(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetDepthMask(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.depthStencilDesc.DepthWriteMask = enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
|
||||
c.depthWriteEnabled = enable;
|
||||
}
|
||||
|
||||
void Renderer::StateSetBlendEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetBlendEnable(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.blendDesc.RenderTarget[0].BlendEnable = enable;
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Renderer::StateSetBlendFunc(int src, int dst)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetBlendFunc(src, dst);
|
||||
return;
|
||||
}
|
||||
|
||||
c.blendDesc.RenderTarget[0].SrcBlend = static_cast<D3D11_BLEND>(src);
|
||||
c.blendDesc.RenderTarget[0].DestBlend = static_cast<D3D11_BLEND>(dst);
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Renderer::StateSetBlendFactor(unsigned int colour)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetBlendFactor(colour);
|
||||
return;
|
||||
}
|
||||
|
||||
const float scale = 255.0f;
|
||||
c.blendFactor[0] = static_cast<float>((colour >> 0) & 0xFF) / scale;
|
||||
c.blendFactor[1] = static_cast<float>((colour >> 8) & 0xFF) / scale;
|
||||
c.blendFactor[2] = static_cast<float>((colour >> 16) & 0xFF) / scale;
|
||||
c.blendFactor[3] = static_cast<float>((colour >> 24) & 0xFF) / scale;
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Renderer::StateSetAlphaFunc(int, float param)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.alphaReference = param;
|
||||
|
||||
const float alpha[4] = {0.0f, 0.0f, 0.0f, c.alphaTestEnabled ? c.alphaReference : 0.0f};
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_alphaTestBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, alpha, sizeof(alpha));
|
||||
c.m_pDeviceContext->Unmap(c.m_alphaTestBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::StateSetDepthFunc(int func)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetDepthFunc(func);
|
||||
return;
|
||||
}
|
||||
|
||||
c.depthStencilDesc.DepthFunc = static_cast<D3D11_COMPARISON_FUNC>(func);
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
|
||||
}
|
||||
|
||||
void Renderer::StateSetFaceCull(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetFaceCull(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_NONE;
|
||||
c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
|
||||
c.faceCullEnabled = enable;
|
||||
}
|
||||
|
||||
void Renderer::StateSetFaceCullCW(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.faceCullEnabled)
|
||||
c.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_FRONT;
|
||||
else
|
||||
c.rasterizerDesc.CullMode = D3D11_CULL_NONE;
|
||||
|
||||
c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
|
||||
}
|
||||
|
||||
void Renderer::StateSetLineWidth(float) {}
|
||||
|
||||
void Renderer::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha)
|
||||
{
|
||||
Context &c = getContext();
|
||||
|
||||
std::uint8_t mask = 0;
|
||||
mask |= red ? 0x1 : 0;
|
||||
mask |= green ? 0x2 : 0;
|
||||
mask |= blue ? 0x4 : 0;
|
||||
mask |= alpha ? 0x8 : 0;
|
||||
|
||||
c.blendDesc.RenderTarget[0].RenderTargetWriteMask = mask;
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Renderer::StateSetDepthTestEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetDepthTestEnable(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.depthStencilDesc.DepthEnable = enable;
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
|
||||
c.depthTestEnabled = enable;
|
||||
}
|
||||
|
||||
void Renderer::StateSetAlphaTestEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.alphaTestEnabled = enable;
|
||||
|
||||
const float alpha[4] = {0.0f, 0.0f, 0.0f, enable ? c.alphaReference : 0.0f};
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_alphaTestBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, alpha, sizeof(alpha));
|
||||
c.m_pDeviceContext->Unmap(c.m_alphaTestBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::StateSetDepthSlopeAndBias(float slope, float bias)
|
||||
{
|
||||
Context &c = getContext();
|
||||
|
||||
const float scale = 65536.0f;
|
||||
c.rasterizerDesc.DepthBias = static_cast<int>(bias * scale);
|
||||
c.rasterizerDesc.SlopeScaledDepthBias = slope * scale;
|
||||
c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
|
||||
}
|
||||
|
||||
void Renderer::UpdateFogState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::UpdateFogState", "UpdateFogState", MP_ORCHID1)
|
||||
Context &c = getContext();
|
||||
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
|
||||
|
||||
float fogParams[4] = {};
|
||||
if (c.fogEnabled)
|
||||
{
|
||||
if (c.fogMode == 1)
|
||||
{
|
||||
fogParams[0] = c.fogFarDistance;
|
||||
fogParams[1] = 1.0f / (c.fogFarDistance - c.fogNearDistance);
|
||||
fogParams[2] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fogParams[0] = c.fogDensity;
|
||||
fogParams[2] = 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
const float fogColour[4] = {c.fogColourRed, c.fogColourGreen, c.fogColourBlue, 1.0f};
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
d3d11->Map(c.m_fogParamsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, fogParams, sizeof(fogParams));
|
||||
d3d11->Unmap(c.m_fogParamsBuffer, 0);
|
||||
|
||||
d3d11->Map(c.m_fogColourBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, fogColour, sizeof(fogColour));
|
||||
d3d11->Unmap(c.m_fogColourBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::StateSetVertexTextureUV(float u, float v)
|
||||
{
|
||||
Context &c = getContext();
|
||||
const float texgen[4] = {u - 1.0f, v - 1.0f, 0.0f, 0.0f};
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_vertexTexcoordBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, texgen, sizeof(texgen));
|
||||
c.m_pDeviceContext->Unmap(c.m_vertexTexcoordBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::UpdateTexGenState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::UpdateTexGenState", "UpdateTexGenState", MP_ORCHID1)
|
||||
Context &c = getContext();
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_texGenMatricesBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, c.texGenMatrices, sizeof(c.texGenMatrices));
|
||||
c.m_pDeviceContext->Unmap(c.m_texGenMatricesBuffer, 0);
|
||||
}
|
||||
|
||||
void Renderer::UpdateLightingState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::UpdateLightingState", "UpdateLightingState", MP_ORCHID1)
|
||||
Context &c = getContext();
|
||||
if (!c.lightingDirty || !c.lightingEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c.lightEnabled[0])
|
||||
{
|
||||
std::memset(&c.lightDirection[0], 0, sizeof(c.lightDirection[0]));
|
||||
std::memset(&c.lightColour[0], 0, sizeof(c.lightColour[0]));
|
||||
}
|
||||
|
||||
if (!c.lightEnabled[1])
|
||||
{
|
||||
std::memset(&c.lightDirection[1], 0, sizeof(c.lightDirection[1]));
|
||||
std::memset(&c.lightColour[1], 0, sizeof(c.lightColour[1]));
|
||||
}
|
||||
|
||||
const std::size_t lightingBytes = sizeof(c.lightDirection) + sizeof(c.lightColour) + sizeof(c.lightAmbientColour);
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_lightingStateBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, c.lightDirection, lightingBytes);
|
||||
c.m_pDeviceContext->Unmap(c.m_lightingStateBuffer, 0);
|
||||
|
||||
c.lightingDirty = false;
|
||||
}
|
||||
|
||||
void Renderer::StateSetLightDirection(int light, float x, float y, float z)
|
||||
{
|
||||
@@ -510,6 +413,106 @@ void Renderer::StateSetLightDirection(int light, float x, float y, float z)
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetLightEnable(int light, bool enable)
|
||||
{
|
||||
if (light >= 2)
|
||||
return;
|
||||
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetLightEnable(light, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.lightEnabled[light] = enable;
|
||||
c.lightingDirty = true;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetLightingEnable(bool enable)
|
||||
{
|
||||
Context &c = getContext();
|
||||
if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
|
||||
{
|
||||
c.commandBuffer->SetLightingEnable(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
c.lightingEnabled = enable;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetLineWidth(float) {}
|
||||
|
||||
|
||||
void Renderer::StateSetStencil(D3D11_COMPARISON_FUNC function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask)
|
||||
{
|
||||
Context &c = getContext();
|
||||
|
||||
D3D11_DEPTH_STENCIL_DESC desc = c.depthStencilDesc;
|
||||
desc.StencilEnable = true;
|
||||
desc.StencilReadMask = stencil_func_mask;
|
||||
desc.StencilWriteMask = stencil_write_mask;
|
||||
desc.FrontFace.StencilFunc = function;
|
||||
desc.BackFace.StencilFunc = function;
|
||||
|
||||
ID3D11DepthStencilState *state = NULL;
|
||||
m_pDevice->CreateDepthStencilState(&desc, &state);
|
||||
m_pDeviceContext->OMSetDepthStencilState(state, stencil_ref);
|
||||
if (state != NULL) state->Release();
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace)
|
||||
{
|
||||
Context &c = getContext();
|
||||
|
||||
DirectX::XMVECTOR plane = DirectX::XMVectorSet(x, y, z, w);
|
||||
if (eyeSpace)
|
||||
{
|
||||
DirectX::XMFLOAT4X4 modelView;
|
||||
std::memset(&modelView, 0, sizeof(modelView));
|
||||
std::memcpy(&modelView, MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(modelView));
|
||||
|
||||
DirectX::XMVECTOR determinant = DirectX::XMVectorZero();
|
||||
const DirectX::XMMATRIX inverse = DirectX::XMMatrixInverse(&determinant, DirectX::XMLoadFloat4x4(&modelView));
|
||||
plane = DirectX::XMVector4Transform(plane, inverse);
|
||||
}
|
||||
|
||||
DirectX::XMFLOAT4 transformed;
|
||||
DirectX::XMStoreFloat4(&transformed, plane);
|
||||
|
||||
const int activeSet = eyeSpace ? 0 : 1;
|
||||
const int inactiveSet = eyeSpace ? 1 : 0;
|
||||
|
||||
float *active = reinterpret_cast<float *>(&c.texGenMatrices[activeSet]);
|
||||
active[col + 0] = transformed.x;
|
||||
active[col + 4] = transformed.y;
|
||||
active[col + 8] = transformed.z;
|
||||
active[col + 12] = transformed.w;
|
||||
|
||||
float *inactive = reinterpret_cast<float *>(&c.texGenMatrices[inactiveSet]);
|
||||
inactive[col + 0] = 0.0f;
|
||||
inactive[col + 4] = 0.0f;
|
||||
inactive[col + 8] = 0.0f;
|
||||
inactive[col + 12] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetVertexTextureUV(float u, float v)
|
||||
{
|
||||
Context &c = getContext();
|
||||
const float texgen[4] = {u - 1.0f, v - 1.0f, 0.0f, 0.0f};
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_vertexTexcoordBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, texgen, sizeof(texgen));
|
||||
c.m_pDeviceContext->Unmap(c.m_vertexTexcoordBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StateSetViewport(C4JRender::eViewportType viewportType)
|
||||
{
|
||||
getContext();
|
||||
@@ -528,10 +531,10 @@ void Renderer::StateSetViewport(C4JRender::eViewportType viewportType)
|
||||
case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
|
||||
break;
|
||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||
y = fullHeight * 0.5f;
|
||||
height = fullHeight * 0.5f;
|
||||
break;
|
||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||
y = fullHeight * 0.5f;
|
||||
height = fullHeight * 0.5f;
|
||||
break;
|
||||
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||
@@ -577,72 +580,108 @@ void Renderer::StateSetViewport(C4JRender::eViewportType viewportType)
|
||||
m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
|
||||
}
|
||||
|
||||
void Renderer::StateSetEnableViewportClipPlanes(bool) {}
|
||||
|
||||
void Renderer::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace)
|
||||
void Renderer::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha)
|
||||
{
|
||||
Context &c = getContext();
|
||||
|
||||
DirectX::XMVECTOR plane = DirectX::XMVectorSet(x, y, z, w);
|
||||
if (eyeSpace)
|
||||
{
|
||||
DirectX::XMFLOAT4X4 modelView;
|
||||
std::memset(&modelView, 0, sizeof(modelView));
|
||||
std::memcpy(&modelView, MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(modelView));
|
||||
std::uint8_t mask = 0;
|
||||
mask |= red ? 0x1 : 0;
|
||||
mask |= green ? 0x2 : 0;
|
||||
mask |= blue ? 0x4 : 0;
|
||||
mask |= alpha ? 0x8 : 0;
|
||||
|
||||
DirectX::XMVECTOR determinant = DirectX::XMVectorZero();
|
||||
const DirectX::XMMATRIX inverse = DirectX::XMMatrixInverse(&determinant, DirectX::XMLoadFloat4x4(&modelView));
|
||||
plane = DirectX::XMVector4Transform(plane, inverse);
|
||||
}
|
||||
|
||||
DirectX::XMFLOAT4 transformed;
|
||||
DirectX::XMStoreFloat4(&transformed, plane);
|
||||
|
||||
const int activeSet = eyeSpace ? 0 : 1;
|
||||
const int inactiveSet = eyeSpace ? 1 : 0;
|
||||
|
||||
float *active = reinterpret_cast<float *>(&c.texGenMatrices[activeSet]);
|
||||
active[col + 0] = transformed.x;
|
||||
active[col + 4] = transformed.y;
|
||||
active[col + 8] = transformed.z;
|
||||
active[col + 12] = transformed.w;
|
||||
|
||||
float *inactive = reinterpret_cast<float *>(&c.texGenMatrices[inactiveSet]);
|
||||
inactive[col + 0] = 0.0f;
|
||||
inactive[col + 4] = 0.0f;
|
||||
inactive[col + 8] = 0.0f;
|
||||
inactive[col + 12] = 0.0f;
|
||||
c.blendDesc.RenderTarget[0].RenderTargetWriteMask = mask;
|
||||
c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Renderer::StateSetStencil(D3D11_COMPARISON_FUNC function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask)
|
||||
{
|
||||
Context &c = getContext();
|
||||
|
||||
D3D11_DEPTH_STENCIL_DESC desc = c.depthStencilDesc;
|
||||
desc.StencilEnable = true;
|
||||
desc.StencilReadMask = stencil_func_mask;
|
||||
desc.StencilWriteMask = stencil_write_mask;
|
||||
desc.FrontFace.StencilFunc = function;
|
||||
desc.BackFace.StencilFunc = function;
|
||||
|
||||
ID3D11DepthStencilState *state = NULL;
|
||||
m_pDevice->CreateDepthStencilState(&desc, &state);
|
||||
m_pDeviceContext->OMSetDepthStencilState(state, stencil_ref);
|
||||
if (state != NULL) state->Release();
|
||||
}
|
||||
|
||||
void Renderer::StateSetForceLOD(int LOD)
|
||||
{
|
||||
Context &c = getContext();
|
||||
c.forcedLOD = LOD;
|
||||
}
|
||||
|
||||
void Renderer::StateUpdate()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::StateUpdate", "StateUpdate", MP_ORCHID1)
|
||||
PROFILER_SCOPE("Renderer::StateUpdate", "StateUpdate", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
StateSetFaceCull(c.faceCullEnabled);
|
||||
StateSetDepthMask(c.depthWriteEnabled);
|
||||
StateSetDepthTestEnable(c.depthTestEnabled);
|
||||
StateSetAlphaTestEnable(c.alphaTestEnabled);
|
||||
}
|
||||
|
||||
void Renderer::UpdateFogState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::UpdateFogState", "UpdateFogState", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
|
||||
|
||||
float fogParams[4] = {};
|
||||
if (c.fogEnabled)
|
||||
{
|
||||
if (c.fogMode == 1)
|
||||
{
|
||||
fogParams[0] = c.fogFarDistance;
|
||||
fogParams[1] = 1.0f / (c.fogFarDistance - c.fogNearDistance);
|
||||
fogParams[2] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fogParams[0] = c.fogDensity;
|
||||
fogParams[2] = 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
const float fogColour[4] = {c.fogColourRed, c.fogColourGreen, c.fogColourBlue, 1.0f};
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
d3d11->Map(c.m_fogParamsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, fogParams, sizeof(fogParams));
|
||||
d3d11->Unmap(c.m_fogParamsBuffer, 0);
|
||||
|
||||
d3d11->Map(c.m_fogColourBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, fogColour, sizeof(fogColour));
|
||||
d3d11->Unmap(c.m_fogColourBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::UpdateLightingState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::UpdateLightingState", "UpdateLightingState", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
if (!c.lightingDirty || !c.lightingEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c.lightEnabled[0])
|
||||
{
|
||||
std::memset(&c.lightDirection[0], 0, sizeof(c.lightDirection[0]));
|
||||
std::memset(&c.lightColour[0], 0, sizeof(c.lightColour[0]));
|
||||
}
|
||||
|
||||
if (!c.lightEnabled[1])
|
||||
{
|
||||
std::memset(&c.lightDirection[1], 0, sizeof(c.lightDirection[1]));
|
||||
std::memset(&c.lightColour[1], 0, sizeof(c.lightColour[1]));
|
||||
}
|
||||
|
||||
const std::size_t lightingBytes = sizeof(c.lightDirection) + sizeof(c.lightColour) + sizeof(c.lightAmbientColour);
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_lightingStateBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
std::memcpy(mapped.pData, c.lightDirection, lightingBytes);
|
||||
c.m_pDeviceContext->Unmap(c.m_lightingStateBuffer, 0);
|
||||
|
||||
c.lightingDirty = false;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::UpdateTexGenState()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::UpdateTexGenState", "UpdateTexGenState", MP_ORCHID1);
|
||||
Context &c = getContext();
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
c.m_pDeviceContext->Map(c.m_texGenMatricesBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
c.m_pDeviceContext->Unmap(c.m_texGenMatricesBuffer, 0);
|
||||
std::memcpy(mapped.pData, c.texGenMatrices, sizeof(c.texGenMatrices));
|
||||
}
|
||||
|
||||
|
||||
void Renderer::UpdateViewportState() {}
|
||||
@@ -30,71 +30,100 @@ unsigned char* dataStart;
|
||||
unsigned char *dataCurr;
|
||||
unsigned char *dataEnd;
|
||||
|
||||
DXGI_FORMAT Renderer::textureFormats[] = { DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN };
|
||||
DXGI_FORMAT Renderer::textureFormats[] = {
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_FORMAT_UNKNOWN
|
||||
};
|
||||
|
||||
void user_write_data_init(unsigned char* pBuffer, int size)
|
||||
// these are here because they are used before they are defined
|
||||
// its fine like that and the order of everything matches ida so we have to put these here
|
||||
void user_flush_data(png_struct_def *png_ptr);
|
||||
void user_write_data(png_struct_def *png_ptr, unsigned char *src, size_t length);
|
||||
|
||||
HRESULT Renderer::LoadTextureData(BYTE* pbData, DWORD dwBytes, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
|
||||
{
|
||||
dataStart = pBuffer;
|
||||
dataCurr = pBuffer;
|
||||
dataEnd = pBuffer + size;
|
||||
PROFILER_SCOPE("Renderer::LoadTextureData_Memory", "LoadTextureData_Memory", MP_PURPLE4);
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
png_image_begin_read_from_memory(&image, pbData, dwBytes);
|
||||
|
||||
if (PNG_IMAGE_FAILED(image))
|
||||
return E_FAIL;
|
||||
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
*ppDataOut = new int[image.width * image.height];
|
||||
if (!*ppDataOut || !png_image_finish_read(&image, NULL, *ppDataOut, NULL, NULL))
|
||||
return E_FAIL;
|
||||
|
||||
pSrcInfo->Width = image.width;
|
||||
pSrcInfo->Height = image.height;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int user_write_data_bytes_written()
|
||||
HRESULT Renderer::LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
|
||||
{
|
||||
return static_cast<int>(dataCurr - dataStart);
|
||||
PROFILER_SCOPE("Renderer::LoadTextureData_File", "LoadTextureData_File", MP_PURPLE4);
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
png_image_begin_read_from_file(&image, szFilename);
|
||||
|
||||
if (PNG_IMAGE_FAILED(image))
|
||||
return E_FAIL;
|
||||
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
*ppDataOut = new int[image.width * image.height];
|
||||
if (!*ppDataOut || !png_image_finish_read(&image, NULL, *ppDataOut, NULL, NULL))
|
||||
return E_FAIL;
|
||||
|
||||
pSrcInfo->Width = image.width;
|
||||
pSrcInfo->Height = image.height;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void user_write_data(png_struct_def* png_ptr, unsigned char* src, size_t length)
|
||||
HRESULT Renderer::SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int* ppDataOut)
|
||||
{
|
||||
int bytesToWrite = static_cast<int>(dataEnd - dataCurr);
|
||||
if (static_cast<int>(length) < bytesToWrite)
|
||||
bytesToWrite = static_cast<int>(length);
|
||||
PROFILER_SCOPE("Renderer::SaveTextureData", "SaveTextureData", MP_PURPLE4);
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
|
||||
memcpy(dataCurr, src, bytesToWrite);
|
||||
dataCurr += bytesToWrite;
|
||||
image.width = pSrcInfo->Width;
|
||||
image.height = pSrcInfo->Height;
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
png_image_write_to_file(&image, szFilename, NULL, ppDataOut, NULL, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void user_flush_data(png_struct_def* png_ptr)
|
||||
HRESULT Renderer::SaveTextureDataToMemory(void* pOutput, int outputCapacity, int* outputLength, int width, int height, int* ppDataIn)
|
||||
{
|
||||
// TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
|
||||
}
|
||||
PROFILER_SCOPE("Renderer::SaveTextureDataToMemory", "SaveTextureDataToMemory", MP_PURPLE4);
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
|
||||
int Renderer::TextureCreate()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::TextureCreate", "TextureCreate", MP_PURPLE4)
|
||||
for (int i = 0; i < MAX_TEXTURES; i++)
|
||||
{
|
||||
if (!m_textures[i].allocated)
|
||||
{
|
||||
m_textures[i].texture = NULL;
|
||||
m_textures[i].allocated = true;
|
||||
m_textures[i].mipLevels = 1;
|
||||
m_textures[i].textureFormat = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
dataEnd = (BYTE *)pOutput + outputCapacity;
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
dataStart = (BYTE*)pOutput;
|
||||
dataCurr = (BYTE*)pOutput;
|
||||
|
||||
void Renderer::TextureFree(int idx)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::TextureFree", "TextureFree", MP_PURPLE4)
|
||||
if (m_textures[idx].texture)
|
||||
{
|
||||
m_textures[idx].texture->Release();
|
||||
m_textures[idx].texture = NULL;
|
||||
}
|
||||
if (m_textures[idx].view)
|
||||
{
|
||||
m_textures[idx].view->Release();
|
||||
m_textures[idx].view = NULL;
|
||||
}
|
||||
m_textures[idx].allocated = false;
|
||||
png_image_write_to_stdio(&image, NULL, NULL, ppDataIn, NULL, NULL, user_write_data, user_flush_data);
|
||||
|
||||
*outputLength = (int)(dataCurr - dataStart);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Renderer::TextureBind(int idx)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::TextureBind", "TextureBind", MP_PURPLE4)
|
||||
PROFILER_SCOPE("Renderer::TextureBind", "TextureBind", MP_PURPLE4);
|
||||
if (idx == -1)
|
||||
idx = defaultTextureIndex;
|
||||
|
||||
@@ -111,7 +140,7 @@ void Renderer::TextureBind(int idx)
|
||||
|
||||
void Renderer::TextureBindVertex(int idx)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::TextureBindVertex", "TextureBindVertex", MP_PURPLE4)
|
||||
PROFILER_SCOPE("Renderer::TextureBindVertex", "TextureBindVertex", MP_PURPLE4);
|
||||
if (idx == -1)
|
||||
idx = defaultTextureIndex;
|
||||
|
||||
@@ -123,21 +152,26 @@ void Renderer::TextureBindVertex(int idx)
|
||||
UpdateTextureState(true);
|
||||
}
|
||||
|
||||
void Renderer::TextureSetTextureLevels(int levels)
|
||||
int Renderer::TextureCreate()
|
||||
{
|
||||
Context& c = getContext();
|
||||
m_textures[c.textureIdx].mipLevels = levels;
|
||||
}
|
||||
|
||||
int Renderer::TextureGetTextureLevels()
|
||||
{
|
||||
Context& c = getContext();
|
||||
return m_textures[c.textureIdx].mipLevels;
|
||||
PROFILER_SCOPE("Renderer::TextureCreate", "TextureCreate", MP_PURPLE4);
|
||||
for (int i = 0; i < MAX_TEXTURES; i++)
|
||||
{
|
||||
if (!m_textures[i].allocated)
|
||||
{
|
||||
m_textures[i].texture = NULL;
|
||||
m_textures[i].allocated = true;
|
||||
m_textures[i].mipLevels = 1;
|
||||
m_textures[i].samplerParams = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Renderer::TextureData(int width, int height, void* data, int level, C4JRender::eTextureFormat format)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::TextureData", "TextureData", MP_PURPLE4)
|
||||
PROFILER_SCOPE("Renderer::TextureData", "TextureData", MP_PURPLE4);
|
||||
Context& c = getContext();
|
||||
int idx = c.textureIdx;
|
||||
|
||||
@@ -163,25 +197,25 @@ void Renderer::TextureData(int width, int height, void* data, int level, C4JRend
|
||||
}
|
||||
|
||||
c.m_pDeviceContext->UpdateSubresource(
|
||||
m_textures[idx].texture,
|
||||
level,
|
||||
NULL,
|
||||
data,
|
||||
static_cast<UINT>(width * 4),
|
||||
static_cast<UINT>(width * height * 4)
|
||||
m_textures[idx].texture,
|
||||
level,
|
||||
NULL,
|
||||
data,
|
||||
(UINT)(width * 4),
|
||||
(UINT)(width * height * 4)
|
||||
);
|
||||
}
|
||||
|
||||
void Renderer::TextureDataUpdate(int xoffset, int yoffset, int width, int height, void* data, int level)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::TextureDataUpdate", "TextureDataUpdate", MP_PURPLE4)
|
||||
PROFILER_SCOPE("Renderer::TextureDataUpdate", "TextureDataUpdate", MP_PURPLE4);
|
||||
Context& c = getContext();
|
||||
int idx = c.textureIdx;
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
D3D11_TEXTURE2D_DESC desc = {};
|
||||
m_textures[idx].texture->GetDesc(&desc);
|
||||
|
||||
D3D11_BOX box;
|
||||
D3D11_BOX box = {};
|
||||
box.left = xoffset;
|
||||
box.top = yoffset;
|
||||
box.right = xoffset + width;
|
||||
@@ -194,11 +228,40 @@ void Renderer::TextureDataUpdate(int xoffset, int yoffset, int width, int height
|
||||
level,
|
||||
&box,
|
||||
data,
|
||||
static_cast<UINT>(width * 4),
|
||||
static_cast<UINT>(width * height * 4)
|
||||
(UINT)(width * 4),
|
||||
(UINT)(width * height * 4)
|
||||
);
|
||||
}
|
||||
|
||||
void Renderer::TextureDynamicUpdateEnd() {}
|
||||
void Renderer::TextureDynamicUpdateStart() {}
|
||||
|
||||
void Renderer::TextureFree(int idx)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::TextureFree", "TextureFree", MP_PURPLE4);
|
||||
m_textures[idx].texture->Release();
|
||||
m_textures[idx].view->Release();
|
||||
m_textures[idx].view = NULL;
|
||||
m_textures[idx].allocated = false;
|
||||
m_textures[idx].texture = NULL;
|
||||
}
|
||||
|
||||
void Renderer::TextureGetStats() {}
|
||||
|
||||
ID3D11ShaderResourceView* Renderer::TextureGetTexture(int idx)
|
||||
{
|
||||
if (idx < MAX_TEXTURES) {
|
||||
if (m_textures[idx].allocated) return m_textures[idx].view;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int Renderer::TextureGetTextureLevels()
|
||||
{
|
||||
Context& c = getContext();
|
||||
return m_textures[c.textureIdx].mipLevels;
|
||||
}
|
||||
|
||||
void Renderer::TextureSetParam(int param, int value)
|
||||
{
|
||||
Context& c = getContext();
|
||||
@@ -229,14 +292,10 @@ void Renderer::TextureSetParam(int param, int value)
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::TextureDynamicUpdateStart()
|
||||
void Renderer::TextureSetTextureLevels(int levels)
|
||||
{
|
||||
// TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
|
||||
}
|
||||
|
||||
void Renderer::TextureDynamicUpdateEnd()
|
||||
{
|
||||
// TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
|
||||
Context& c = getContext();
|
||||
m_textures[c.textureIdx].mipLevels = levels;
|
||||
}
|
||||
|
||||
void Renderer::UpdateTextureState(bool bVertex)
|
||||
@@ -250,101 +309,25 @@ void Renderer::UpdateTextureState(bool bVertex)
|
||||
c.m_pDeviceContext->PSSetSamplers(0, 1, &pSampler);
|
||||
}
|
||||
|
||||
HRESULT Renderer::LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
|
||||
void user_flush_data(png_struct_def* png_ptr) {}
|
||||
void user_write_data(png_struct_def* png_ptr, unsigned char* src, size_t length)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::LoadTextureData_File", "LoadTextureData_File", MP_PURPLE4)
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
int bytesToWrite = static_cast<int>(dataEnd - dataCurr);
|
||||
if (static_cast<int>(length) < bytesToWrite)
|
||||
bytesToWrite = (int)length;
|
||||
|
||||
if (!png_image_begin_read_from_file(&image, szFilename))
|
||||
return -1;
|
||||
|
||||
// TODO(3UR): why crash?
|
||||
//if ((image.format & 3u) > 1)
|
||||
// return -1;
|
||||
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
*ppDataOut = new int[image.width * image.height];
|
||||
if (!*ppDataOut || !png_image_finish_read(&image, NULL, *ppDataOut, 0, NULL))
|
||||
return -1;
|
||||
|
||||
pSrcInfo->Width = image.width;
|
||||
pSrcInfo->Height = image.height;
|
||||
return S_OK;
|
||||
std::memcpy(dataCurr, src, bytesToWrite);
|
||||
dataCurr += bytesToWrite;
|
||||
}
|
||||
|
||||
HRESULT Renderer::LoadTextureData(BYTE* pbData, DWORD dwBytes, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
|
||||
int user_write_data_bytes_written()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::LoadTextureData_Memory", "LoadTextureData_Memory", MP_PURPLE4)
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
if (!png_image_begin_read_from_memory(&image, pbData, dwBytes))
|
||||
return -1;
|
||||
|
||||
// TODO(3UR): why crash?
|
||||
//if ((image.format & 3u) > 1)
|
||||
// return -1;
|
||||
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
*ppDataOut = new int[image.width * image.height];
|
||||
if (!*ppDataOut || !png_image_finish_read(&image, NULL, *ppDataOut, 0, NULL))
|
||||
return -1;
|
||||
|
||||
pSrcInfo->Width = image.width;
|
||||
pSrcInfo->Height = image.height;
|
||||
return S_OK;
|
||||
return static_cast<int>(dataCurr - dataStart);
|
||||
}
|
||||
|
||||
HRESULT Renderer::SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int* ppDataOut)
|
||||
void user_write_data_init(unsigned char* pBuffer, int size)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::SaveTextureData", "SaveTextureData", MP_PURPLE4)
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.width = pSrcInfo->Width;
|
||||
image.height = pSrcInfo->Height;
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
png_image_write_to_file(&image, szFilename, 0, ppDataOut, 0, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Renderer::SaveTextureDataToMemory(void* pOutput, int outputCapacity, int* outputLength, int width, int height, int* ppDataIn)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::SaveTextureDataToMemory", "SaveTextureDataToMemory", MP_PURPLE4)
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
image.format = PNG_FORMAT_BGRA;
|
||||
|
||||
dataEnd = (BYTE*)pOutput + outputCapacity;
|
||||
dataStart = (BYTE*)pOutput;
|
||||
dataCurr = (BYTE*)pOutput;
|
||||
|
||||
png_image_write_to_stdio(&image, NULL, 0, ppDataIn, 0, NULL, user_write_data, user_flush_data);
|
||||
|
||||
*outputLength = static_cast<int>(dataCurr - dataStart);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Renderer::TextureGetStats()
|
||||
{
|
||||
// TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView* Renderer::TextureGetTexture(int idx)
|
||||
{
|
||||
if ((unsigned int)idx <= 511)
|
||||
{
|
||||
if (m_textures[idx].allocated)
|
||||
return m_textures[idx].view;
|
||||
}
|
||||
return NULL;
|
||||
dataStart = pBuffer;
|
||||
dataCurr = pBuffer;
|
||||
dataEnd = pBuffer + size;
|
||||
}
|
||||
@@ -28,14 +28,14 @@ SOFTWARE.
|
||||
void Renderer::DrawVertexBuffer(C4JRender::ePrimitiveType PrimitiveType, int count, ID3D11Buffer *buffer, C4JRender::eVertexType vType,
|
||||
C4JRender::ePixelShaderType psType)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::DrawVertexBuffer", "DrawVertexBuffer", MP_RED2)
|
||||
PROFILER_SCOPE("Renderer::DrawVertexBuffer", "DrawVertexBuffer", MP_RED2);
|
||||
Renderer::Context &c = getContext();
|
||||
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
|
||||
|
||||
int drawCount = count;
|
||||
bool indexed = false;
|
||||
|
||||
PROFILER_SCOPE("Renderer::DrawVertexBuffer", "DrawVertexSetup", MP_RED2)
|
||||
PROFILER_SCOPE("Renderer::DrawVertexBuffer", "DrawVertexSetup", MP_RED2);
|
||||
DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed);
|
||||
StateUpdate();
|
||||
|
||||
@@ -52,7 +52,7 @@ void Renderer::DrawVertexBuffer(C4JRender::ePrimitiveType PrimitiveType, int cou
|
||||
void Renderer::DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelShaderType psType, C4JRender::ePrimitiveType PrimitiveType, int *count,
|
||||
bool *indexed)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::DrawVertexSetup", "DrawVertexSetup", MP_RED2)
|
||||
PROFILER_SCOPE("Renderer::DrawVertexSetup", "DrawVertexSetup", MP_RED2);
|
||||
Renderer::Context &c = getContext();
|
||||
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
|
||||
|
||||
@@ -129,7 +129,7 @@ void Renderer::DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelSh
|
||||
void Renderer::DrawVertices(C4JRender::ePrimitiveType PrimitiveType, int count, void *vertices, C4JRender::eVertexType vType,
|
||||
C4JRender::ePixelShaderType psType)
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::DrawVertices", "DrawVertices", MP_RED2)
|
||||
PROFILER_SCOPE("Renderer::DrawVertices", "DrawVertices", MP_RED2);
|
||||
Renderer::Context &c = getContext();
|
||||
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
|
||||
Renderer::CommandBuffer *commandBuffer = c.commandBuffer;
|
||||
@@ -150,7 +150,7 @@ void Renderer::DrawVertices(C4JRender::ePrimitiveType PrimitiveType, int count,
|
||||
int drawCount = count;
|
||||
bool indexed = false;
|
||||
|
||||
PROFILER_SCOPE("Renderer::DrawVertices", "DrawVertexSetup", MP_RED2)
|
||||
PROFILER_SCOPE("Renderer::DrawVertices", "DrawVertexSetup", MP_RED2);
|
||||
DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed);
|
||||
|
||||
const UINT stride = vertexStrideTable[vType];
|
||||
|
||||
Reference in New Issue
Block a user