mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 09:35:23 -04:00
Implement scissoring for Direct3D9/11/OpenGL too
This commit is contained in:
parent
7485956415
commit
402bdb1b57
@ -33,6 +33,7 @@ GL_FUNC(void, glVertexPointer)(GLint size, GLenum type, GLsizei stride, GLpointe
|
|||||||
GL_FUNC(void, glClear)(GLuint mask);
|
GL_FUNC(void, glClear)(GLuint mask);
|
||||||
GL_FUNC(void, glHint)(GLenum target, GLenum mode);
|
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, 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 */
|
/* Texture functions */
|
||||||
GL_FUNC(void, glBindTexture)(GLenum target, GLuint texture);
|
GL_FUNC(void, glBindTexture)(GLenum target, GLuint texture);
|
||||||
|
@ -63,6 +63,8 @@ typedef cc_uintptr GLpointer;
|
|||||||
#define GL_MATRIX_MODE 0x0BA0
|
#define GL_MATRIX_MODE 0x0BA0
|
||||||
#define GL_VIEWPORT 0x0BA2
|
#define GL_VIEWPORT 0x0BA2
|
||||||
#define GL_ALPHA_TEST 0x0BC0
|
#define GL_ALPHA_TEST 0x0BC0
|
||||||
|
#define GL_SCISSOR_TEST 0x0C11
|
||||||
|
|
||||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||||
#define GL_DEPTH_BITS 0x0D56
|
#define GL_DEPTH_BITS 0x0D56
|
||||||
|
|
||||||
|
@ -630,22 +630,35 @@ void Gfx_DisableTextureOffset(void) {
|
|||||||
//---------------------------------------------------------Rasteriser-----------------------------------------------------
|
//---------------------------------------------------------Rasteriser-----------------------------------------------------
|
||||||
//########################################################################################################################
|
//########################################################################################################################
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage
|
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage
|
||||||
static ID3D11RasterizerState* rs_states[2];
|
static ID3D11RasterizerState* rs_states[4];
|
||||||
static cc_bool rs_culling;
|
static cc_bool rs_culling, rs_scissor;
|
||||||
|
|
||||||
static void RS_CreateRasterState(void) {
|
static void RS_CreateRasterState(void) {
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_rasterizer_desc
|
// https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_rasterizer_desc
|
||||||
D3D11_RASTERIZER_DESC desc = { 0 };
|
D3D11_RASTERIZER_DESC desc = { 0 };
|
||||||
desc.CullMode = D3D11_CULL_NONE;
|
for (int i = 0; i < Array_Elems(rs_states); i++)
|
||||||
desc.FillMode = D3D11_FILL_SOLID;
|
{
|
||||||
desc.FrontCounterClockwise = true;
|
desc.CullMode = (i & 1) ? D3D11_CULL_BACK : D3D11_CULL_NONE;
|
||||||
desc.DepthClipEnable = true; // otherwise vertices/pixels beyond far plane are still wrongly rendered
|
desc.ScissorEnable = (i & 2) != 0;
|
||||||
ID3D11Device_CreateRasterizerState(device, &desc, &rs_states[0]);
|
desc.FillMode = D3D11_FILL_SOLID;
|
||||||
|
desc.FrontCounterClockwise = true;
|
||||||
desc.CullMode = D3D11_CULL_BACK;
|
desc.DepthClipEnable = true; // otherwise vertices/pixels beyond far plane are still wrongly rendered
|
||||||
ID3D11Device_CreateRasterizerState(device, &desc, &rs_states[1]);
|
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) {
|
void Gfx_SetViewport(int x, int y, int w, int h) {
|
||||||
D3D11_VIEWPORT viewport;
|
D3D11_VIEWPORT viewport;
|
||||||
viewport.TopLeftX = x;
|
viewport.TopLeftX = x;
|
||||||
@ -657,15 +670,16 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
|
|||||||
ID3D11DeviceContext_RSSetViewports(context, 1, &viewport);
|
ID3D11DeviceContext_RSSetViewports(context, 1, &viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RS_UpdateRasterState(void) {
|
void Gfx_SetScissor(int x, int y, int w, int h) {
|
||||||
ID3D11DeviceContext_RSSetState(context, rs_states[rs_culling]);
|
rs_scissor = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
|
||||||
}
|
|
||||||
|
|
||||||
static void RS_FreeRasterStates(void) {
|
D3D11_RECT rect;
|
||||||
for (int i = 0; i < Array_Elems(rs_states); i++)
|
rect.left = x;
|
||||||
{
|
rect.top = y;
|
||||||
ID3D11RasterizerState_Release(rs_states[i]);
|
rect.right = x + w;
|
||||||
}
|
rect.bottom = y + h;
|
||||||
|
ID3D11DeviceContext_RSSetScissorRects(context, 1, &rect);
|
||||||
|
RS_UpdateRasterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RS_Init(void) {
|
static void RS_Init(void) {
|
||||||
|
@ -891,4 +891,16 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
|
|||||||
vp.MaxZ = 1.0f;
|
vp.MaxZ = 1.0f;
|
||||||
IDirect3DDevice9_SetViewport(device, &vp);
|
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
|
#endif
|
||||||
|
@ -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;
|
extern float VP_COL_Y_PLUS_HHEIGHT, VP_TEX_Y_PLUS_HHEIGHT;
|
||||||
|
|
||||||
void Gfx_SetViewport(int x, int y, int w, int h) {
|
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.hwidth = w * 0.5f;
|
||||||
VIEWPORT.hheight = h * -0.5f;
|
VIEWPORT.hheight = h * -0.5f;
|
||||||
VIEWPORT.x_plus_hwidth = x + w * 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_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;
|
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
|
#endif
|
||||||
|
@ -932,22 +932,27 @@ void Gfx_OnWindowResize(void) {
|
|||||||
fb_width = Game.Width;
|
fb_width = Game.Width;
|
||||||
fb_height = Game.Height;
|
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);
|
Window_AllocFramebuffer(&fb_bmp, Game.Width, Game.Height);
|
||||||
colorBuffer = fb_bmp.scan0;
|
colorBuffer = fb_bmp.scan0;
|
||||||
cb_stride = fb_bmp.width;
|
cb_stride = fb_bmp.width;
|
||||||
|
|
||||||
depthBuffer = Mem_Alloc(fb_width * fb_height, 4, "depth buffer");
|
depthBuffer = Mem_Alloc(fb_width * fb_height, 4, "depth buffer");
|
||||||
db_stride = fb_width;
|
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_SetViewport(int x, int y, int w, int h) {
|
||||||
void Gfx_SetScissor (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) {
|
void Gfx_GetApiInfo(cc_string* info) {
|
||||||
int pointerSize = sizeof(void*) * 8;
|
int pointerSize = sizeof(void*) * 8;
|
||||||
|
@ -336,3 +336,10 @@ void Gfx_OnWindowResize(void) {
|
|||||||
void Gfx_SetViewport(int x, int y, int w, int h) {
|
void Gfx_SetViewport(int x, int y, int w, int h) {
|
||||||
glViewport(x, y, w, 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);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user