Implement scissoring for Direct3D9/11/OpenGL too

This commit is contained in:
UnknownShadow200 2024-06-21 21:08:57 +10:00
parent 7485956415
commit 402bdb1b57
7 changed files with 73 additions and 35 deletions

View File

@ -33,6 +33,7 @@ GL_FUNC(void, glVertexPointer)(GLint size, GLenum type, GLsizei stride, GLpointe
GL_FUNC(void, glClear)(GLuint mask);
GL_FUNC(void, glHint)(GLenum target, GLenum mode);
GL_FUNC(void, glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
GL_FUNC(void, glScissor)(GLint x, GLint y, GLsizei width, GLsizei height);
/* Texture functions */
GL_FUNC(void, glBindTexture)(GLenum target, GLuint texture);

View File

@ -63,6 +63,8 @@ typedef cc_uintptr GLpointer;
#define GL_MATRIX_MODE 0x0BA0
#define GL_VIEWPORT 0x0BA2
#define GL_ALPHA_TEST 0x0BC0
#define GL_SCISSOR_TEST 0x0C11
#define GL_MAX_TEXTURE_SIZE 0x0D33
#define GL_DEPTH_BITS 0x0D56

View File

@ -630,22 +630,35 @@ void Gfx_DisableTextureOffset(void) {
//---------------------------------------------------------Rasteriser-----------------------------------------------------
//########################################################################################################################
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage
static ID3D11RasterizerState* rs_states[2];
static cc_bool rs_culling;
static ID3D11RasterizerState* rs_states[4];
static cc_bool rs_culling, rs_scissor;
static void RS_CreateRasterState(void) {
// https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_rasterizer_desc
D3D11_RASTERIZER_DESC desc = { 0 };
desc.CullMode = D3D11_CULL_NONE;
desc.FillMode = D3D11_FILL_SOLID;
desc.FrontCounterClockwise = true;
desc.DepthClipEnable = true; // otherwise vertices/pixels beyond far plane are still wrongly rendered
ID3D11Device_CreateRasterizerState(device, &desc, &rs_states[0]);
desc.CullMode = D3D11_CULL_BACK;
ID3D11Device_CreateRasterizerState(device, &desc, &rs_states[1]);
for (int i = 0; i < Array_Elems(rs_states); i++)
{
desc.CullMode = (i & 1) ? D3D11_CULL_BACK : D3D11_CULL_NONE;
desc.ScissorEnable = (i & 2) != 0;
desc.FillMode = D3D11_FILL_SOLID;
desc.FrontCounterClockwise = true;
desc.DepthClipEnable = true; // otherwise vertices/pixels beyond far plane are still wrongly rendered
ID3D11Device_CreateRasterizerState(device, &desc, &rs_states[i]);
}
}
static void RS_UpdateRasterState(void) {
ID3D11DeviceContext_RSSetState(context, rs_states[rs_culling | (rs_scissor << 1)]);
}
static void RS_FreeRasterStates(void) {
for (int i = 0; i < Array_Elems(rs_states); i++)
{
ID3D11RasterizerState_Release(rs_states[i]);
}
}
void Gfx_SetViewport(int x, int y, int w, int h) {
D3D11_VIEWPORT viewport;
viewport.TopLeftX = x;
@ -657,15 +670,16 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
ID3D11DeviceContext_RSSetViewports(context, 1, &viewport);
}
static void RS_UpdateRasterState(void) {
ID3D11DeviceContext_RSSetState(context, rs_states[rs_culling]);
}
void Gfx_SetScissor(int x, int y, int w, int h) {
rs_scissor = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
static void RS_FreeRasterStates(void) {
for (int i = 0; i < Array_Elems(rs_states); i++)
{
ID3D11RasterizerState_Release(rs_states[i]);
}
D3D11_RECT rect;
rect.left = x;
rect.top = y;
rect.right = x + w;
rect.bottom = y + h;
ID3D11DeviceContext_RSSetScissorRects(context, 1, &rect);
RS_UpdateRasterState();
}
static void RS_Init(void) {

View File

@ -891,4 +891,16 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
vp.MaxZ = 1.0f;
IDirect3DDevice9_SetViewport(device, &vp);
}
void Gfx_SetScissor(int x, int y, int w, int h) {
cc_bool enabled = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
RECT rect;
rect.left = x;
rect.top = y;
rect.right = x + w;
rect.bottom = y + h;
IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, enabled);
IDirect3DDevice9_SetScissorRect(device, &rect);
}
#endif

View File

@ -624,15 +624,6 @@ extern float VP_COL_X_PLUS_HWIDTH, VP_TEX_X_PLUS_HWIDTH;
extern float VP_COL_Y_PLUS_HHEIGHT, VP_TEX_Y_PLUS_HHEIGHT;
void Gfx_SetViewport(int x, int y, int w, int h) {
if (x == 0 && y == 0 && w == Game.Width && h == Game.Height) {
SCISSOR_TEST_ENABLED = GL_FALSE;
} else {
SCISSOR_TEST_ENABLED = GL_TRUE;
}
STATE_DIRTY = GL_TRUE;
glScissor (x, y, w, h);
VIEWPORT.hwidth = w * 0.5f;
VIEWPORT.hheight = h * -0.5f;
VIEWPORT.x_plus_hwidth = x + w * 0.5f;
@ -644,4 +635,10 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
VP_COL_X_PLUS_HWIDTH = VP_TEX_X_PLUS_HWIDTH = x + w * 0.5f;
VP_COL_Y_PLUS_HHEIGHT = VP_TEX_Y_PLUS_HHEIGHT = y + h * 0.5f;
}
void Gfx_SetScissor(int x, int y, int w, int h) {
SCISSOR_TEST_ENABLED = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
STATE_DIRTY = GL_TRUE;
glScissor(x, y, w, h);
}
#endif

View File

@ -932,22 +932,27 @@ void Gfx_OnWindowResize(void) {
fb_width = Game.Width;
fb_height = Game.Height;
vp_hwidth = fb_width / 2.0f;
vp_hheight = fb_height / 2.0f;
fb_maxX = fb_width - 1;
fb_maxY = fb_height - 1;
Window_AllocFramebuffer(&fb_bmp, Game.Width, Game.Height);
colorBuffer = fb_bmp.scan0;
cb_stride = fb_bmp.width;
depthBuffer = Mem_Alloc(fb_width * fb_height, 4, "depth buffer");
db_stride = fb_width;
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
Gfx_SetScissor (0, 0, Game.Width, Game.Height);
}
void Gfx_SetViewport(int x, int y, int w, int h) { }
void Gfx_SetScissor (int x, int y, int w, int h) { }
void Gfx_SetViewport(int x, int y, int w, int h) {
vp_hwidth = w / 2.0f;
vp_hheight = h / 2.0f;
}
void Gfx_SetScissor (int x, int y, int w, int h) {
/* TODO minX/Y */
fb_maxX = x + w - 1;
fb_maxY = y + h - 1;
}
void Gfx_GetApiInfo(cc_string* info) {
int pointerSize = sizeof(void*) * 8;

View File

@ -336,3 +336,10 @@ void Gfx_OnWindowResize(void) {
void Gfx_SetViewport(int x, int y, int w, int h) {
glViewport(x, y, w, h);
}
void Gfx_SetScissor(int x, int y, int w, int h) {
cc_bool enabled = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
if (enabled) { glEnable(GL_SCISSOR_TEST); } else { glDisable(GL_SCISSOR_TEST); }
glScissor(x, Game.Height - h - y, w, h);
}