diff --git a/Windows_Libs/Dev/Render/Profiler.h b/Windows_Libs/Dev/Render/Profiler.h index 00c3af9..4c9229b 100644 --- a/Windows_Libs/Dev/Render/Profiler.h +++ b/Windows_Libs/Dev/Render/Profiler.h @@ -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 \ No newline at end of file diff --git a/Windows_Libs/Dev/Render/Renderer.h b/Windows_Libs/Dev/Render/Renderer.h index fc23523..64887c1 100644 --- a/Windows_Libs/Dev/Render/Renderer.h +++ b/Windows_Libs/Dev/Render/Renderer.h @@ -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; diff --git a/Windows_Libs/Dev/Render/RendererCBuff.cpp b/Windows_Libs/Dev/Render/RendererCBuff.cpp index b635a1a..7e535a4 100644 --- a/Windows_Libs/Dev/Render/RendererCBuff.cpp +++ b/Windows_Libs/Dev/Render/RendererCBuff.cpp @@ -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(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(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(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(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(m_vertexData) + vertexOffset, dataIn, byteCount); + std::memcpy(static_cast(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(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(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(command.set_blend_func.m_src); - c.blendDesc.RenderTarget[0].DestBlend = static_cast(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(static_cast(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(m_commandHandleToIndex); + std::int16_t *externalToInternal = static_cast(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(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(reservedRendererDword3)]; + } + } while (completedDeletes < static_cast(reservedRendererDword3)); } - reservedRendererDword3 = 0; LeaveCriticalSection(&m_commandBufferCS); } @@ -829,4 +462,384 @@ void Renderer::DeleteInternalBuffer(int index) } LeaveCriticalSection(&m_commandBufferCS); -} \ No newline at end of file +} + +void Renderer::CommandBuffer::EndRecording(ID3D11Device *device) +{ + if (m_vertexDataLength != 0) + { + D3D11_BUFFER_DESC desc = {}; + desc.ByteWidth = static_cast(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(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(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(command.set_blend_func.m_src); + c.blendDesc.RenderTarget[0].DestBlend = static_cast(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() {} diff --git a/Windows_Libs/Dev/Render/RendererCore.cpp b/Windows_Libs/Dev/Render/RendererCore.cpp index c352d37..ed95723 100644 --- a/Windows_Libs/Dev/Render/RendererCore.cpp +++ b/Windows_Libs/Dev/Render/RendererCore.cpp @@ -34,6 +34,7 @@ _RTL_CRITICAL_SECTION Renderer::totalAllocCS = {}; DWORD Renderer::s_auiWidths[] = { 1920, 512, 256, 128, 64, 0 }; DWORD Renderer::s_auiHeights[] = { 1080, 512, 256, 128, 64 }; int Renderer::totalAlloc = 0; +const float Renderer::PI = 3.14159274f; D3D11_INPUT_ELEMENT_DESC g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, @@ -109,17 +110,17 @@ Renderer::Context::Context(ID3D11Device* device, ID3D11DeviceContext* deviceCont , deferredBuffers() { deviceContext->QueryInterface(IID_PPV_ARGS(&userAnnotation)); - memset(matrixStacks, 0, sizeof(matrixStacks)); - memset(matrixDirty, 0, sizeof(matrixDirty)); - memset(stackPos, 0, sizeof(stackPos)); - memset(lightEnabled, 0, sizeof(lightEnabled)); - memset(lightDirection, 0, sizeof(lightDirection)); - memset(lightColour, 0, sizeof(lightColour)); - memset(&lightAmbientColour, 0, sizeof(lightAmbientColour)); - memset(texGenMatrices, 0, sizeof(texGenMatrices)); - memset(&blendDesc, 0, sizeof(blendDesc)); - memset(&depthStencilDesc, 0, sizeof(depthStencilDesc)); - memset(&rasterizerDesc, 0, sizeof(rasterizerDesc)); + std::memset(matrixStacks, 0, sizeof(matrixStacks)); + std::memset(matrixDirty, 0, sizeof(matrixDirty)); + std::memset(stackPos, 0, sizeof(stackPos)); + std::memset(lightEnabled, 0, sizeof(lightEnabled)); + std::memset(lightDirection, 0, sizeof(lightDirection)); + std::memset(lightColour, 0, sizeof(lightColour)); + std::memset(&lightAmbientColour, 0, sizeof(lightAmbientColour)); + std::memset(texGenMatrices, 0, sizeof(texGenMatrices)); + std::memset(&blendDesc, 0, sizeof(blendDesc)); + std::memset(&depthStencilDesc, 0, sizeof(depthStencilDesc)); + std::memset(&rasterizerDesc, 0, sizeof(rasterizerDesc)); blendFactor[0] = 0.0f; blendFactor[1] = 0.0f; blendFactor[2] = 0.0f; @@ -169,10 +170,10 @@ Renderer::Context::Context(ID3D11Device* device, ID3D11DeviceContext* deviceCont rasterizerDesc.MultisampleEnable = true; rasterizerDesc.AntialiasedLineEnable = false; - memset(lightDirection, 0, sizeof(lightDirection)); - memset(lightColour, 0, sizeof(lightColour)); - memset(&lightAmbientColour, 0, sizeof(lightAmbientColour)); - memset(texGenMatrices, 0, sizeof(texGenMatrices)); + std::memset(lightDirection, 0, sizeof(lightDirection)); + std::memset(lightColour, 0, sizeof(lightColour)); + std::memset(&lightAmbientColour, 0, sizeof(lightAmbientColour)); + std::memset(texGenMatrices, 0, sizeof(texGenMatrices)); const float zero4[4] = {0.0f, 0.0f, 0.0f, 0.0f}; const float one4[4] = {1.0f, 1.0f, 1.0f, 1.0f}; @@ -246,596 +247,82 @@ void Renderer::BeginConditionalRendering(int) {} void Renderer::BeginConditionalSurvey(int) {} -void Renderer::CaptureScreen(ImageFileBuffer *, XSOCIAL_PREVIEWIMAGE *) {} - -void Renderer::Clear(int flags, D3D11_RECT *) -{ - PROFILER_SCOPE("Renderer::Clear", "Clear", MP_MAGENTA) - - Renderer::Context &c = getContext(); - - ID3D11BlendState *blendState = NULL; - ID3D11DepthStencilState *depthState = NULL; - ID3D11RasterizerState *rasterizerState = NULL; - - PROFILER_SCOPE("Renderer::Clear", "Blend", MP_MAGENTA) - D3D11_BLEND_DESC blendDesc = {}; - blendDesc.AlphaToCoverageEnable = false; - blendDesc.IndependentBlendEnable = false; - blendDesc.RenderTarget[0].BlendEnable = false; - blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; - blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - blendDesc.RenderTarget[0].RenderTargetWriteMask = (flags & CLEAR_COLOUR_FLAG) ? D3D11_COLOR_WRITE_ENABLE_ALL : 0; - m_pDevice->CreateBlendState(&blendDesc, &blendState); - - PROFILER_SCOPE("Renderer::Clear", "Depth", MP_MAGENTA) - D3D11_DEPTH_STENCIL_DESC depthDesc = {}; - depthDesc.DepthEnable = (flags & CLEAR_DEPTH_FLAG) ? true : false; - depthDesc.DepthWriteMask = depthDesc.DepthEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; - depthDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - depthDesc.StencilEnable = false; - depthDesc.StencilReadMask = 0xFF; - depthDesc.StencilWriteMask = 0xFF; - depthDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - depthDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - depthDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - depthDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - depthDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - depthDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - depthDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - depthDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - m_pDevice->CreateDepthStencilState(&depthDesc, &depthState); - - PROFILER_SCOPE("Renderer::Clear", "Rasterizer", MP_MAGENTA) - D3D11_RASTERIZER_DESC rasterDesc = {}; - rasterDesc.FillMode = D3D11_FILL_SOLID; - rasterDesc.CullMode = D3D11_CULL_NONE; - rasterDesc.DepthClipEnable = true; - rasterDesc.MultisampleEnable = true; - m_pDevice->CreateRasterizerState(&rasterDesc, &rasterizerState); - - PROFILER_SCOPE("Renderer::Clear", "DrawClearQuad", MP_MAGENTA) - c.m_pDeviceContext->VSSetShader(screenClearVertexShader, NULL, 0); - c.m_pDeviceContext->IASetInputLayout(NULL); - c.m_pDeviceContext->PSSetShader(screenClearPixelShader, NULL, 0); - c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView); - c.m_pDeviceContext->OMSetBlendState(blendState, NULL, 0xFFFFFFFF); - c.m_pDeviceContext->OMSetDepthStencilState(depthState, 0); - c.m_pDeviceContext->RSSetState(rasterizerState); - c.m_pDeviceContext->PSSetShaderResources(0, 0, NULL); - c.m_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - c.m_pDeviceContext->Draw(4, 0); - - if (blendState) - { - blendState->Release(); - blendState = NULL; - } - if (depthState) - { - depthState->Release(); - depthState = NULL; - } - if (rasterizerState) - { - rasterizerState->Release(); - rasterizerState = NULL; - } - - c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF); - c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0); - c.m_pDeviceContext->RSSetState(GetManagedRasterizerState()); - c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView); - - activeVertexType = -1; - activePixelType = -1; -} - -void Renderer::ConvertLinearToPng(ImageFileBuffer *pngOut, unsigned char *linearData, unsigned int width, unsigned int height) -{ - const size_t dataSize = static_cast(width) * static_cast(height) * 4; - const size_t outputCapacity = (dataSize * 24) / 20 + 256; - - void *outputBuffer = malloc(outputCapacity); - int outputLength = 0; - - SaveTextureDataToMemory( - outputBuffer, - static_cast(outputCapacity), - &outputLength, - static_cast(width), - static_cast(height), - reinterpret_cast(linearData) - ); - - pngOut->m_type = ImageFileBuffer::e_typePNG; - pngOut->m_pBuffer = outputBuffer; - pngOut->m_bufferSize = outputLength; -} - -void Renderer::DoScreenGrabOnNextPresent() -{ - m_bShouldScreenGrabNextFrame = true; -} - -void Renderer::EndConditionalRendering() {} -void Renderer::EndConditionalSurvey() {} - void Renderer::BeginEvent(LPCWSTR eventName) { - Renderer::Context &c = Renderer::getContext(); - if (c.m_pDeviceContext->GetType() != D3D11_DEVICE_CONTEXT_DEFERRED && c.userAnnotation) + Renderer::Context *c = reinterpret_cast(TlsGetValue(Renderer::tlsIdx)); + if (c && c->m_pDeviceContext->GetType() != D3D11_DEVICE_CONTEXT_DEFERRED) { - c.userAnnotation->BeginEvent(eventName); - ++c.annotateDepth; + c->userAnnotation->BeginEvent(eventName); + ++c->annotateDepth; } } -void Renderer::EndEvent() -{ - Renderer::Context &c = Renderer::getContext(); - if (c.m_pDeviceContext->GetType() != D3D11_DEVICE_CONTEXT_DEFERRED && c.userAnnotation) - { - c.userAnnotation->EndEvent(); - --c.annotateDepth; - assert(c.annotateDepth >= 0); - } -} - -void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain) -{ - m_pDevice = pDevice; - m_pDeviceContext = InitialiseContext(true); - m_pSwapChain = pSwapChain; - - #ifdef ENABLE_PROFILING - MicroProfileOnThreadCreate("MainRenderThread"); - MicroProfileSetEnableAllGroups(true); - #endif - - m_commandHandleToIndex = new int16_t[NUM_COMMAND_HANDLES]; - m_commandBuffers = new CommandBuffer *[MAX_COMMAND_BUFFERS]; - m_commandMatrices = new DirectX::XMMATRIX[MAX_COMMAND_BUFFERS]; - m_commandIndexToHandle = new int[MAX_COMMAND_BUFFERS]; - m_commandVertexTypes = new uint8_t[MAX_COMMAND_BUFFERS]; - m_commandPrimitiveTypes = new uint8_t[MAX_COMMAND_BUFFERS]; - - memset(m_commandHandleToIndex, 0xFF, NUM_COMMAND_HANDLES * sizeof(int16_t)); - memset(m_commandBuffers, 0, MAX_COMMAND_BUFFERS * sizeof(CommandBuffer*)); - memset(m_commandIndexToHandle, 0, MAX_COMMAND_BUFFERS * sizeof(int)); - memset(m_commandVertexTypes, 0, MAX_COMMAND_BUFFERS * sizeof(uint8_t)); - memset(m_commandPrimitiveTypes, 0, MAX_COMMAND_BUFFERS * sizeof(uint8_t)); - - reservedRendererDword3 = 0; - m_bShouldScreenGrabNextFrame = false; - m_bSuspended = false; - - SetupShaders(); - const float clearColour[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - SetClearColour(clearColour); - - UINT backBufferSampleCount = 1; - UINT backBufferSampleQuality = 0; - - ID3D11Texture2D *backBuffer = NULL; - pSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); - if (backBuffer) - { - D3D11_TEXTURE2D_DESC backDesc = {}; - backBuffer->GetDesc(&backDesc); - backBufferWidth = backDesc.Width; - backBufferHeight = backDesc.Height; - backBufferSampleCount = backDesc.SampleDesc.Count; - backBufferSampleQuality = backDesc.SampleDesc.Quality; - - m_pDevice->CreateRenderTargetView(backBuffer, NULL, &renderTargetView); - - D3D11_TEXTURE2D_DESC srvDesc = backDesc; - srvDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; - srvDesc.MiscFlags = 0; - - ID3D11Texture2D *srvTexture = NULL; - m_pDevice->CreateTexture2D(&srvDesc, NULL, &srvTexture); - m_pDevice->CreateShaderResourceView(srvTexture, NULL, &renderTargetShaderResourceView); - - srvTexture->Release(); - backBuffer->Release(); - } - - ID3D11RenderTargetView *boundRTV = NULL; - m_pDeviceContext->OMGetRenderTargets(1, &boundRTV, &depthStencilView); - if (boundRTV) - boundRTV->Release(); - - if (!depthStencilView && backBufferWidth != 0 && backBufferHeight != 0) - { - D3D11_TEXTURE2D_DESC depthDesc = {}; - depthDesc.Width = backBufferWidth; - depthDesc.Height = backBufferHeight; - depthDesc.MipLevels = 1; - depthDesc.ArraySize = 1; - depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depthDesc.SampleDesc.Count = backBufferSampleCount; - depthDesc.SampleDesc.Quality = backBufferSampleQuality; - depthDesc.Usage = D3D11_USAGE_DEFAULT; - depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - - ID3D11Texture2D *depthTexture = NULL; - if (SUCCEEDED(m_pDevice->CreateTexture2D(&depthDesc, NULL, &depthTexture))) - { - m_pDevice->CreateDepthStencilView(depthTexture, NULL, &depthStencilView); - depthTexture->Release(); - } - } - - D3D11_TEXTURE2D_DESC desc = {}; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - for (UINT i = 0; i < MAX_MIP_LEVELS - 1; ++i) - { - desc.Width = s_auiWidths[i + 1]; - desc.Height = s_auiHeights[i + 1]; - - HRESULT hr = m_pDevice->CreateTexture2D(&desc, NULL, &renderTargetTextures[i]); - assert(hr == S_OK); - - hr = m_pDevice->CreateRenderTargetView(renderTargetTextures[i], NULL, &renderTargetViews[i]); - assert(hr == S_OK); - - hr = m_pDevice->CreateShaderResourceView(renderTargetTextures[i], NULL, &renderTargetShaderResourceViews[i]); - assert(hr == S_OK); - } - - memset(m_textures, 0, sizeof(m_textures)); - defaultTextureIndex = TextureCreate(); - TextureBind(defaultTextureIndex); - - unsigned char *defaultTextureData = new unsigned char[0x400]; - memset(defaultTextureData, 0xFF, 0x400); - TextureData(16, 16, defaultTextureData, 0, C4JRender::TEXTURE_FORMAT_RxGyBzAw); - delete[] defaultTextureData; - - presentCount = 0; - rendererFlag0 = 0; - reservedRendererWord0 = 10922; - StateSetViewport(C4JRender::VIEWPORT_TYPE_FULLSCREEN); - StateSetVertexTextureUV(0.0f, 0.0f); - TextureBindVertex(-1); - - InitializeCriticalSection(&m_commandBufferCS); - - reservedRendererDword1 = 0; - activeVertexType = -1; - activePixelType = -1; - reservedRendererByte1 = 1; - reservedRendererByte0 = 0; - - unsigned short *quadIndices = new unsigned short[0x18000]; - for (UINT i = 0; i < 0x4000; ++i) - { - unsigned short base = static_cast(i * 4); - unsigned int offset = i * 6; - quadIndices[offset + 0] = base; - quadIndices[offset + 1] = base + 1; - quadIndices[offset + 2] = base + 3; - quadIndices[offset + 3] = base + 1; - quadIndices[offset + 4] = base + 2; - quadIndices[offset + 5] = base + 3; - } - - D3D11_BUFFER_DESC quadIndexDesc = {}; - quadIndexDesc.ByteWidth = 0x30000; - quadIndexDesc.Usage = D3D11_USAGE_IMMUTABLE; - quadIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - quadIndexDesc.CPUAccessFlags = 0; - quadIndexDesc.MiscFlags = 0; - - D3D11_SUBRESOURCE_DATA quadIndexData = {}; - quadIndexData.pSysMem = quadIndices; - HRESULT hr = m_pDevice->CreateBuffer(&quadIndexDesc, &quadIndexData, &quadIndexBuffer); - assert(hr >= 0); - delete[] quadIndices; - - unsigned short *fanIndices = new unsigned short[0x2FFFA]; - for (UINT i = 0; i < 65534; ++i) - { - unsigned int offset = i * 3; - fanIndices[offset + 0] = 0; - fanIndices[offset + 1] = static_cast(i + 1); - fanIndices[offset + 2] = static_cast(i + 2); - } - - D3D11_BUFFER_DESC fanIndexDesc = {}; - fanIndexDesc.ByteWidth = 0x5FFF4; - fanIndexDesc.Usage = D3D11_USAGE_IMMUTABLE; - fanIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - - D3D11_SUBRESOURCE_DATA fanIndexData = {}; - fanIndexData.pSysMem = fanIndices; - m_pDevice->CreateBuffer(&fanIndexDesc, &fanIndexData, &fanIndexBuffer); - delete[] fanIndices; - - InitializeCriticalSection(&Renderer::totalAllocCS); -} - -ID3D11DeviceContext *Renderer::InitialiseContext(bool fromPresent) -{ - ID3D11DeviceContext *deviceContext = NULL; - - if (fromPresent) - m_pDevice->GetImmediateContext(&deviceContext); - else - m_pDevice->CreateDeferredContext(0, &deviceContext); - - Renderer::Context *c = new (std::nothrow) Renderer::Context(m_pDevice, deviceContext); - TlsSetValue(Renderer::tlsIdx, c); - - return deviceContext; -} - -bool Renderer::IsHiDef() -{ - return true; -} - -bool Renderer::IsWidescreen() -{ - return true; -} - -void Renderer::Present() -{ - PROFILER_SCOPE("Renderer::Present", "Present", MP_MAGENTA) - - if (m_bShouldScreenGrabNextFrame) - { - PROFILER_SCOPE("Renderer::Present", "ScreenGrab", MP_MAGENTA) - - unsigned char *linearData = new unsigned char[kScreenGrabWidth * kScreenGrabHeight * 4]; - - ID3D11Texture2D *backBuffer = NULL; - ID3D11Texture2D *stagingTexture = NULL; - - m_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); - if (backBuffer) - { - D3D11_TEXTURE2D_DESC desc = {}; - backBuffer->GetDesc(&desc); - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.MiscFlags = 0; - m_pDevice->CreateTexture2D(&desc, NULL, &stagingTexture); - } - - if (stagingTexture && backBuffer) - { - PROFILER_SCOPE("Renderer::Present", "CopyResource", MP_MAGENTA) - m_pDeviceContext->CopyResource(stagingTexture, backBuffer); - - D3D11_MAPPED_SUBRESOURCE mapped = {}; - if (SUCCEEDED(m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mapped))) - { - const unsigned char *src = reinterpret_cast(mapped.pData); - - for (UINT y = 0; y < kScreenGrabHeight; ++y) - { - unsigned char *dstRow = linearData + y * kScreenGrabWidth * 4; - const unsigned char *srcRow = src + y * mapped.RowPitch; - memcpy(dstRow, srcRow, kScreenGrabWidth * 4); - - for (UINT x = 0; x < kScreenGrabWidth; ++x) - dstRow[x * 4 + 3] = 0xFF; - } - - m_pDeviceContext->Unmap(stagingTexture, 0); - } - } - - static int count = 0; - char fileName[304]; - sprintf_s(fileName, "d:\\screen%d.png", count++); - - D3DXIMAGE_INFO info; - info.Width = kScreenGrabWidth; - info.Height = kScreenGrabHeight; - SaveTextureData(fileName, &info, reinterpret_cast(linearData)); - - delete[] linearData; - - if (stagingTexture) - { - stagingTexture->Release(); - stagingTexture = NULL; - } - if (backBuffer) - { - backBuffer->Release(); - backBuffer = NULL; - } - - m_bShouldScreenGrabNextFrame = false; - } - - m_pSwapChain->Present(1, 0); - ++presentCount; -} - -void Renderer::Resume() -{ - m_bSuspended = false; -} - -void Renderer::SetClearColour(const float colourRGBA[4]) -{ - for (int i = 0; i < 4; ++i) - m_fClearColor[i] = colourRGBA[i]; - - Renderer::Context &c = getContext(); - if (&c) - { - D3D11_MAPPED_SUBRESOURCE mapped = {}; - if (SUCCEEDED(c.m_pDeviceContext->Map(c.m_clearColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) - { - *(DirectX::XMVECTOR*)mapped.pData = DirectX::XMVectorSet(colourRGBA[0], colourRGBA[1], colourRGBA[2], colourRGBA[3]); - c.m_pDeviceContext->Unmap(c.m_clearColorBuffer, 0); - } - } -} - -void Renderer::SetupShaders() -{ - vertexShaderTable = new ID3D11VertexShader *[C4JRender::VERTEX_TYPE_COUNT]; - pixelShaderTable = new ID3D11PixelShader *[C4JRender::PIXEL_SHADER_COUNT]; - vertexStrideTable = new unsigned int[C4JRender::VERTEX_TYPE_COUNT]; - inputLayoutTable = new ID3D11InputLayout *[C4JRender::VERTEX_TYPE_COUNT]; - - for (UINT i = 0; i < C4JRender::VERTEX_TYPE_COUNT; ++i) - { - vertexShaderTable[i] = NULL; - inputLayoutTable[i] = NULL; - vertexStrideTable[i] = g_vertexStrides[i]; - } - - for (UINT i = 0; i < C4JRender::PIXEL_SHADER_COUNT; ++i) - { - pixelShaderTable[i] = NULL; - } - - screenSpaceVertexShader = NULL; - screenClearVertexShader = NULL; - screenSpacePixelShader = NULL; - screenClearPixelShader = NULL; - - m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]); - m_pDevice->CreateVertexShader(g_main_VS_Compressed, sizeof(g_main_VS_Compressed), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_COMPRESSED]); - m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]); - m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]); - m_pDevice->CreateVertexShader(g_main_VS_ScreenSpace, sizeof(g_main_VS_ScreenSpace), NULL, &screenSpaceVertexShader); - m_pDevice->CreateVertexShader(g_main_VS_ScreenClear, sizeof(g_main_VS_ScreenClear), NULL, &screenClearVertexShader); - - m_pDevice->CreatePixelShader(g_main_PS_Standard, sizeof(g_main_PS_Standard), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_STANDARD]); - m_pDevice->CreatePixelShader(g_main_PS_TextureProjection, sizeof(g_main_PS_TextureProjection), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_PROJECTION]); - m_pDevice->CreatePixelShader(g_main_PS_ForceLOD, sizeof(g_main_PS_ForceLOD), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_FORCELOD]); - m_pDevice->CreatePixelShader(g_main_PS_ScreenSpace, sizeof(g_main_PS_ScreenSpace), NULL, &screenSpacePixelShader); - m_pDevice->CreatePixelShader(g_main_PS_ScreenClear, sizeof(g_main_PS_ScreenClear), NULL, &screenClearPixelShader); - - m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]); - m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_Compressed, 2, g_main_VS_Compressed, sizeof(g_main_VS_Compressed), &inputLayoutTable[C4JRender::VERTEX_TYPE_COMPRESSED]); - m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]); - m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]); -} - -void Renderer::StartFrame() -{ - PROFILER_SCOPE("Renderer::StartFrame", "StartFrame", MP_MAGENTA) - - Renderer::Context &c = getContext(); - - activeVertexType = -1; - activePixelType = -1; - - TextureBindVertex(-1); - TextureBind(-1); - - PROFILER_SCOPE("Renderer::StartFrame", "State", MP_MAGENTA) - - StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); - StateSetDepthMask(true); - StateSetBlendEnable(true); - StateSetBlendFunc(D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA); - StateSetBlendFactor(0xFFFFFFFF); - StateSetAlphaFunc(D3D11_COMPARISON_GREATER, 0.1f); - StateSetDepthFunc(D3D11_COMPARISON_LESS_EQUAL); - StateSetFaceCull(true); - StateSetLineWidth(1.0f); - StateSetWriteEnable(true, true, true, true); - StateSetDepthTestEnable(false); - StateSetAlphaTestEnable(true); - - c.m_pDeviceContext->VSSetConstantBuffers(0, 10, &c.m_modelViewMatrix); - c.m_pDeviceContext->PSSetConstantBuffers(0, 6, &c.m_tintColorBuffer); - - D3D11_VIEWPORT viewport = {}; - viewport.TopLeftX = 0.0f; - viewport.TopLeftY = 0.0f; - viewport.Width = (float)backBufferWidth; - viewport.Height = (float)backBufferHeight; - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - c.m_pDeviceContext->RSSetViewports(1, &viewport); - c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView); - - #ifdef ENABLE_PROFILING - MicroProfileFlip(nullptr); - #endif -} - -void Renderer::Suspend() -{ - m_bSuspended = true; -} - -bool Renderer::Suspended() -{ - return m_bSuspended; -} - -void Renderer::UpdateGamma(unsigned short) {} - -Renderer::Context &Renderer::getContext() -{ - return *reinterpret_cast(TlsGetValue(Renderer::tlsIdx)); -} +void Renderer::CaptureScreen(ImageFileBuffer *, XSOCIAL_PREVIEWIMAGE *) {} void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) { Renderer::Context &c = getContext(); - float left = 0.0f; - float bottom = 0.0f; - float right = 1.0f; - float top = 1.0f; - + float left; + float bottom; + float right; + float top; + switch (m_ViewportType) { - case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: - bottom = 0.5f; + case C4JRender::VIEWPORT_TYPE_FULLSCREEN: + left = 0.0f; + bottom = 0.0f; + right = 1.0f; + top = 1.0f; break; - case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + left = 0.0f; + bottom = 0.0f; + right = 1.0f; top = 0.5f; break; + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + left = 0.0f; + bottom = 0.5f; + right = 1.0f; + top = 1.0f; + break; case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: + left = 0.0f; + bottom = 0.0f; right = 0.5f; + top = 1.0f; break; case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: - left = 0.5f; + left = 0.0f; + bottom = 0.0f; + right = 0.5f; + top = 1.0f; break; case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: + left = 0.0f; + bottom = 0.0f; right = 0.5f; - bottom = 0.5f; + top = 0.5f; break; case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: left = 0.5f; - bottom = 0.5f; + bottom = 0.0f; + right = 1.0f; + top = 0.5f; break; case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: + left = 0.0f; right = 0.5f; - top = 0.5f; + bottom = 0.5f; + top = 1.0f; break; case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: left = 0.5f; - top = 0.5f; + right = 1.0f; + bottom = 0.5f; + top = 1.0f; break; default: break; @@ -908,9 +395,9 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.MaxAnisotropy = 1; + samplerDesc.MaxAnisotropy = 16; samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - samplerDesc.MinLOD = 0.0f; + samplerDesc.MinLOD = -(std::numeric_limits::max)(); samplerDesc.MaxLOD = (std::numeric_limits::max)(); m_pDevice->CreateSamplerState(&samplerDesc, &samplerState); @@ -920,6 +407,10 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) c.m_pDeviceContext->OMSetBlendState(blendState, NULL, -1); c.m_pDeviceContext->OMSetDepthStencilState(depthState, 0); c.m_pDeviceContext->RSSetState(rasterizerState); + blendState->Release(); + depthState->Release(); + rasterizerState->Release(); + c.m_pDeviceContext->PSSetShaderResources(0, 0, NULL); for (UINT i = 0; i < MAX_MIP_LEVELS - 1; ++i) { @@ -942,7 +433,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) D3D11_MAPPED_SUBRESOURCE mapped = {}; c.m_pDeviceContext->Map(c.m_thumbnailBoundsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - float *constants = (float *)mapped.pData; + float* constants = static_cast(mapped.pData); if (i == 0) { constants[0] = left; @@ -966,7 +457,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) renderTargetTextures[MAX_MIP_LEVELS - 2]->GetDesc(&texDesc); texDesc.Usage = D3D11_USAGE_STAGING; texDesc.BindFlags = 0; - texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; texDesc.MiscFlags = 0; m_pDevice->CreateTexture2D(&texDesc, NULL, &stagingTexture); @@ -978,68 +469,55 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) c.m_pDeviceContext->CopyResource(stagingTexture, renderTargetTextures[MAX_MIP_LEVELS - 2]); D3D11_MAPPED_SUBRESOURCE mapped = {}; - if (SUCCEEDED(c.m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mapped))) + c.m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ_WRITE, 0, &mapped); + const unsigned char* src = static_cast(mapped.pData); + unsigned char* dst = linearData; + + for (UINT y = 0; y < kThumbnailSize; ++y) { - const unsigned char *src = static_cast(mapped.pData); - unsigned char *dst = linearData; + std::memcpy(dst, src, stride); - for (UINT y = 0; y < kThumbnailSize; ++y) + unsigned char* alpha = dst + 3; + for (UINT x = 0; x < kThumbnailSize; ++x) { - memcpy(dst, src, stride); - - unsigned char *alpha = dst + 3; - for (UINT x = 0; x < kThumbnailSize; ++x) - { - *alpha = 0xFF; - alpha += 4; - } - - src += mapped.RowPitch; - dst += stride; + *alpha = 0xFF; + alpha += 4; } - c.m_pDeviceContext->Unmap(stagingTexture, 0); + src += mapped.RowPitch; + dst += stride; } + + c.m_pDeviceContext->Unmap(stagingTexture, 0); } ConvertLinearToPng(pngOut, linearData, kThumbnailSize, kThumbnailSize); delete[] linearData; - if (stagingTexture) - { - stagingTexture->Release(); - stagingTexture = NULL; - } - if (samplerState) - { - samplerState->Release(); - samplerState = NULL; - } - if (rasterizerState) - { - rasterizerState->Release(); - rasterizerState = NULL; - } - if (depthState) - { - depthState->Release(); - depthState = NULL; - } - if (blendState) - { - blendState->Release(); - blendState = NULL; - } + stagingTexture->Release(); + samplerState->Release(); - c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, -1); - c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0); - c.m_pDeviceContext->RSSetState(GetManagedRasterizerState()); + ID3D11BlendState *restoredBlendState = NULL; + ID3D11DepthStencilState *restoredDepthState = NULL; + ID3D11RasterizerState *restoredRasterizerState = NULL; + + m_pDevice->CreateBlendState(&c.blendDesc, &restoredBlendState); + c.m_pDeviceContext->OMSetBlendState(restoredBlendState, c.blendFactor, 0xFFFFFFFF); + restoredBlendState->Release(); + + m_pDevice->CreateDepthStencilState(&c.depthStencilDesc, &restoredDepthState); + c.m_pDeviceContext->OMSetDepthStencilState(restoredDepthState, 0); + restoredDepthState->Release(); + + m_pDevice->CreateRasterizerState(&c.rasterizerDesc, &restoredRasterizerState); + c.m_pDeviceContext->RSSetState(restoredRasterizerState); + restoredRasterizerState->Release(); D3D11_VIEWPORT viewport = {}; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; - viewport.Width = (float)backBufferWidth; - viewport.Height = (float)backBufferHeight; + viewport.Width = static_cast(backBufferWidth); + viewport.Height = static_cast(backBufferHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; @@ -1049,3 +527,480 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) activeVertexType = -1; activePixelType = -1; } + +void Renderer::Clear(int flags, D3D11_RECT *) +{ + PROFILER_SCOPE("Renderer::Clear", "Clear", MP_MAGENTA); + + Renderer::Context *c = reinterpret_cast(TlsGetValue(Renderer::tlsIdx)); + unsigned char clearFlags = static_cast(flags); + + ID3D11BlendState *blendState = NULL; + ID3D11DepthStencilState *depthState = NULL; + ID3D11RasterizerState *rasterizerState = NULL; + + PROFILER_SCOPE("Renderer::Clear", "Blend", MP_MAGENTA); + D3D11_BLEND_DESC blendDesc = {}; + blendDesc.AlphaToCoverageEnable = false; + blendDesc.IndependentBlendEnable = false; + blendDesc.RenderTarget[0].BlendEnable = false; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = (clearFlags & CLEAR_COLOUR_FLAG) ? D3D11_COLOR_WRITE_ENABLE_ALL : 0; + m_pDevice->CreateBlendState(&blendDesc, &blendState); + + PROFILER_SCOPE("Renderer::Clear", "Depth", MP_MAGENTA); + D3D11_DEPTH_STENCIL_DESC depthDesc = {}; + depthDesc.DepthEnable = (clearFlags & CLEAR_DEPTH_FLAG) ? true : false; + depthDesc.DepthWriteMask = depthDesc.DepthEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + depthDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthDesc.StencilEnable = false; + depthDesc.StencilReadMask = 0xFF; + depthDesc.StencilWriteMask = 0xFF; + depthDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + m_pDevice->CreateDepthStencilState(&depthDesc, &depthState); + + PROFILER_SCOPE("Renderer::Clear", "Rasterizer", MP_MAGENTA); + D3D11_RASTERIZER_DESC rasterDesc = {}; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.DepthClipEnable = true; + rasterDesc.MultisampleEnable = true; + m_pDevice->CreateRasterizerState(&rasterDesc, &rasterizerState); + + PROFILER_SCOPE("Renderer::Clear", "DrawClearQuad", MP_MAGENTA); + m_pDeviceContext->VSSetShader(screenClearVertexShader, NULL, 0); + m_pDeviceContext->IASetInputLayout(NULL); + m_pDeviceContext->PSSetShader(screenClearPixelShader, NULL, 0); + m_pDeviceContext->OMSetBlendState(blendState, NULL, 0xFFFFFFFF); + m_pDeviceContext->OMSetDepthStencilState(depthState, 0); + m_pDeviceContext->RSSetState(rasterizerState); + c->m_pDeviceContext->PSSetShaderResources(0, 0, NULL); + c->m_pDeviceContext->IASetVertexBuffers(0, 0, NULL, NULL, NULL); + m_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + m_pDeviceContext->Draw(4, 0); + + blendState->Release(); + depthState->Release(); + rasterizerState->Release(); + + ID3D11BlendState *restoredBlendState = NULL; + ID3D11DepthStencilState *restoredDepthState = NULL; + ID3D11RasterizerState *restoredRasterizerState = NULL; + + m_pDevice->CreateBlendState(&c->blendDesc, &restoredBlendState); + m_pDeviceContext->OMSetBlendState(restoredBlendState, c->blendFactor, 0xFFFFFFFF); + restoredBlendState->Release(); + + m_pDevice->CreateDepthStencilState(&c->depthStencilDesc, &restoredDepthState); + m_pDeviceContext->OMSetDepthStencilState(restoredDepthState, 0); + restoredDepthState->Release(); + + m_pDevice->CreateRasterizerState(&c->rasterizerDesc, &restoredRasterizerState); + m_pDeviceContext->RSSetState(restoredRasterizerState); + restoredRasterizerState->Release(); + + activeVertexType = -1; + activePixelType = -1; +} + +void Renderer::ConvertLinearToPng(ImageFileBuffer *pngOut, unsigned char *linearData, unsigned int width, unsigned int height) +{ + const size_t dataSize = static_cast(width) * static_cast(height) * 4; + const size_t outputCapacity = (dataSize * 24) / 20 + 256; + + void *outputBuffer = std::malloc(outputCapacity); + int outputLength = 0; + + SaveTextureDataToMemory( + outputBuffer, + static_cast(outputCapacity), + &outputLength, + static_cast(width), + static_cast(height), + reinterpret_cast(linearData) + ); + + pngOut->m_type = ImageFileBuffer::e_typePNG; + pngOut->m_pBuffer = outputBuffer; + pngOut->m_bufferSize = outputLength; +} + +void Renderer::DoScreenGrabOnNextPresent() +{ + m_bShouldScreenGrabNextFrame = true; +} + +void Renderer::EndConditionalRendering() {} +void Renderer::EndConditionalSurvey() {} + +void Renderer::EndEvent() +{ + Renderer::Context *c = reinterpret_cast(TlsGetValue(Renderer::tlsIdx)); + if (c && c->m_pDeviceContext->GetType() != D3D11_DEVICE_CONTEXT_DEFERRED) + { + c->userAnnotation->EndEvent(); + if (--c->annotateDepth < 0) + c->annotateDepth = 0; + } +} + +void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain) +{ + m_pDevice = pDevice; + m_pDeviceContext = InitialiseContext(true); + m_pSwapChain = pSwapChain; + + PROFILER_INIT(); + + m_commandHandleToIndex = new int16_t[NUM_COMMAND_HANDLES]; + m_commandBuffers = new CommandBuffer *[MAX_COMMAND_BUFFERS]; + m_commandMatrices = new DirectX::XMMATRIX[MAX_COMMAND_BUFFERS]; + m_commandIndexToHandle = new int[MAX_COMMAND_BUFFERS]; + m_commandPrimitiveTypes = new uint8_t[MAX_COMMAND_BUFFERS]; + m_commandVertexTypes = new uint8_t[MAX_COMMAND_BUFFERS]; + + std::memset(m_commandHandleToIndex, 0xFF, 0x1000000u); + std::memset(m_commandBuffers, 0, 0xFA00u); + std::memset(m_commandIndexToHandle, 0, 0xFA00u); + std::memset(m_commandPrimitiveTypes, 0, 0x3E80u); + std::memset(m_commandVertexTypes, 0, 0x3E80u); + + reservedRendererDword3 = 0; + m_bShouldScreenGrabNextFrame = false; + + SetupShaders(); + const float clearColour[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + SetClearColour(clearColour); + + m_pDeviceContext->OMGetRenderTargets(1, &renderTargetView, &depthStencilView); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = 0; + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + + ID3D11Resource *backBufferResource = NULL; + ID3D11Texture2D *backBufferTexture = NULL; + renderTargetView->GetResource(&backBufferResource); + backBufferResource->QueryInterface(IID_PPV_ARGS(&backBufferTexture)); + + D3D11_TEXTURE2D_DESC backDesc = {}; + backBufferTexture->GetDesc(&backDesc); + backBufferWidth = backDesc.Width; + backBufferHeight = backDesc.Height; + renderTargetTextures[0] = backBufferTexture; + + m_pDevice->CreateRenderTargetView(backBufferTexture, &rtvDesc, &renderTargetView); + m_pDevice->CreateShaderResourceView(backBufferTexture, &srvDesc, &renderTargetShaderResourceView); + backBufferResource->Release(); + + D3D11_TEXTURE2D_DESC desc = {}; + desc.Width = 0; + desc.Height = 0; + desc.ArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + for (UINT i = 0; i < MAX_MIP_LEVELS - 1; ++i) + { + desc.Width = s_auiWidths[i + 1]; + desc.Height = s_auiHeights[i + 1]; + + m_pDevice->CreateTexture2D(&desc, NULL, &renderTargetTextures[i]); + m_pDevice->CreateRenderTargetView(renderTargetTextures[i], &rtvDesc, &renderTargetViews[i]); + m_pDevice->CreateShaderResourceView(renderTargetTextures[i], &srvDesc, &renderTargetShaderResourceViews[i]); + } + + std::memset(m_textures, 0, sizeof(m_textures)); + defaultTextureIndex = TextureCreate(); + TextureBind(defaultTextureIndex); + + unsigned char *defaultTextureData = new unsigned char[0x400]; + std::memset(defaultTextureData, 0xFF, 0x400); + TextureData(16, 16, defaultTextureData, 0, C4JRender::TEXTURE_FORMAT_RxGyBzAw); + delete[] defaultTextureData; + + presentCount = 0; + rendererFlag0 = 0; + reservedRendererWord0 = 10922; + StateSetViewport(C4JRender::VIEWPORT_TYPE_FULLSCREEN); + StateSetVertexTextureUV(0.0f, 0.0f); + TextureBindVertex(-1); + + InitializeCriticalSection(&m_commandBufferCS); + + reservedRendererDword1 = 0; + activeVertexType = -1; + reservedRendererByte1 = 1; + activePixelType = -1; + reservedRendererByte0 = 0; + + unsigned short *quadIndices = new unsigned short[0x18000]; + for (UINT i = 0; i < 0x4000; ++i) + { + unsigned short base = static_cast(i * 4); + unsigned int offset = i * 6; + quadIndices[offset + 0] = base; + quadIndices[offset + 1] = base + 1; + quadIndices[offset + 2] = base + 3; + quadIndices[offset + 3] = base + 1; + quadIndices[offset + 4] = base + 2; + quadIndices[offset + 5] = base + 3; + } + + D3D11_BUFFER_DESC quadIndexDesc = {}; + quadIndexDesc.ByteWidth = 0x30000; + quadIndexDesc.Usage = D3D11_USAGE_IMMUTABLE; + quadIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + quadIndexDesc.CPUAccessFlags = 0; + quadIndexDesc.MiscFlags = 0; + + D3D11_SUBRESOURCE_DATA quadIndexData = {}; + quadIndexData.pSysMem = quadIndices; + HRESULT hr = m_pDevice->CreateBuffer(&quadIndexDesc, &quadIndexData, &quadIndexBuffer); + assert(hr >= 0); + delete[] quadIndices; + + unsigned short *fanIndices = new unsigned short[0x2FFFA]; + for (UINT i = 0; i < 65534; ++i) + { + unsigned int offset = i * 3; + fanIndices[offset + 0] = 0; + fanIndices[offset + 1] = static_cast(i + 1); + fanIndices[offset + 2] = static_cast(i + 2); + } + + D3D11_BUFFER_DESC fanIndexDesc = {}; + fanIndexDesc.ByteWidth = 0x5FFF4; + fanIndexDesc.Usage = D3D11_USAGE_IMMUTABLE; + fanIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + + D3D11_SUBRESOURCE_DATA fanIndexData = {}; + fanIndexData.pSysMem = fanIndices; + m_pDevice->CreateBuffer(&fanIndexDesc, &fanIndexData, &fanIndexBuffer); + delete[] fanIndices; + + InitializeCriticalSection(&Renderer::totalAllocCS); +} + +ID3D11DeviceContext *Renderer::InitialiseContext(bool fromPresent) +{ + ID3D11DeviceContext *deviceContext = NULL; + + if (fromPresent) + m_pDevice->GetImmediateContext(&deviceContext); + else + m_pDevice->CreateDeferredContext(0, &deviceContext); + + Renderer::Context *c = new Renderer::Context(m_pDevice, deviceContext); + TlsSetValue(Renderer::tlsIdx, c); + + return deviceContext; +} + +bool Renderer::IsHiDef() +{ + return true; +} + +bool Renderer::IsWidescreen() +{ + return true; +} + +void Renderer::Present() +{ + PROFILER_SCOPE("Renderer::Present", "Present", MP_MAGENTA); + + if (m_bShouldScreenGrabNextFrame) + { + PROFILER_SCOPE("Renderer::Present", "ScreenGrab", MP_MAGENTA); + + unsigned char *linearData = new unsigned char[kScreenGrabWidth * kScreenGrabHeight * 4]; + + ID3D11Resource *backBufferResource = NULL; + ID3D11Texture2D *backBuffer = NULL; + ID3D11Texture2D *stagingTexture = NULL; + + renderTargetView->GetResource(&backBufferResource); + backBufferResource->QueryInterface(IID_PPV_ARGS(&backBuffer)); + D3D11_TEXTURE2D_DESC desc = {}; + backBuffer->GetDesc(&desc); + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + m_pDevice->CreateTexture2D(&desc, NULL, &stagingTexture); + backBufferResource->Release(); + + if (stagingTexture) + { + PROFILER_SCOPE("Renderer::Present", "CopyResource", MP_MAGENTA); + m_pDeviceContext->CopyResource(stagingTexture, backBuffer); + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ_WRITE, 0, &mapped); + const unsigned char* src = reinterpret_cast(mapped.pData); + + for (UINT y = 0; y < kScreenGrabHeight; ++y) + { + unsigned char *dstRow = linearData + y * kScreenGrabWidth * 4; + const unsigned char *srcRow = src + y * mapped.RowPitch; + std::memcpy(dstRow, srcRow, kScreenGrabWidth * 4); + + for (UINT x = 0; x < kScreenGrabWidth; ++x) + dstRow[x * 4 + 3] = 0xFF; + } + + m_pDeviceContext->Unmap(stagingTexture, 0); + } + + static int count = 0; + char fileName[304]; + sprintf(fileName, "d:\\screen%d.png", count++); + + D3DXIMAGE_INFO info; + info.Width = kScreenGrabWidth; + info.Height = kScreenGrabHeight; + SaveTextureData(fileName, &info, reinterpret_cast(linearData)); + + delete[] linearData; + + m_bShouldScreenGrabNextFrame = false; + } + + m_pSwapChain->Present(1, 0); + ++presentCount; +} + +void Renderer::Resume() +{ + m_bSuspended = false; +} + +void Renderer::SetClearColour(const float colourRGBA[4]) +{ + for (int i = 0; i < 4; ++i) + m_fClearColor[i] = colourRGBA[i]; + + Renderer::Context *c = reinterpret_cast(TlsGetValue(Renderer::tlsIdx)); + if (c) + { + D3D11_MAPPED_SUBRESOURCE mapped = {}; + c->m_pDeviceContext->Map(c->m_clearColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + *(DirectX::XMVECTOR *)mapped.pData = DirectX::XMVectorSet(colourRGBA[0], colourRGBA[1], colourRGBA[2], colourRGBA[3]); + c->m_pDeviceContext->Unmap(c->m_clearColorBuffer, 0); + } +} + +void Renderer::SetupShaders() +{ + vertexShaderTable = new ID3D11VertexShader *[C4JRender::VERTEX_TYPE_COUNT]; + vertexStrideTable = new unsigned int[C4JRender::VERTEX_TYPE_COUNT]; + for (UINT i = 0; i < C4JRender::VERTEX_TYPE_COUNT; ++i) + vertexStrideTable[i] = g_vertexStrides[i]; + inputLayoutTable = new ID3D11InputLayout *[C4JRender::VERTEX_TYPE_COUNT]; + pixelShaderTable = new ID3D11PixelShader *[C4JRender::PIXEL_SHADER_COUNT]; + + m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]); + m_pDevice->CreateVertexShader(g_main_VS_Compressed, sizeof(g_main_VS_Compressed), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_COMPRESSED]); + m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]); + m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]); + m_pDevice->CreateVertexShader(g_main_VS_ScreenSpace, sizeof(g_main_VS_ScreenSpace), NULL, &screenSpaceVertexShader); + m_pDevice->CreateVertexShader(g_main_VS_ScreenClear, sizeof(g_main_VS_ScreenClear), NULL, &screenClearVertexShader); + + m_pDevice->CreatePixelShader(g_main_PS_Standard, sizeof(g_main_PS_Standard), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_STANDARD]); + m_pDevice->CreatePixelShader(g_main_PS_TextureProjection, sizeof(g_main_PS_TextureProjection), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_PROJECTION]); + m_pDevice->CreatePixelShader(g_main_PS_ForceLOD, sizeof(g_main_PS_ForceLOD), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_FORCELOD]); + m_pDevice->CreatePixelShader(g_main_PS_ScreenSpace, sizeof(g_main_PS_ScreenSpace), NULL, &screenSpacePixelShader); + m_pDevice->CreatePixelShader(g_main_PS_ScreenClear, sizeof(g_main_PS_ScreenClear), NULL, &screenClearPixelShader); + + m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]); + m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_Compressed, 2, g_main_VS_Compressed, sizeof(g_main_VS_Compressed), &inputLayoutTable[C4JRender::VERTEX_TYPE_COMPRESSED]); + m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]); + m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]); +} + +void Renderer::StartFrame() +{ + PROFILER_SCOPE("Renderer::StartFrame", "StartFrame", MP_MAGENTA); + + Renderer::Context &c = getContext(); + + activeVertexType = -1; + activePixelType = -1; + + TextureBindVertex(-1); + TextureBind(-1); + + PROFILER_SCOPE("Renderer::StartFrame", "State", MP_MAGENTA); + + StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); + StateSetDepthMask(true); + StateSetBlendEnable(true); + StateSetBlendFunc(D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA); + StateSetBlendFactor(0xFFFFFFFF); + StateSetAlphaFunc(D3D11_COMPARISON_GREATER, 0.1f); + StateSetDepthFunc(D3D11_COMPARISON_LESS_EQUAL); + StateSetFaceCull(true); + StateSetLineWidth(1.0f); + StateSetWriteEnable(true, true, true, true); + StateSetDepthTestEnable(false); + StateSetAlphaTestEnable(true); + + c.m_pDeviceContext->VSSetConstantBuffers(0, 10, &c.m_modelViewMatrix); + c.m_pDeviceContext->PSSetConstantBuffers(0, 6, &c.m_tintColorBuffer); + + D3D11_VIEWPORT viewport = {}; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + viewport.Width = static_cast(backBufferWidth); + viewport.Height = static_cast(backBufferHeight); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + c.m_pDeviceContext->RSSetViewports(1, &viewport); + c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView); + + PROFILER_FLIP(); +} + +void Renderer::Suspend() +{ + m_bSuspended = true; +} + +bool Renderer::Suspended() +{ + return m_bSuspended; +} + +void Renderer::UpdateGamma(unsigned short) {} + +Renderer::Context &Renderer::getContext() +{ + return *reinterpret_cast(TlsGetValue(Renderer::tlsIdx)); +} + diff --git a/Windows_Libs/Dev/Render/RendererMatrix.cpp b/Windows_Libs/Dev/Render/RendererMatrix.cpp index ff4ab78..667edaa 100644 --- a/Windows_Libs/Dev/Render/RendererMatrix.cpp +++ b/Windows_Libs/Dev/Render/RendererMatrix.cpp @@ -31,7 +31,8 @@ const float *Renderer::MatrixGet(int type) { Context &c = getContext(); const int depth = c.stackPos[type]; - return reinterpret_cast(&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); } diff --git a/Windows_Libs/Dev/Render/RendererState.cpp b/Windows_Libs/Dev/Render/RendererState.cpp index fe14813..9af73e4 100644 --- a/Windows_Libs/Dev/Render/RendererState.cpp +++ b/Windows_Libs/Dev/Render/RendererState.cpp @@ -28,9 +28,10 @@ SOFTWARE. #include #include + 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(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(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(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(3); + desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; desc.MipLODBias = 0.0f; desc.MaxAnisotropy = 16; - desc.ComparisonFunc = static_cast(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((colour >> 0) & 0xFF) / scale; + c.blendFactor[1] = static_cast((colour >> 8) & 0xFF) / scale; + c.blendFactor[2] = static_cast((colour >> 16) & 0xFF) / scale; + c.blendFactor[3] = static_cast((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(src); + c.blendDesc.RenderTarget[0].DestBlend = static_cast(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(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(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(src); - c.blendDesc.RenderTarget[0].DestBlend = static_cast(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((colour >> 0) & 0xFF) / scale; - c.blendFactor[1] = static_cast((colour >> 8) & 0xFF) / scale; - c.blendFactor[2] = static_cast((colour >> 16) & 0xFF) / scale; - c.blendFactor[3] = static_cast((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(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(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(&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(&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(&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(&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() {} \ No newline at end of file diff --git a/Windows_Libs/Dev/Render/RendererTexture.cpp b/Windows_Libs/Dev/Render/RendererTexture.cpp index f14b6a4..295670b 100644 --- a/Windows_Libs/Dev/Render/RendererTexture.cpp +++ b/Windows_Libs/Dev/Render/RendererTexture.cpp @@ -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(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(dataEnd - dataCurr); - if (static_cast(length) < bytesToWrite) - bytesToWrite = static_cast(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(width * 4), - static_cast(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(width * 4), - static_cast(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(dataEnd - dataCurr); + if (static_cast(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(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(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; } \ No newline at end of file diff --git a/Windows_Libs/Dev/Render/RendererVertex.cpp b/Windows_Libs/Dev/Render/RendererVertex.cpp index b70761a..84b4928 100644 --- a/Windows_Libs/Dev/Render/RendererVertex.cpp +++ b/Windows_Libs/Dev/Render/RendererVertex.cpp @@ -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];