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, 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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
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[0]);
|
||||
|
||||
desc.CullMode = D3D11_CULL_BACK;
|
||||
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) {
|
||||
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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user