Optimise selection box rendering.

This commit is contained in:
UnknownShadow200 2018-03-13 08:24:15 +11:00
parent 12e274af77
commit 0eec5dc504
5 changed files with 33 additions and 27 deletions

View file

@ -9,21 +9,21 @@ namespace ClassicalSharp.Selections {
internal class SelectionBox { internal class SelectionBox {
public byte ID; public byte ID;
public Vector3I Min, Max; public Vector3 Min, Max;
public FastColour Colour; public FastColour Colour;
public float MinDist, MaxDist; public float MinDist, MaxDist;
public SelectionBox(Vector3I p1, Vector3I p2, FastColour col) { public SelectionBox(Vector3I p1, Vector3I p2, FastColour col) {
Min = Vector3I.Min(p1, p2); Min = (Vector3)Vector3I.Min(p1, p2);
Max = Vector3I.Max(p1, p2); Max = (Vector3)Vector3I.Max(p1, p2);
Colour = col; Colour = col;
} }
public void Render(double delta, VertexP3fC4b[] vertices, VertexP3fC4b[] lineVertices, public void Render(double delta, VertexP3fC4b[] vertices, VertexP3fC4b[] lineVertices,
ref int index, ref int lineIndex) { ref int index, ref int lineIndex) {
float offset = MinDist < 32 * 32 ? 1/32f : 1/16f; float offset = MinDist < 32 * 32 ? 1/32f : 1/16f;
Vector3 p1 = (Vector3)Min - new Vector3(offset, offset, offset); Vector3 offsetV = new Vector3(offset, offset, offset);
Vector3 p2 = (Vector3)Max + new Vector3(offset, offset, offset); Vector3 p1 = Min - offsetV, p2 = Max + offsetV;
int col = Colour.Pack(); int col = Colour.Pack();
HorQuad(vertices, ref index, col, p1.X, p1.Z, p2.X, p2.Z, p1.Y); // bottom HorQuad(vertices, ref index, col, p1.X, p1.Z, p2.X, p2.Z, p1.Y); // bottom
@ -80,14 +80,21 @@ namespace ClassicalSharp.Selections {
internal class SelectionBoxComparer : IComparer<SelectionBox> { internal class SelectionBoxComparer : IComparer<SelectionBox> {
public int Compare(SelectionBox a, SelectionBox b) { public int Compare(SelectionBox a, SelectionBox b) {
// Reversed comparison order because we need to render back to front for alpha blending. float aDist, bDist;
return a.MinDist == b.MinDist if (a.MinDist == b.MinDist) {
? b.MaxDist.CompareTo(a.MaxDist) aDist = a.MaxDist; bDist = b.MaxDist;
: b.MinDist.CompareTo(a.MinDist); } else {
aDist = a.MinDist; bDist = b.MinDist;
}
// Reversed comparison order result, because we need to render back to front for alpha blending
if (aDist < bDist) return 1;
if (aDist > bDist) return -1;
return 0;
} }
internal void Intersect(SelectionBox box, Vector3 origin) { internal void Intersect(SelectionBox box, Vector3 origin) {
Vector3I min = box.Min, max = box.Max; Vector3 min = box.Min, max = box.Max;
float closest = float.PositiveInfinity, furthest = float.NegativeInfinity; float closest = float.PositiveInfinity, furthest = float.NegativeInfinity;
// Bottom corners // Bottom corners
UpdateDist(origin, min.X, min.Y, min.Z, ref closest, ref furthest); UpdateDist(origin, min.X, min.Y, min.Z, ref closest, ref furthest);

View file

@ -67,12 +67,12 @@ namespace ClassicalSharp.Selections {
IGraphicsApi gfx = game.Graphics; IGraphicsApi gfx = game.Graphics;
gfx.SetBatchFormat(VertexFormat.P3fC4b); gfx.SetBatchFormat(VertexFormat.P3fC4b);
gfx.UpdateDynamicVb_Lines(lineVb, lineVertices, gfx.UpdateDynamicVb_Lines(lineVb, lineVertices,
selections.Count * LineVerticesCount); selections.Count * LineVerticesCount);
gfx.DepthWrite = false; gfx.DepthWrite = false;
gfx.AlphaBlending = true; gfx.AlphaBlending = true;
gfx.UpdateDynamicVb_IndexedTris(vb, vertices, gfx.UpdateDynamicVb_IndexedTris(vb, vertices,
selections.Count * VerticesCount); selections.Count * VerticesCount);
gfx.DepthWrite = true; gfx.DepthWrite = true;
gfx.AlphaBlending = false; gfx.AlphaBlending = false;
} }

View file

@ -5,6 +5,7 @@
#include "Screens.h" #include "Screens.h"
#include "Block.h" #include "Block.h"
#include "Event.h" #include "Event.h"
#include "HeldBlockRenderer.h"
void GameMode_Init(void) { void GameMode_Init(void) {
BlockID* inv = Inventory_Table; BlockID* inv = Inventory_Table;
@ -39,7 +40,7 @@ bool GameMode_HandlesKeyDown(Key key) {
bool GameMode_PickingLeft(void) { bool GameMode_PickingLeft(void) {
/* always play delete animations, even if we aren't picking a block */ /* always play delete animations, even if we aren't picking a block */
game.HeldBlockRenderer.ClickAnim(true); HeldBlockRenderer_ClickAnim(true);
return false; return false;
} }
bool GameMode_PickingRight(void) { return false; } bool GameMode_PickingRight(void) { return false; }

View file

@ -1048,7 +1048,7 @@ void HUDScreen_Render(GuiElement* elem, Real64 delta) {
if (!screen->ShowingList && !showMinimal) { if (!screen->ShowingList && !showMinimal) {
Gfx_SetTexturing(true); Gfx_SetTexturing(true);
DrawCrosshairs(); HUDScreen_DrawCrosshairs();
Gfx_SetTexturing(false); Gfx_SetTexturing(false);
} }
if (chat->HandlesAllInput && !Game_PureClassic) { if (chat->HandlesAllInput && !Game_PureClassic) {

View file

@ -7,20 +7,17 @@
/* Data for a selection box. */ /* Data for a selection box. */
typedef struct SelectionBox_ { typedef struct SelectionBox_ {
Vector3I Min, Max; Vector3 Min, Max;
PackedCol Col; PackedCol Col;
Real32 MinDist, MaxDist; Real32 MinDist, MaxDist;
} SelectionBox; } SelectionBox;
void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4b** lineVertices) { void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4b** lineVertices) {
Real32 offset = box->MinDist < 32.0f * 32.0f ? (1.0f / 32.0f) : (1.0f / 16.0f); Real32 offset = box->MinDist < 32.0f * 32.0f ? (1.0f / 32.0f) : (1.0f / 16.0f);
Vector3 p1, p2; Vector3 p1 = box->Min, p2 = box->Max;
PackedCol col = box->Col;
Vector3I_ToVector3(&p1, &box->Min);
Vector3I_ToVector3(&p2, &box->Max);
Vector3_Add1(&p1, &p1, -offset); Vector3_Add1(&p1, &p1, -offset);
Vector3_Add1(&p2, &p2, offset); Vector3_Add1(&p2, &p2, offset);
PackedCol col = box->Col;
SelectionBox_HorQuad(vertices, col, p1.X, p1.Z, p2.X, p2.Z, p1.Y); /* bottom */ SelectionBox_HorQuad(vertices, col, p1.X, p1.Z, p2.X, p2.Z, p1.Y); /* bottom */
SelectionBox_HorQuad(vertices, col, p1.X, p1.Z, p2.X, p2.Z, p2.Y); /* top */ SelectionBox_HorQuad(vertices, col, p1.X, p1.Z, p2.X, p2.Z, p2.Y); /* top */
@ -105,7 +102,7 @@ void SelectionBox_UpdateDist(Vector3 p, Real32 x2, Real32 y2, Real32 z2, Real32*
} }
void SelectionBox_Intersect(SelectionBox* box, Vector3 origin) { void SelectionBox_Intersect(SelectionBox* box, Vector3 origin) {
Vector3I min = box->Min, max = box->Max; Vector3 min = box->Min, max = box->Max;
Real32 closest = MATH_POS_INF, furthest = -MATH_POS_INF; Real32 closest = MATH_POS_INF, furthest = -MATH_POS_INF;
/* Bottom corners */ /* Bottom corners */
SelectionBox_UpdateDist(origin, min.X, min.Y, min.Z, &closest, &furthest); SelectionBox_UpdateDist(origin, min.X, min.Y, min.Z, &closest, &furthest);
@ -133,8 +130,9 @@ bool selections_allocated;
void Selections_Add(UInt8 id, Vector3I p1, Vector3I p2, PackedCol col) { void Selections_Add(UInt8 id, Vector3I p1, Vector3I p2, PackedCol col) {
SelectionBox sel; SelectionBox sel;
Vector3I_Min(&sel.Min, &p1, &p2); Vector3I min, max;
Vector3I_Max(&sel.Max, &p1, &p2); Vector3I_Min(&min, &p1, &p2); Vector3I_ToVector3(&sel.Min, &min);
Vector3I_Max(&max, &p1, &p2); Vector3I_ToVector3(&sel.Max, &max);
sel.Col = col; sel.Col = col;
Selections_Remove(id); Selections_Remove(id);
@ -158,12 +156,12 @@ void Selections_Remove(UInt8 id) {
} }
} }
void Selections_ContextLost(void) { void Selections_ContextLost(void* obj) {
Gfx_DeleteVb(&selections_VB); Gfx_DeleteVb(&selections_VB);
Gfx_DeleteVb(&selections_LineVB); Gfx_DeleteVb(&selections_LineVB);
} }
void Selections_ContextRecreated(void) { void Selections_ContextRecreated(void* obj) {
if (!selections_allocated) return; if (!selections_allocated) return;
selections_VB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES); selections_VB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES);
selections_LineVB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES); selections_LineVB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES);
@ -199,7 +197,7 @@ void Selections_Render(Real64 delta) {
Selections_QuickSort(0, selections_count - 1); Selections_QuickSort(0, selections_count - 1);
if (!selections_allocated) { /* lazy init as most servers don't use this */ if (!selections_allocated) { /* lazy init as most servers don't use this */
Selections_ContextRecreated(); Selections_ContextRecreated(NULL);
selections_allocated = true; selections_allocated = true;
} }
@ -231,7 +229,7 @@ void Selections_Reset(void) {
} }
void Selections_Free(void) { void Selections_Free(void) {
Selections_ContextLost(); Selections_ContextLost(NULL);
Event_UnregisterVoid(&GfxEvents_ContextLost, NULL, Selections_ContextLost); Event_UnregisterVoid(&GfxEvents_ContextLost, NULL, Selections_ContextLost);
Event_UnregisterVoid(&GfxEvents_ContextRecreated, NULL, Selections_ContextRecreated); Event_UnregisterVoid(&GfxEvents_ContextRecreated, NULL, Selections_ContextRecreated);
} }