Rest Of The Tesselator
This commit is contained in:
parent
b2db67b4bf
commit
1001427309
@ -113,3 +113,4 @@ TRUE 3D Dropped Items
|
||||
TRUE Render Entity Shadows
|
||||
TRUE Render Vignette
|
||||
TRUE Increase Render Chunk Size
|
||||
TRUE Proper Entity Shading
|
@ -10,7 +10,7 @@
|
||||
void reborn_init_patch();
|
||||
|
||||
// Replace Call Located At start With A Call To target
|
||||
void overwrite_call(void *start, void *target);
|
||||
void overwrite_call(void *start, void *target, bool force_b_instruction = false);
|
||||
|
||||
// Replace All Calls To Method start With target
|
||||
void *overwrite_calls_manual(void *start, void *target, bool allow_no_callsites = false);
|
||||
|
@ -21,8 +21,8 @@ static void _overwrite_call_internal(void *start, void *target, const bool use_b
|
||||
// Increment Code Block Position
|
||||
increment_code_block();
|
||||
}
|
||||
void overwrite_call(void *start, void *target) {
|
||||
const bool use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION;
|
||||
void overwrite_call(void *start, void *target, const bool force_b_instruction) {
|
||||
const bool use_b_instruction = force_b_instruction || ((unsigned char *) start)[3] == B_INSTRUCTION;
|
||||
_overwrite_call_internal(start, target, use_b_instruction);
|
||||
}
|
||||
|
||||
|
@ -228,3 +228,7 @@ GL_FUNC(glGenBuffers, void, (GLsizei n, GLuint *buffers))
|
||||
void glGenBuffers(const GLsizei n, GLuint *buffers) {
|
||||
real_glGenBuffers()(n, buffers);
|
||||
}
|
||||
GL_FUNC(glNormalPointer, void, (GLenum type, GLsizei stride, const void *pointer))
|
||||
void glNormalPointer(const GLenum type, const GLsizei stride, const void *pointer) {
|
||||
real_glNormalPointer()(type, stride, pointer);
|
||||
}
|
@ -30,6 +30,7 @@ extern "C" {
|
||||
#define GL_VERTEX_ARRAY 0x8074
|
||||
#define GL_COLOR_ARRAY 0x8076
|
||||
#define GL_TEXTURE_COORD_ARRAY 0x8078
|
||||
#define GL_NORMAL_ARRAY 0x8075
|
||||
#define GL_GREATER 0x204
|
||||
#define GL_ALPHA_TEST 0xbc0
|
||||
#define GL_TEXTURE_2D 0xde1
|
||||
@ -47,6 +48,7 @@ extern "C" {
|
||||
#define GL_TRIANGLES 0x4
|
||||
#define GL_TRIANGLE_STRIP 0x5
|
||||
#define GL_TRIANGLE_FAN 0x6
|
||||
#define GL_QUADS 0x7
|
||||
#define GL_FASTEST 0x1101
|
||||
#define GL_BACK 0x405
|
||||
#define GL_CULL_FACE 0xb44
|
||||
@ -158,6 +160,7 @@ GLenum glGetError();
|
||||
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
void glPixelStorei(GLenum pname, GLint param);
|
||||
void glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
|
||||
void glNormalPointer(GLenum type, GLsizei stride, const void *pointer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ struct {
|
||||
gl_array_details_t glVertexPointer;
|
||||
gl_array_details_t glColorPointer;
|
||||
gl_array_details_t glTexCoordPointer;
|
||||
gl_array_details_t glNormalPointer;
|
||||
} gl_array_details;
|
||||
#endif
|
||||
struct gl_state_t {
|
||||
@ -41,6 +42,7 @@ struct gl_state_t {
|
||||
bool vertex_array_enabled = false;
|
||||
bool color_array_enabled = false;
|
||||
bool tex_coord_array_enabled = false;
|
||||
bool normal_array_enabled = false;
|
||||
// Update State
|
||||
bool &get_array_enabled(const GLenum array) {
|
||||
switch (array) {
|
||||
@ -53,6 +55,9 @@ struct gl_state_t {
|
||||
case GL_TEXTURE_COORD_ARRAY: {
|
||||
return tex_coord_array_enabled;
|
||||
}
|
||||
case GL_NORMAL_ARRAY: {
|
||||
return normal_array_enabled;
|
||||
}
|
||||
default: {
|
||||
ERR("Unsupported Array Type: %i", array);
|
||||
}
|
||||
@ -71,6 +76,7 @@ struct gl_state_t {
|
||||
send_array_to_driver(GL_VERTEX_ARRAY);
|
||||
send_array_to_driver(GL_COLOR_ARRAY);
|
||||
send_array_to_driver(GL_TEXTURE_COORD_ARRAY);
|
||||
send_array_to_driver(GL_NORMAL_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, bound_array_buffer);
|
||||
glBindTexture(GL_TEXTURE_2D, bound_texture);
|
||||
}
|
||||
@ -762,3 +768,20 @@ CALL(69, glBufferSubData, void, (GLenum target, GLintptr offset, GLsizeiptr size
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL(72, glNormalPointer, void, (GLenum type, GLsizei stride, const void *pointer))
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
gl_array_details_t &state = gl_array_details.glNormalPointer; \
|
||||
if (state.type != type || state.stride != stride || state.pointer != uint32_t(pointer)) { \
|
||||
state.type = type; \
|
||||
state.stride = stride; \
|
||||
state.pointer = uint32_t(pointer); \
|
||||
trampoline(true, gl_state.bound_array_buffer, state); \
|
||||
}
|
||||
#else
|
||||
glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>());
|
||||
gl_array_details_t state = args.next<gl_array_details_t>();
|
||||
func(state.type, state.stride, (const void *) uintptr_t(state.pointer));
|
||||
return 0;
|
||||
#endif
|
||||
}
|
@ -99,6 +99,9 @@ set(SRC
|
||||
src/multidraw/storage.cpp
|
||||
# classic-ui
|
||||
src/classic-ui/classic-ui.cpp
|
||||
# shading
|
||||
src/shading/init.cpp
|
||||
src/shading/tesselator.cpp
|
||||
)
|
||||
# Install Splashes
|
||||
install(
|
||||
|
@ -31,4 +31,5 @@ void init_screenshot();
|
||||
void init_f3();
|
||||
void init_multidraw();
|
||||
void init_classic_ui();
|
||||
void init_shading();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
extern int multidraw_vertex_size;
|
||||
extern "C" {
|
||||
void LevelRenderer_renderSameAsLast(LevelRenderer *self, float delta);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ __attribute__((constructor)) static void init() {
|
||||
init_multiplayer();
|
||||
if (!reborn_is_headless()) {
|
||||
init_sound();
|
||||
init_shading();
|
||||
}
|
||||
init_input();
|
||||
init_sign();
|
||||
|
@ -50,7 +50,7 @@ HOOK(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLen
|
||||
}
|
||||
|
||||
// Render
|
||||
#define VERTEX_SIZE 24
|
||||
int multidraw_vertex_size = 24;
|
||||
#define MAX_RENDER_CHUNKS 4096
|
||||
static bool supports_multidraw() {
|
||||
static int ret = -1;
|
||||
@ -76,9 +76,9 @@ static void multidraw_renderSameAsLast(const LevelRenderer *self, const float b)
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, storage->buffer->server_side_data);
|
||||
glVertexPointer(3, GL_FLOAT, VERTEX_SIZE, (void *) 0);
|
||||
glTexCoordPointer(2, GL_FLOAT, VERTEX_SIZE, (void *) 0xc);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, VERTEX_SIZE, (void *) 0x14);
|
||||
glVertexPointer(3, GL_FLOAT, multidraw_vertex_size, (void *) 0);
|
||||
glTexCoordPointer(2, GL_FLOAT, multidraw_vertex_size, (void *) 0xc);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, multidraw_vertex_size, (void *) 0x14);
|
||||
|
||||
// Draw
|
||||
if (supports_multidraw()) {
|
||||
@ -110,7 +110,7 @@ static int LevelRenderer_renderChunks_injection(__attribute__((unused)) LevelRen
|
||||
}
|
||||
// Queue
|
||||
const int j = multidraw_total++;
|
||||
multidraw_firsts[j] = block->offset / VERTEX_SIZE;
|
||||
multidraw_firsts[j] = block->offset / multidraw_vertex_size;
|
||||
multidraw_counts[j] = render_chunk->vertices;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#include <mods/init/init.h>
|
||||
#include <mods/feature/feature.h>
|
||||
|
||||
#include "shading-internal.h"
|
||||
|
||||
// Init
|
||||
void init_shading() {
|
||||
if (feature_has("Proper Entity Shading", server_disabled)) {
|
||||
_init_custom_tesselator();
|
||||
}
|
||||
}
|
@ -0,0 +1,202 @@
|
||||
#include <optional>
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/multidraw/multidraw.h>
|
||||
#include "shading-internal.h"
|
||||
|
||||
// Structures
|
||||
struct UV {
|
||||
float u;
|
||||
float v;
|
||||
};
|
||||
struct CustomVertex {
|
||||
Vec3 pos;
|
||||
UV uv;
|
||||
GLuint color;
|
||||
GLuint normal;
|
||||
};
|
||||
struct CustomTesselator {
|
||||
int vertex_count;
|
||||
CustomVertex *vertices;
|
||||
std::optional<uint32_t> normal;
|
||||
int quad_to_triangle_tracker;
|
||||
|
||||
static CustomTesselator instance;
|
||||
};
|
||||
CustomTesselator CustomTesselator::instance;
|
||||
|
||||
static void Tesselator_clear_injection(Tesselator_clear_t original, Tesselator *self) {
|
||||
if (original) {
|
||||
original(self);
|
||||
}
|
||||
CustomTesselator::instance.vertex_count = 0;
|
||||
CustomTesselator::instance.quad_to_triangle_tracker = 0;
|
||||
CustomTesselator::instance.normal.reset();
|
||||
}
|
||||
|
||||
#define MAX_VERTICES 524288
|
||||
static void Tesselator_init_injection(Tesselator_init_t original, Tesselator *self) {
|
||||
original(self);
|
||||
CustomTesselator::instance.vertices = new CustomVertex[MAX_VERTICES];
|
||||
Tesselator_clear_injection(nullptr, nullptr);
|
||||
}
|
||||
|
||||
static void Tesselator_begin_injection(Tesselator_begin_t original, Tesselator *self, const int mode) {
|
||||
original(self, mode);
|
||||
if (!self->void_begin_end) {
|
||||
Tesselator_clear_injection(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint get_next_buffer() {
|
||||
Tesselator::instance.next_buffer_id++;
|
||||
Tesselator::instance.next_buffer_id %= Tesselator::instance.buffer_count;
|
||||
const GLuint out = Tesselator::instance.buffers[Tesselator::instance.next_buffer_id];
|
||||
return out;
|
||||
}
|
||||
|
||||
static RenderChunk Tesselator_end_injection(Tesselator *self, const bool use_given_buffer, const int buffer) {
|
||||
// Check
|
||||
if (!self->active) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
RenderChunk out;
|
||||
out.constructor();
|
||||
if (self->void_begin_end) {
|
||||
return out;
|
||||
}
|
||||
// Render
|
||||
out.vertices = CustomTesselator::instance.vertex_count;
|
||||
if (out.vertices > 0) {
|
||||
out.buffer = use_given_buffer ? buffer : get_next_buffer();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, out.buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, out.vertices * sizeof(CustomVertex), CustomTesselator::instance.vertices, GL_STATIC_DRAW);
|
||||
}
|
||||
// Finish
|
||||
self->clear();
|
||||
self->active = false;
|
||||
return out;
|
||||
}
|
||||
|
||||
static void Tesselator_draw_injection(Tesselator *self) {
|
||||
// Check
|
||||
if (!self->active) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
if (self->void_begin_end) {
|
||||
return;
|
||||
}
|
||||
// Render
|
||||
const int vertices = CustomTesselator::instance.vertex_count;
|
||||
if (vertices > 0) {
|
||||
const GLuint buffer = get_next_buffer();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * sizeof(CustomVertex), CustomTesselator::instance.vertices, GL_STATIC_DRAW);
|
||||
if (self->has_texture) {
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(CustomVertex), (void *) offsetof(CustomVertex, uv));
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
if (self->has_color) {
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(CustomVertex), (void *) offsetof(CustomVertex, color));
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
if (CustomTesselator::instance.normal) {
|
||||
glNormalPointer(GL_BYTE, sizeof(CustomVertex), (void *) offsetof(CustomVertex, normal));
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(CustomVertex), (void *) offsetof(CustomVertex, pos));
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
int mode = self->mode;
|
||||
if (mode == GL_QUADS) {
|
||||
mode = GL_TRIANGLES;
|
||||
}
|
||||
glDrawArrays(mode, 0, vertices);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (self->has_texture) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
if (self->has_color) {
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
if (CustomTesselator::instance.normal) {
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
}
|
||||
// Finish
|
||||
self->clear();
|
||||
self->active = false;
|
||||
}
|
||||
|
||||
static void Tesselator_vertex_injection(const Tesselator *self, const float x, const float y, const float z) {
|
||||
CustomVertex &vertex = CustomTesselator::instance.vertices[CustomTesselator::instance.vertex_count++];
|
||||
vertex.pos = {
|
||||
(self->offset_x + x) * self->sx,
|
||||
(self->offset_y + y) * self->sy,
|
||||
self->offset_z + z
|
||||
};
|
||||
if (self->has_texture) {
|
||||
vertex.uv = {self->u, self->v};
|
||||
}
|
||||
if (self->has_color) {
|
||||
vertex.color = self->_color;
|
||||
}
|
||||
if (CustomTesselator::instance.normal) {
|
||||
vertex.normal = *CustomTesselator::instance.normal;
|
||||
}
|
||||
// Convert To Triangles
|
||||
if (self->mode == GL_QUADS) {
|
||||
int &tracker = CustomTesselator::instance.quad_to_triangle_tracker;
|
||||
if (tracker == 3) {
|
||||
tracker = 0;
|
||||
} else {
|
||||
if (tracker == 2) {
|
||||
const int last_vertex = CustomTesselator::instance.vertex_count - 1;
|
||||
for (const int i : {-2, 0}) {
|
||||
CustomTesselator::instance.vertices[CustomTesselator::instance.vertex_count++] = CustomTesselator::instance.vertices[last_vertex + i];
|
||||
}
|
||||
}
|
||||
tracker++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Tesselator_normal_injection(__attribute__((unused)) Tesselator *self, const float nx, const float ny, const float nz) {
|
||||
const char xx = (char) (nx * 128);
|
||||
const char yy = (char) (ny * 127);
|
||||
const char zz = (char) (nz * 127);
|
||||
CustomTesselator::instance.normal = xx | (yy << 8) | (zz << 16);
|
||||
}
|
||||
|
||||
static void drawArrayVT_injection(const int buffer, const int vertices, int vertex_size, const uint mode) {
|
||||
vertex_size = sizeof(CustomVertex);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glTexCoordPointer(2, GL_FLOAT, vertex_size, (void *) offsetof(CustomVertex, uv));
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, vertex_size, (void *) offsetof(CustomVertex, pos));
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glNormalPointer(GL_BYTE, sizeof(CustomVertex), (void *) offsetof(CustomVertex, normal));
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glDrawArrays(mode, 0, vertices);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
// Init
|
||||
void _init_custom_tesselator() {
|
||||
multidraw_vertex_size = sizeof(CustomVertex);
|
||||
overwrite_calls(Tesselator_init, Tesselator_init_injection);
|
||||
overwrite_calls(Tesselator_clear, Tesselator_clear_injection);
|
||||
overwrite_calls(Tesselator_begin, Tesselator_begin_injection);
|
||||
overwrite_call((void *) Tesselator_end->backup, (void *) Tesselator_end_injection, true);
|
||||
overwrite_call((void *) Tesselator_draw->backup, (void *) Tesselator_draw_injection, true);
|
||||
overwrite_call((void *) Tesselator_vertex->backup, (void *) Tesselator_vertex_injection, true);
|
||||
overwrite_call((void *) Tesselator_normal->backup, (void *) Tesselator_normal_injection, true);
|
||||
overwrite_call((void *) Common_drawArrayVT->backup, (void *) drawArrayVT_injection, true);
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
size 0x18;
|
||||
|
||||
constructor () = 0x525ac;
|
||||
|
||||
property uint buffer = 0x0;
|
||||
property int vertices = 0x4;
|
||||
property float x = 0xc;
|
||||
property float y = 0x10;
|
||||
property float z = 0x14;
|
||||
property int id = 0x8;
|
||||
property Vec3 pos = 0xc;
|
||||
|
||||
mark-as-simple;
|
@ -7,3 +7,4 @@ static-method int sdl_key_to_minecraft_key(int sdl_key) = 0x1243c;
|
||||
static-method void anGenBuffers(int count, uint *buffers) = 0x5f28c;
|
||||
static-method int getTimeMs() = 0x13cd4;
|
||||
static-method int getEpochTimeS() = 0x13d00;
|
||||
static-method void drawArrayVT(int buffer, int vertices, int vertex_size, uint mode) = 0x5f2cc;
|
@ -1,9 +1,53 @@
|
||||
method void init() = 0x5289c;
|
||||
method void clear() = 0x528ac;
|
||||
|
||||
method void begin(int mode) = 0x529d4;
|
||||
method void begin_quads() = 0x52a24;
|
||||
|
||||
method RenderChunk end(bool use_given_buffer, int buffer) = 0x528d4;
|
||||
method void draw() = 0x52e08;
|
||||
method void voidBeginAndEndCalls(bool x) = 0x52f74;
|
||||
|
||||
method void colorABGR(int color) = 0x52b54;
|
||||
method void color(int r, int g, int b, int a) = 0x52a48;
|
||||
method void noColor() = 0x52d54;
|
||||
method void enableColor() = 0x52f7c;
|
||||
|
||||
method void vertex(float x, float y, float z) = 0x52bc0;
|
||||
method void tex(float u, float v) = 0x52a2c;
|
||||
method void vertexUV(float x, float y, float z, float u, float v) = 0x52d40;
|
||||
|
||||
method void scale2d(float sx, float sy) = 0x52b94;
|
||||
method void resetScale() = 0x52bb0;
|
||||
|
||||
method void normal(float nx, float ny, float nz) = 0x52d68;
|
||||
|
||||
method void offset(float x, float y, float z) = 0x52d80;
|
||||
method void addOffset(float x, float y, float z) = 0x52d90;
|
||||
method void offset_vec3(const Vec3 &x) = 0x52db8;
|
||||
method void addOffset_vec3(const Vec3 &x) = 0x52dd4;
|
||||
|
||||
property bool active = 0x3c;
|
||||
property int mode = 0x58;
|
||||
|
||||
property int next_buffer_id = 0x44;
|
||||
property uint *buffers = 0x48;
|
||||
property int buffer_count = 0x40;
|
||||
|
||||
property float offset_x = 0x8;
|
||||
property float offset_y = 0xc;
|
||||
property float offset_z = 0x10;
|
||||
|
||||
property bool has_texture = 0x2d;
|
||||
property float u = 0x14;
|
||||
property float v = 0x18;
|
||||
|
||||
property bool has_color = 0x2c;
|
||||
property uint _color = 0x1c;
|
||||
|
||||
property float sx = 0x24;
|
||||
property float sy = 0x28;
|
||||
|
||||
property bool void_begin_end = 0x30;
|
||||
|
||||
static-property Tesselator instance = 0x137538;
|
||||
|
Loading…
Reference in New Issue
Block a user