mirror of
https://github.com/NoelFB/blah.git
synced 2024-11-28 16:58:57 +08:00
fixing d3d11 depth buffers, adding depth buffer clear support
This commit is contained in:
parent
a72cd5cab6
commit
2de541fb18
|
@ -14,6 +14,15 @@ namespace Blah
|
|||
class FrameBuffer;
|
||||
typedef std::shared_ptr<FrameBuffer> FrameBufferRef;
|
||||
|
||||
enum class ClearMask
|
||||
{
|
||||
None = 0,
|
||||
Color = 1,
|
||||
Depth = 2,
|
||||
Stencil = 4,
|
||||
All = (int)Color | (int)Depth | (int)Stencil
|
||||
};
|
||||
|
||||
class FrameBuffer
|
||||
{
|
||||
protected:
|
||||
|
@ -56,7 +65,7 @@ namespace Blah
|
|||
virtual int height() const = 0;
|
||||
|
||||
// Clears the FrameBuffer
|
||||
virtual void clear(Color color) = 0;
|
||||
virtual void clear(Color color = Color::black, float depth = 1.0f, uint8_t stencil = 0, ClearMask mask = ClearMask::All) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ namespace Blah
|
|||
|
||||
float cos(float x);
|
||||
|
||||
float tan(float x);
|
||||
|
||||
float atan2(float y, float x);
|
||||
|
||||
float pow(float x, float n);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "vec3.h"
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
|
@ -36,8 +37,11 @@ namespace Blah
|
|||
|
||||
static Mat4x4 create_ortho(float width, float height, float z_near_plane, float z_far_plane);
|
||||
static Mat4x4 create_ortho_offcenter(float left, float right, float bottom, float top, float z_near_plane, float z_far_plane);
|
||||
static Mat4x4 create_perspective(float field_of_view, float ratio, float z_near_plane, float z_far_plane);
|
||||
static Mat4x4 create_translation(float x, float y, float z);
|
||||
static Mat4x4 create_scale(float x, float y, float z);
|
||||
static Mat4x4 create_lookat(Vec3 position, Vec3 target, Vec3 up);
|
||||
|
||||
|
||||
Mat4x4 operator* (const Mat4x4& rhs);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "calc.h"
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
|
@ -19,5 +20,37 @@ namespace Blah
|
|||
, y(y)
|
||||
, z(z)
|
||||
{}
|
||||
|
||||
inline Vec3 operator +(const Vec3 rhs) const
|
||||
{
|
||||
return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
|
||||
}
|
||||
|
||||
inline Vec3 operator -(const Vec3 rhs) const
|
||||
{
|
||||
return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
|
||||
}
|
||||
|
||||
inline Vec3 normal() const
|
||||
{
|
||||
float ls = x * x + y * y + z * z;
|
||||
float length = (float)Calc::sqrt(ls);
|
||||
return Vec3(x / length, y / length, z / length);
|
||||
}
|
||||
|
||||
static inline float dot(Vec3 a, Vec3 b)
|
||||
{
|
||||
return a.x * b.x +
|
||||
a.y * b.y +
|
||||
a.z * b.z;
|
||||
}
|
||||
|
||||
static inline Vec3 cross(Vec3 a, Vec3 b)
|
||||
{
|
||||
return Vec3(
|
||||
a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -300,9 +300,9 @@ namespace
|
|||
return App::draw_height();
|
||||
}
|
||||
|
||||
virtual void clear(Color color) override
|
||||
virtual void clear(Color color, float depth, uint8_t stencil, ClearMask mask) override
|
||||
{
|
||||
GraphicsBackend::clear_backbuffer(color);
|
||||
GraphicsBackend::clear_backbuffer(color, depth, stencil, mask);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace Blah
|
|||
void render(const RenderPass& pass);
|
||||
|
||||
// Clears the backbuffer
|
||||
void clear_backbuffer(Color color);
|
||||
void clear_backbuffer(Color color, float depth, uint8_t stencil, ClearMask mask);
|
||||
|
||||
// Creates a new Texture.
|
||||
// if the Texture is invalid, this should return an empty reference.
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace Blah
|
|||
ID3D11Device* device = nullptr;
|
||||
ID3D11DeviceContext* context = nullptr;
|
||||
IDXGISwapChain* swap_chain = nullptr;
|
||||
ID3D11RenderTargetView* backbuffer = nullptr;
|
||||
ID3D11RenderTargetView* backbuffer_view = nullptr;
|
||||
ID3D11DepthStencilView* backbuffer_depth_view = nullptr;
|
||||
|
||||
// supported renderer features
|
||||
RendererFeatures features;
|
||||
|
@ -120,12 +121,10 @@ namespace Blah
|
|||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
if (is_framebuffer)
|
||||
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
bool is_depth_stencil = false;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
|
@ -144,9 +143,18 @@ namespace Blah
|
|||
case TextureFormat::DepthStencil:
|
||||
desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
m_size = width * height * 4;
|
||||
is_depth_stencil = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_depth_stencil)
|
||||
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
||||
else
|
||||
desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
|
||||
|
||||
if (is_framebuffer && !is_depth_stencil)
|
||||
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
|
||||
m_dxgi_format = desc.Format;
|
||||
|
||||
auto hr = state.device->CreateTexture2D(&desc, NULL, &texture);
|
||||
|
@ -158,6 +166,8 @@ namespace Blah
|
|||
return;
|
||||
}
|
||||
|
||||
if (!is_depth_stencil)
|
||||
{
|
||||
hr = state.device->CreateShaderResourceView(texture, NULL, &view);
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
|
@ -165,6 +175,7 @@ namespace Blah
|
|||
texture = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~D3D11_Texture()
|
||||
{
|
||||
|
@ -347,13 +358,28 @@ namespace Blah
|
|||
return m_attachments[0]->height();
|
||||
}
|
||||
|
||||
virtual void clear(Color color) override
|
||||
virtual void clear(Color color, float depth, uint8_t stencil, ClearMask mask) override
|
||||
{
|
||||
float col[4] = { color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f };
|
||||
|
||||
for (int i = 0; i < m_attachments.size(); i++)
|
||||
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
|
||||
{
|
||||
for (int i = 0; i < m_attachments.size() - 1; i++)
|
||||
state.context->ClearRenderTargetView(color_views[i], col);
|
||||
}
|
||||
|
||||
if (depth_view)
|
||||
{
|
||||
UINT flags = 0;
|
||||
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
|
||||
flags |= D3D11_CLEAR_DEPTH;
|
||||
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
|
||||
flags |= D3D11_CLEAR_STENCIL;
|
||||
|
||||
if (flags != 0)
|
||||
state.context->ClearDepthStencilView(depth_view, flags, depth, stencil);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class D3D11_Shader : public Shader
|
||||
|
@ -722,10 +748,13 @@ namespace Blah
|
|||
state.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer);
|
||||
if (frame_buffer)
|
||||
{
|
||||
state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer);
|
||||
state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer_view);
|
||||
frame_buffer->Release();
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// create a depth backbuffer
|
||||
|
||||
// Store Features
|
||||
state.features.instancing = true;
|
||||
state.features.max_texture_size = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
|
@ -802,8 +831,8 @@ namespace Blah
|
|||
if (state.last_size != next_size)
|
||||
{
|
||||
// release old buffer
|
||||
if (state.backbuffer)
|
||||
state.backbuffer->Release();
|
||||
if (state.backbuffer_view)
|
||||
state.backbuffer_view->Release();
|
||||
|
||||
// perform resize
|
||||
hr = state.swap_chain->ResizeBuffers(0, next_size.x, next_size.y, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
|
||||
|
@ -815,7 +844,7 @@ namespace Blah
|
|||
hr = state.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer);
|
||||
if (SUCCEEDED(hr) && frame_buffer)
|
||||
{
|
||||
hr = state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer);
|
||||
hr = state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer_view);
|
||||
BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize");
|
||||
frame_buffer->Release();
|
||||
}
|
||||
|
@ -870,7 +899,7 @@ namespace Blah
|
|||
// Set the Target
|
||||
if (pass.target == App::backbuffer || !pass.target)
|
||||
{
|
||||
ctx->OMSetRenderTargets(1, &state.backbuffer, nullptr);
|
||||
ctx->OMSetRenderTargets(1, &state.backbuffer_view, state.backbuffer_depth_view);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1036,10 +1065,25 @@ namespace Blah
|
|||
}
|
||||
}
|
||||
|
||||
void GraphicsBackend::clear_backbuffer(Color color)
|
||||
void GraphicsBackend::clear_backbuffer(Color color, float depth, uint8_t stencil, ClearMask mask)
|
||||
{
|
||||
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
|
||||
{
|
||||
float clear[4] = { color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f };
|
||||
state.context->ClearRenderTargetView(state.backbuffer, clear);
|
||||
state.context->ClearRenderTargetView(state.backbuffer_view, clear);
|
||||
}
|
||||
|
||||
if (state.backbuffer_depth_view)
|
||||
{
|
||||
UINT flags = 0;
|
||||
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
|
||||
flags |= D3D11_CLEAR_DEPTH;
|
||||
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
|
||||
flags |= D3D11_CLEAR_STENCIL;
|
||||
|
||||
if (flags != 0)
|
||||
state.context->ClearDepthStencilView(state.backbuffer_depth_view, flags, depth, stencil);
|
||||
}
|
||||
}
|
||||
|
||||
// Utility Methods
|
||||
|
|
|
@ -749,13 +749,24 @@ namespace Blah
|
|||
return m_height;
|
||||
}
|
||||
|
||||
virtual void clear(Color color) override
|
||||
virtual void clear(Color color, float depth, uint8_t stencil, ClearMask mask) override
|
||||
{
|
||||
int clear = 0;
|
||||
|
||||
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
|
||||
clear |= GL_COLOR_BUFFER_BIT;
|
||||
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
|
||||
clear |= GL_DEPTH_BUFFER_BIT;
|
||||
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
|
||||
clear |= GL_STENCIL_BUFFER_BIT;
|
||||
|
||||
gl.BindFramebuffer(GL_FRAMEBUFFER, m_id);
|
||||
gl.Disable(GL_SCISSOR_TEST);
|
||||
gl.ColorMask(true, true, true, true);
|
||||
gl.ClearColor(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
|
||||
gl.Clear(GL_COLOR_BUFFER_BIT);
|
||||
gl.ClearDepth(depth);
|
||||
gl.ClearStencil(stencil);
|
||||
gl.Clear(clear);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1485,13 +1496,24 @@ namespace Blah
|
|||
}
|
||||
}
|
||||
|
||||
void GraphicsBackend::clear_backbuffer(Color color)
|
||||
void GraphicsBackend::clear_backbuffer(Color color, float depth, uint8_t stencil, ClearMask mask)
|
||||
{
|
||||
int clear = 0;
|
||||
|
||||
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
|
||||
clear |= GL_COLOR_BUFFER_BIT;
|
||||
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
|
||||
clear |= GL_DEPTH_BUFFER_BIT;
|
||||
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
|
||||
clear |= GL_STENCIL_BUFFER_BIT;
|
||||
|
||||
gl.BindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
gl.Disable(GL_SCISSOR_TEST);
|
||||
gl.ColorMask(true, true, true, true);
|
||||
gl.ClearColor(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
|
||||
gl.Clear(GL_COLOR_BUFFER_BIT);
|
||||
gl.ClearDepth(depth);
|
||||
gl.ClearStencil(stencil);
|
||||
gl.Clear(clear);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,11 @@ float Calc::cos(float x)
|
|||
return cosf(x);
|
||||
}
|
||||
|
||||
float Calc::tan(float x)
|
||||
{
|
||||
return tanf(x);
|
||||
}
|
||||
|
||||
float Calc::atan2(float y, float x)
|
||||
{
|
||||
return atan2f(y, x);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <blah/math/mat4x4.h>
|
||||
#include <blah/core/log.h>
|
||||
|
||||
using namespace Blah;
|
||||
|
||||
|
@ -59,6 +60,29 @@ Mat4x4 Mat4x4::create_ortho_offcenter(float left, float right, float bottom, flo
|
|||
return result;
|
||||
}
|
||||
|
||||
Mat4x4 Mat4x4::create_perspective(float field_of_view, float ratio, float z_near_plane, float z_far_plane)
|
||||
{
|
||||
float yScale = 1.0f / (float)Calc::tan(field_of_view * 0.5f);
|
||||
float xScale = yScale / ratio;
|
||||
|
||||
Mat4x4 result;
|
||||
|
||||
result.m11 = xScale;
|
||||
result.m12 = result.m13 = result.m14 = 0.0f;
|
||||
|
||||
result.m22 = yScale;
|
||||
result.m21 = result.m23 = result.m24 = 0.0f;
|
||||
|
||||
result.m31 = result.m32 = 0.0f;
|
||||
result.m33 = z_far_plane / (z_near_plane - z_far_plane);
|
||||
result.m34 = -1.0f;
|
||||
|
||||
result.m41 = result.m42 = result.m44 = 0.0f;
|
||||
result.m43 = z_near_plane * z_far_plane / (z_near_plane - z_far_plane);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4x4 Mat4x4::create_translation(float x, float y, float z)
|
||||
{
|
||||
Mat4x4 result = identity;
|
||||
|
@ -81,6 +105,34 @@ Mat4x4 Mat4x4::create_scale(float x, float y, float z)
|
|||
return result;
|
||||
}
|
||||
|
||||
Mat4x4 Mat4x4::create_lookat(Vec3 position, Vec3 target, Vec3 up)
|
||||
{
|
||||
Vec3 zaxis = (position - target).normal();
|
||||
Vec3 xaxis = Vec3::cross(up, zaxis).normal();
|
||||
Vec3 yaxis = Vec3::cross(zaxis, xaxis);
|
||||
|
||||
Mat4x4 result;
|
||||
|
||||
result.m11 = xaxis.x;
|
||||
result.m12 = yaxis.x;
|
||||
result.m13 = zaxis.x;
|
||||
result.m14 = 0.0f;
|
||||
result.m21 = xaxis.y;
|
||||
result.m22 = yaxis.y;
|
||||
result.m23 = zaxis.y;
|
||||
result.m24 = 0.0f;
|
||||
result.m31 = xaxis.z;
|
||||
result.m32 = yaxis.z;
|
||||
result.m33 = zaxis.z;
|
||||
result.m34 = 0.0f;
|
||||
result.m41 = -Vec3::dot(xaxis, position);
|
||||
result.m42 = -Vec3::dot(yaxis, position);
|
||||
result.m43 = -Vec3::dot(zaxis, position);
|
||||
result.m44 = 1.0f;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4x4 Mat4x4::operator*(const Mat4x4& rhs)
|
||||
{
|
||||
Mat4x4 m;
|
||||
|
|
Loading…
Reference in New Issue
Block a user