mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
tr1/output: make sprites use the meshes shader
This commit is contained in:
parent
01b2d37fdc
commit
f144f8ccad
6 changed files with 42 additions and 72 deletions
|
@ -6,6 +6,7 @@
|
||||||
#define VERT_FLAT_SHADED 0x02
|
#define VERT_FLAT_SHADED 0x02
|
||||||
#define VERT_REFLECTIVE 0x04
|
#define VERT_REFLECTIVE 0x04
|
||||||
#define VERT_NO_LIGHTING 0x08
|
#define VERT_NO_LIGHTING 0x08
|
||||||
|
#define VERT_SPRITE 0x10 // flag for billboarded sprites in mesh shader
|
||||||
|
|
||||||
#define WIBBLE_SIZE 32
|
#define WIBBLE_SIZE 32
|
||||||
#define MAX_WIBBLE 2
|
#define MAX_WIBBLE 2
|
||||||
|
|
|
@ -27,11 +27,18 @@ out float gShade;
|
||||||
out vec4 gColor;
|
out vec4 gColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gWorldPos = uMatModelView * vec4(inPosition.xyz, 1.0);
|
// billboard sprites if flagged, else standard vertex transform
|
||||||
|
vec4 eyePos = uMatModelView * vec4(inPosition.xyz, 1.0);
|
||||||
|
if ((inFlags & VERT_SPRITE) != 0) {
|
||||||
|
// inNormal.xy carries sprite displacement for billboarding
|
||||||
|
eyePos.xy += inNormal.xy;
|
||||||
|
}
|
||||||
|
gWorldPos = eyePos;
|
||||||
gNormal = inNormal;
|
gNormal = inNormal;
|
||||||
gl_Position = uMatProjection * gWorldPos;
|
gl_Position = uMatProjection * eyePos;
|
||||||
|
|
||||||
if (uWibbleEffect && (inFlags & VERT_NO_CAUSTICS) == 0) {
|
// apply water wibble effect only to non-sprite vertices
|
||||||
|
if (uWibbleEffect && (inFlags & VERT_NO_CAUSTICS) == 0 && (inFlags & VERT_SPRITE) == 0) {
|
||||||
gl_Position.xyz =
|
gl_Position.xyz =
|
||||||
waterWibble(gl_Position, uViewportSize, uTime);
|
waterWibble(gl_Position, uViewportSize, uTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
#ifdef VERTEX
|
|
||||||
|
|
||||||
uniform samplerBuffer uUVW; // texture u, v, layer
|
|
||||||
uniform vec2 uViewportSize;
|
|
||||||
uniform mat4 uMatProjection;
|
|
||||||
uniform mat4 uMatModelView;
|
|
||||||
uniform int uTime;
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 inPosition;
|
|
||||||
layout(location = 1) in vec2 inDisplacement;
|
|
||||||
layout(location = 2) in vec3 inUVW;
|
|
||||||
layout(location = 3) in float inShade;
|
|
||||||
|
|
||||||
out vec4 gWorldPos;
|
|
||||||
out vec2 gTexUV;
|
|
||||||
flat out int gTexLayer;
|
|
||||||
out float gShade;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
vec4 centerEyeSpace = uMatModelView * vec4(inPosition, 1.0);
|
|
||||||
gWorldPos = centerEyeSpace;
|
|
||||||
centerEyeSpace.xy += inDisplacement;
|
|
||||||
gl_Position = uMatProjection * centerEyeSpace;
|
|
||||||
|
|
||||||
gTexUV = inUVW.xy;
|
|
||||||
gTexLayer = int(inUVW.z);
|
|
||||||
gShade = inShade;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(FRAGMENT)
|
|
||||||
|
|
||||||
uniform sampler2DArray uTexAtlas;
|
|
||||||
uniform sampler2D uTexEnvMap;
|
|
||||||
uniform bool uSmoothingEnabled;
|
|
||||||
uniform float uBrightnessMultiplier;
|
|
||||||
uniform vec3 uGlobalTint;
|
|
||||||
uniform vec2 uFog; // x = fog start, y = fog end
|
|
||||||
|
|
||||||
in vec4 gWorldPos;
|
|
||||||
in vec2 gTexUV;
|
|
||||||
flat in int gTexLayer;
|
|
||||||
in float gShade;
|
|
||||||
out vec4 outColor;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
vec3 uvw = vec3(gTexUV.x, gTexUV.y, gTexLayer);
|
|
||||||
vec4 texColor = texture(uTexAtlas, uvw);
|
|
||||||
if (uSmoothingEnabled && discardTranslucent(uTexAtlas, uvw)) {
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texColor.a <= 0.0) {
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
float shade = gShade;
|
|
||||||
shade = shadeFog(shade, gWorldPos.z, uFog);
|
|
||||||
texColor.rgb = applyShade(texColor.rgb, shade);
|
|
||||||
texColor.rgb *= uGlobalTint;
|
|
||||||
texColor.rgb *= uBrightnessMultiplier;
|
|
||||||
outColor = vec4(texColor.rgb, 1.0);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -401,8 +401,8 @@ bool Output_Init(void)
|
||||||
GFX_3D_Renderer_SetAlphaPointDiscard(m_Renderer3D, true);
|
GFX_3D_Renderer_SetAlphaPointDiscard(m_Renderer3D, true);
|
||||||
|
|
||||||
Output_Textures_Init();
|
Output_Textures_Init();
|
||||||
Output_Sprites_Init();
|
|
||||||
Output_Meshes_Init();
|
Output_Meshes_Init();
|
||||||
|
Output_Sprites_Init();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#define VERT_FLAT_SHADED 0b0000'0010 // = 0x02
|
#define VERT_FLAT_SHADED 0b0000'0010 // = 0x02
|
||||||
#define VERT_REFLECTIVE 0b0000'0100 // = 0x04
|
#define VERT_REFLECTIVE 0b0000'0100 // = 0x04
|
||||||
#define VERT_NO_LIGHTING 0b0000'1000 // = 0x08
|
#define VERT_NO_LIGHTING 0b0000'1000 // = 0x08
|
||||||
|
#define VERT_SPRITE 0b0001'0000 // = 0x10
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
#include "game/output/sprites.h"
|
#include "game/output/sprites.h"
|
||||||
|
|
||||||
#include "game/output.h"
|
#include "game/output.h"
|
||||||
|
#include "game/output/meshes/common.h"
|
||||||
#include "game/output/shader.h"
|
#include "game/output/shader.h"
|
||||||
#include "game/output/textures.h"
|
#include "game/output/textures.h"
|
||||||
#include "game/output/utils.h"
|
#include "game/output/utils.h"
|
||||||
#include "game/output/vertex_range.h"
|
#include "game/output/vertex_range.h"
|
||||||
#include "game/room.h"
|
#include "game/room.h"
|
||||||
|
|
||||||
|
#include <libtrx/game/math/types.h>
|
||||||
|
#include <libtrx/game/output/types.h>
|
||||||
#include <libtrx/gfx/gl/utils.h>
|
#include <libtrx/gfx/gl/utils.h>
|
||||||
#include <libtrx/log.h>
|
#include <libtrx/log.h>
|
||||||
#include <libtrx/memory.h>
|
#include <libtrx/memory.h>
|
||||||
|
@ -33,7 +36,7 @@ typedef struct {
|
||||||
MATRIX matrix;
|
MATRIX matrix;
|
||||||
XYZ_32 pos;
|
XYZ_32 pos;
|
||||||
int32_t sprite_idx;
|
int32_t sprite_idx;
|
||||||
uint16_t shade;
|
M_SPRITE_SHADE shade;
|
||||||
} M_DYNAMIC_SPRITE;
|
} M_DYNAMIC_SPRITE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -135,25 +138,47 @@ static void M_PrepareBuffer(
|
||||||
glBindVertexArray(buffer->vao);
|
glBindVertexArray(buffer->vao);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buffer->geom_vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, buffer->geom_vbo);
|
||||||
|
|
||||||
|
// attribute 0: position
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
0, 3, GL_FLOAT, GL_FALSE, sizeof(M_SPRITE_VERTEX),
|
0, 3, GL_FLOAT, GL_FALSE, sizeof(M_SPRITE_VERTEX),
|
||||||
(void *)(intptr_t)offsetof(M_SPRITE_VERTEX, pos));
|
(void *)(intptr_t)offsetof(M_SPRITE_VERTEX, pos));
|
||||||
|
|
||||||
|
// attribute 1: normal (becomes sprite corner displacement)
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
1, 2, GL_FLOAT, GL_FALSE, sizeof(M_SPRITE_VERTEX),
|
1, 2, GL_FLOAT, GL_FALSE, sizeof(M_SPRITE_VERTEX),
|
||||||
(void *)(intptr_t)offsetof(M_SPRITE_VERTEX, displacement));
|
(void *)(intptr_t)offsetof(M_SPRITE_VERTEX, displacement));
|
||||||
|
|
||||||
|
// attribute 2: uvw
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
2, 3, GL_FLOAT, GL_FALSE, sizeof(M_SPRITE_VERTEX),
|
2, 3, GL_FLOAT, GL_FALSE, sizeof(M_SPRITE_VERTEX),
|
||||||
(void *)(intptr_t)offsetof(M_SPRITE_VERTEX, uvw));
|
(void *)(intptr_t)offsetof(M_SPRITE_VERTEX, uvw));
|
||||||
|
|
||||||
|
// attribute 3: texture size
|
||||||
|
glDisableVertexAttribArray(3);
|
||||||
|
glVertexAttrib4f(3, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
// attribute 4: trapezoid ratios
|
||||||
|
glDisableVertexAttribArray(4);
|
||||||
|
glVertexAttrib2f(4, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
// attribute 5: flags
|
||||||
|
glDisableVertexAttribArray(5);
|
||||||
|
glVertexAttribI1i(5, VERT_SPRITE);
|
||||||
|
|
||||||
|
// attribute 6: mesh color (ignore)
|
||||||
|
glDisableVertexAttribArray(6);
|
||||||
|
glVertexAttrib4f(6, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buffer->shade_vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, buffer->shade_vbo);
|
||||||
glEnableVertexAttribArray(3);
|
|
||||||
|
// attribute 7 (shade)
|
||||||
|
glEnableVertexAttribArray(7);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
3, 1, GL_UNSIGNED_SHORT, GL_FALSE, sizeof(M_SPRITE_SHADE), 0);
|
7, 1, GL_UNSIGNED_SHORT, GL_FALSE, sizeof(M_SPRITE_SHADE), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_FreeBuffer(M_SPRITE_BUFFER *const buffer)
|
static void M_FreeBuffer(M_SPRITE_BUFFER *const buffer)
|
||||||
|
@ -306,7 +331,7 @@ static void M_PrepareLevelBuffers(void)
|
||||||
|
|
||||||
void Output_Sprites_Init(void)
|
void Output_Sprites_Init(void)
|
||||||
{
|
{
|
||||||
m_Shader = Output_Shader_Create("shaders/sprites.glsl");
|
m_Shader = Output_Meshes_GetShader();
|
||||||
m_LevelData.animated_vertices = Vector_Create(sizeof(OUTPUT_VERTEX_RANGE));
|
m_LevelData.animated_vertices = Vector_Create(sizeof(OUTPUT_VERTEX_RANGE));
|
||||||
m_Dynamic.source = Vector_CreateAtCapacity(sizeof(M_DYNAMIC_SPRITE), 50);
|
m_Dynamic.source = Vector_CreateAtCapacity(sizeof(M_DYNAMIC_SPRITE), 50);
|
||||||
}
|
}
|
||||||
|
@ -316,7 +341,6 @@ void Output_Sprites_Shutdown(void)
|
||||||
Vector_Free(m_LevelData.animated_vertices);
|
Vector_Free(m_LevelData.animated_vertices);
|
||||||
Vector_Free(m_Dynamic.source);
|
Vector_Free(m_Dynamic.source);
|
||||||
M_FreeBuffers();
|
M_FreeBuffers();
|
||||||
Output_Shader_Free(m_Shader);
|
|
||||||
m_Shader = nullptr;
|
m_Shader = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue