Entities Have Shading!

This commit is contained in:
TheBrokenRail 2024-10-18 15:14:18 -04:00
parent 1001427309
commit 18f7d64405
17 changed files with 211 additions and 37 deletions

View File

@ -231,4 +231,16 @@ void glGenBuffers(const GLsizei n, GLuint *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);
}
GL_FUNC(glLightfv, void, (GLenum light, GLenum pname, const GLfloat *params))
void glLightfv(const GLenum light, const GLenum pname, const GLfloat *params) {
real_glLightfv()(light, pname, params);
}
GL_FUNC(glColorMaterial, void, (GLenum face, GLenum mode))
void glColorMaterial(const GLenum face, const GLenum mode) {
real_glColorMaterial()(face, mode);
}
GL_FUNC(glLightModelfv, void, (GLenum pname, const GLfloat *params))
void glLightModelfv(const GLenum pname, const GLfloat *params) {
real_glLightModelfv()(pname, params);
}

View File

@ -88,6 +88,17 @@ extern "C" {
#define GL_ALPHA 0x1906
#define GL_NONE 0
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846e
#define GL_LIGHTING 0xb50
#define GL_LIGHT0 0x4000
#define GL_LIGHT1 0x4001
#define GL_RESCALE_NORMAL 0x803a
#define GL_POSITION 0x1203
#define GL_DIFFUSE 0x1201
#define GL_AMBIENT 0x1200
#define GL_SPECULAR 0x1202
#define GL_FRONT_AND_BACK 0x408
#define GL_AMBIENT_AND_DIFFUSE 0x1602
#define GL_LIGHT_MODEL_AMBIENT 0xb53
typedef float GLfloat;
typedef float GLclampf;
@ -161,6 +172,9 @@ void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void
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);
void glLightfv(GLenum light, GLenum pname, const GLfloat *params);
void glColorMaterial(GLenum face, GLenum mode);
void glLightModelfv(GLenum pname, const GLfloat *params);
#ifdef __cplusplus
}

View File

@ -353,6 +353,10 @@ void glDisableClientState(const GLenum array) {
gl_array_details.glTexCoordPointer.size = -1;
break;
}
case GL_NORMAL_ARRAY: {
gl_array_details.glNormalPointer.size = -1;
break;
}
}
}
#endif
@ -387,6 +391,7 @@ void glBindBuffer(const GLenum target, const GLuint buffer) {
gl_array_details.glVertexPointer.size = -1;
gl_array_details.glColorPointer.size = -1;
gl_array_details.glTexCoordPointer.size = -1;
gl_array_details.glNormalPointer.size = -1;
}
#endif
@ -674,11 +679,17 @@ CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
#endif
}
CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
void glNormal3f(__attribute__((unused)) GLfloat nx, __attribute__((unused)) GLfloat ny, __attribute__((unused)) GLfloat nz) {
// Do Nothing
}
trampoline(true, nx, ny, nz);
#else
GLfloat nx = args.next<GLfloat>();
GLfloat ny = args.next<GLfloat>();
GLfloat nz = args.next<GLfloat>();
func(nx, ny, nz);
return 0;
#endif
}
CALL(58, glIsEnabled, GLboolean, (GLenum cap))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
@ -771,12 +782,13 @@ CALL(69, glBufferSubData, void, (GLenum target, GLintptr offset, GLsizeiptr size
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); \
gl_array_details_t &state = gl_array_details.glNormalPointer;
if (state.size == -1 || state.type != type || state.stride != stride || state.pointer != uint32_t(pointer)) {
state.size = 0;
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>());
@ -784,4 +796,38 @@ CALL(72, glNormalPointer, void, (GLenum type, GLsizei stride, const void *pointe
func(state.type, state.stride, (const void *) uintptr_t(state.pointer));
return 0;
#endif
}
CALL(73, glLightfv, void, (GLenum light, GLenum pname, const GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, light, pname, copy_array(4, params));
#else
GLenum light = args.next<GLenum>();
GLenum pname = args.next<GLenum>();
const GLfloat *params = args.next_arr<GLfloat>();
func(light, pname, params);
return 0;
#endif
}
CALL(74, glColorMaterial, void, (GLenum face, GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, face, mode);
#else
GLenum face = args.next<GLenum>();
GLenum mode = args.next<GLenum>();
func(face, mode);
return 0;
#endif
}
CALL(75, glLightModelfv, void, (GLenum pname, const GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, pname, copy_array(4, params));
#else
GLenum pname = args.next<GLenum>();
const GLfloat *params = args.next_arr<GLfloat>();
func(pname, params);
return 0;
#endif
}

View File

@ -102,6 +102,8 @@ set(SRC
# shading
src/shading/init.cpp
src/shading/tesselator.cpp
src/shading/lighting.cpp
src/shading/normals.cpp
)
# Install Splashes
install(

View File

@ -346,14 +346,13 @@ static void ModelPart_render_injection(ModelPart *model_part, float scale) {
// Stop
is_rendering_chest = false;
}
static void Tesselator_vertexUV_injection(Tesselator_vertexUV_t original, Tesselator *tesselator, const float x, const float y, const float z, const float u, float v) {
static void Tesselator_vertexUV_injection(Tesselator *self, const float x, const float y, const float z, const float u, float v) {
// Fix Chest Texture
if (is_rendering_chest) {
v /= 2;
}
// Call Original Method
original(tesselator, x, y, z, u, v);
self->vertexUV(x, y, z, u, v);
}
static bool ChestTileEntity_shouldSave_injection(__attribute__((unused)) ChestTileEntity_shouldSave_t original, __attribute__((unused)) ChestTileEntity *tile_entity) {
return true;
@ -555,7 +554,7 @@ void _init_misc_graphics() {
overwrite_call((void *) 0x6655c, (void *) ModelPart_render_injection);
overwrite_call((void *) 0x66568, (void *) ModelPart_render_injection);
overwrite_call((void *) 0x66574, (void *) ModelPart_render_injection);
overwrite_calls(Tesselator_vertexUV, Tesselator_vertexUV_injection);
overwrite_call((void *) 0x4278c, (void *) Tesselator_vertexUV_injection);
unsigned char chest_model_patch[4] = {0x13, 0x20, 0xa0, 0xe3}; // "mov r2, #0x13"
patch((void *) 0x66fc8, chest_model_patch);
unsigned char chest_color_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"

View File

@ -7,5 +7,7 @@
void init_shading() {
if (feature_has("Proper Entity Shading", server_disabled)) {
_init_custom_tesselator();
_init_normals();
_init_lighting();
}
}

View File

@ -0,0 +1,55 @@
#include <GLES/gl.h>
#include <symbols/minecraft.h>
#include <libreborn/libreborn.h>
#include "shading-internal.h"
// OpenGL Lighting
static float *get_buffer(const float a, const float b, const float c, const float d) {
static float buffer[4];
buffer[0] = a;
buffer[1] = b;
buffer[2] = c;
buffer[3] = d;
return buffer;
}
static void lighting_turn_on() {
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
constexpr float a = 0.4f;
constexpr float d = 0.6f;
constexpr float s = 0.0f;
Vec3 l = Vec3(0.2f, 1.0f, -0.7f).normalized();
glLightfv(GL_LIGHT0, GL_POSITION, get_buffer(l.x, l.y, l.z, 0));
glLightfv(GL_LIGHT0, GL_DIFFUSE, get_buffer(d, d, d, 1));
glLightfv(GL_LIGHT0, GL_AMBIENT, get_buffer(0, 0, 0, 1));
glLightfv(GL_LIGHT0, GL_SPECULAR, get_buffer(s, s, s, 1.0f));
l = Vec3(-0.2f, 1.0f, 0.7f).normalized();
glLightfv(GL_LIGHT1, GL_POSITION, get_buffer(l.x, l.y, l.z, 0));
glLightfv(GL_LIGHT1, GL_DIFFUSE, get_buffer(d, d, d, 1));
glLightfv(GL_LIGHT1, GL_AMBIENT, get_buffer(0, 0, 0, 1));
glLightfv(GL_LIGHT1, GL_SPECULAR, get_buffer(s, s, s, 1.0f));
glShadeModel(GL_FLAT);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, get_buffer(a, a, a, 1));
}
static void lighting_turn_off() {
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHT1);
glDisable(GL_COLOR_MATERIAL);
}
// Entity Rendering
static void LevelRenderer_renderEntities_injection(LevelRenderer_renderEntities_t original, LevelRenderer *self, Vec3 pos, void *unknown, float a) {
lighting_turn_on();
original(self, pos, unknown, a);
lighting_turn_off();
}
// Init
void _init_lighting() {
overwrite_calls(LevelRenderer_renderEntities, LevelRenderer_renderEntities_injection);
}

View File

@ -0,0 +1,26 @@
#include <symbols/minecraft.h>
#include <libreborn/libreborn.h>
#include "shading-internal.h"
// PolygonQuad
Vec3 vector_to(const Vec3 &a, const Vec3 &b) {
return Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
}
Vec3 vector_cross(const Vec3 &a, const Vec3 &b) {
return Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}
static void PolygonQuad_render_injection(PolygonQuad_render_t original, PolygonQuad *self, Tesselator &t, float scale, int buffer) {
// Set Normal
const Vec3 v0 = vector_to(self->vertices[1].pos, self->vertices[0].pos);
const Vec3 v1 = vector_to(self->vertices[1].pos, self->vertices[2].pos);
const Vec3 n = vector_cross(v1, v0).normalized();
t.normal(n.x, n.y, n.z);
// Call Original Method
original(self, t, scale, buffer);
}
// Init
void _init_normals() {
overwrite_calls(PolygonQuad_render, PolygonQuad_render_injection);
}

View File

@ -1,3 +1,5 @@
#pragma once
__attribute__((visibility("internal"))) void _init_custom_tesselator();
__attribute__((visibility("internal"))) void _init_custom_tesselator();
__attribute__((visibility("internal"))) void _init_normals();
__attribute__((visibility("internal"))) void _init_lighting();

View File

@ -31,6 +31,7 @@ struct CustomTesselator {
};
CustomTesselator CustomTesselator::instance;
// Setup Vertex Array
static void Tesselator_clear_injection(Tesselator_clear_t original, Tesselator *self) {
if (original) {
original(self);
@ -39,7 +40,6 @@ static void Tesselator_clear_injection(Tesselator_clear_t original, Tesselator *
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);
@ -47,6 +47,7 @@ static void Tesselator_init_injection(Tesselator_init_t original, Tesselator *se
Tesselator_clear_injection(nullptr, nullptr);
}
// Handle Tesselation Start
static void Tesselator_begin_injection(Tesselator_begin_t original, Tesselator *self, const int mode) {
original(self, mode);
if (!self->void_begin_end) {
@ -54,13 +55,13 @@ static void Tesselator_begin_injection(Tesselator_begin_t original, Tesselator *
}
}
// Drawing
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) {
@ -83,7 +84,6 @@ static RenderChunk Tesselator_end_injection(Tesselator *self, const bool use_giv
self->active = false;
return out;
}
static void Tesselator_draw_injection(Tesselator *self) {
// Check
if (!self->active) {
@ -132,7 +132,22 @@ static void Tesselator_draw_injection(Tesselator *self) {
self->clear();
self->active = false;
}
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);
}
// Add Vertex
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 = {
@ -166,28 +181,14 @@ static void Tesselator_vertex_injection(const Tesselator *self, const float x, c
}
}
// Specify Normal
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);
const signed char xx = (signed char) (nx * 127);
const signed char yy = (signed char) (ny * 127);
const signed char zz = (signed 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);

View File

@ -35,7 +35,7 @@ set(SRC
src/entity/EntityRenderer.def
src/entity/ItemSpriteRenderer.def
src/entity/PathfinderMob.def
src/entity/HumanoidModel.def
src/entity/model/HumanoidModel.def
src/entity/TripodCameraRenderer.def
src/entity/TripodCamera.def
src/entity/MobFactory.def
@ -161,7 +161,9 @@ set(SRC
src/misc/Strings.def
src/misc/I18n.def
src/misc/SimpleFoodData.def
src/entity/ModelPart.def
src/entity/model/ModelPart.def
src/entity/model/PolygonQuad.def
src/entity/model/VertexPT.def
src/misc/Tesselator.def
src/misc/AABB.def
src/misc/Vec3.def

View File

@ -0,0 +1,3 @@
method void render(Tesselator &t, float scale, int buffer) = 0x42744;
property VertexPT vertices[4] = 0x0;

View File

@ -0,0 +1,7 @@
size 0x14;
property Vec3 pos = 0x0;
property float u = 0xc;
property float v = 0x10;
mark-as-simple;

View File

@ -6,6 +6,7 @@ method void generateSky() = 0x4d0d4;
method void renderHitSelect(Player *player, const HitResult &hit_result, int i, void *vp, float f) = 0x4e318;
method void renderHitOutline(Player *player, const HitResult &hit_result, int i, void *vp, float f) = 0x4dc14;
method int renderChunks(int start, int end, int a, float b) = 0x4f35c;
method void renderEntities(Vec3 pos, void *unknown, float a) = 0x500ec;
property Minecraft *minecraft = 0xb4;
property RenderList render_list = 0x34;

View File

@ -1,5 +1,7 @@
size 0xc;
method Vec3 normalized() = 0x5eae4;
property float x = 0x0;
property float y = 0x4;
property float z = 0x8;