Implement TextureMaterial properly for the new setup.

This commit is contained in:
Relintai 2024-01-04 15:52:04 +01:00
parent 8f6288e674
commit caa9e4d39c
4 changed files with 64 additions and 82 deletions

View File

@ -120,7 +120,7 @@ GameScene::GameScene() {
_font_test_sprite = memnew(Sprite); _font_test_sprite = memnew(Sprite);
_font_test_mat = memnew(TextureMaterial2D()); _font_test_mat = memnew(FontMaterial());
_font_test_mat->texture = _font->get_texture().ptr(); _font_test_mat->texture = _font->get_texture().ptr();
_font_test_sprite->mesh_instance->material = _font_test_mat; _font_test_sprite->mesh_instance->material = _font_test_mat;
_font_test_sprite->width = _font->get_atlas_width(); _font_test_sprite->width = _font->get_atlas_width();

View File

@ -40,7 +40,7 @@ public:
Ref<Font> _font; Ref<Font> _font;
Sprite *_font_test_sprite; Sprite *_font_test_sprite;
TextureMaterial2D *_font_test_mat; FontMaterial *_font_test_mat;
Ref<Mesh> _font_test_mesh; Ref<Mesh> _font_test_mesh;
MeshInstance2D *_font_test_mi; MeshInstance2D *_font_test_mi;

View File

@ -2,114 +2,97 @@
#define FONT_MATERIAL_H #define FONT_MATERIAL_H
#include "render_core/material.h" #include "render_core/material.h"
#include "render_core/texture.h"
#include "core/color.h"
#include "render_core/render_state.h" #include "render_core/render_state.h"
class FontMaterial : public Material { class FontMaterial : public Material {
public: public:
int get_material_id() { int get_material_id() {
return 10; return 11;
} }
void bind_uniforms() { void bind_uniforms() {
set_uniform(projection_matrix_location, RenderState::projection_matrix_3d); set_uniform(projection_matrix_location, RenderState::projection_matrix_2d);
set_uniform(model_view_matrix_location, RenderState::model_view_matrix_3d); set_uniform(model_view_matrix_location, RenderState::model_view_matrix_2d);
glUniform4f(tri_color_uniform_location, color.r, color.g, color.b, color.a); if (texture) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->get_gl_texture());
glUniform1i(texture_location, 0);
}
} }
void setup_uniforms() { void setup_uniforms() {
projection_matrix_location = get_uniform("u_proj_matrix"); projection_matrix_location = get_uniform("u_proj_matrix");
model_view_matrix_location = get_uniform("u_model_view_matrix"); model_view_matrix_location = get_uniform("u_model_view_matrix");
tri_color_uniform_location = get_uniform("fragment_color"); texture_location = get_uniform("u_texture");
} }
GLuint get_program() { void unbind() {
return shader->program; glDisable(GL_TEXTURE_2D);
}
void setup_state() {
glEnable(GL_TEXTURE_2D);
} }
const GLchar **get_vertex_shader_source() { const GLchar **get_vertex_shader_source() {
static const GLchar *vertex_shader_source[] = { static const GLchar *vertex_shader_source[] = {
"\ "uniform mat4 u_proj_matrix;\n"
\n\ "uniform mat4 u_model_view_matrix;\n"
in Vector2 vertexPosition;\n\ "\n"
in vec4 instanceGlyph;\n\ "attribute vec4 a_position;\n"
\n\ "attribute vec2 a_uv;\n"
uniform sampler2D sampler_font;\n\ "\n"
uniform sampler2D sampler_meta;\n\ "varying vec2 v_uv;\n"
\n\ "\n"
uniform float offset_firstline; // ascent - descent - linegap/2\n\ "void main() {\n"
uniform float scale_factor; // scaling factor proportional to font size\n\ " v_uv = a_uv;\n"
uniform Vector2 string_offset; // offset of upper-left corner\n\ " gl_Position = u_proj_matrix * u_model_view_matrix * a_position;\n"
\n\ "}"
uniform Vector2 res_meta; // 96x2 \n\
uniform Vector2 res_bitmap; // 512x256\n\
uniform Vector2 resolution; // screen resolution\n\
\n\
out Vector2 uv;\n\
out float color_index; // for syntax highlighting\n\
\n\
void main() { \
// (xoff, yoff, xoff2, yoff2), from second row of texture\n\
vec4 q2 = texture(sampler_meta, Vector2((instanceGlyph.z + 0.5)/res_meta.x, 0.75))*vec4(res_bitmap, res_bitmap);\n\
\n\
Vector2 p = vertexPosition*(q2.zw - q2.xy) + q2.xy; // offset and scale it properly relative to baseline\n\
p *= Vector2(1.0, -1.0); // flip y, since texture is upside-down\n\
p.y -= offset_firstline; // make sure the upper-left corner of the string is in the upper-left corner of the screen\n\
p *= scale_factor; // scale relative to font size\n\
p += instanceGlyph.xy + string_offset; // move glyph into the right position\n\
p *= 2.0/resolution; // to NDC\n\
p += Vector2(-1.0, 1.0); // move to upper-left corner instead of center\n\
\n\
gl_Position = vec4(p, 0.0, 1.0);\n\
\n\
// (x0, y0, x1-x0, y1-y0), from first row of texture\n\
vec4 q = texture(sampler_meta, Vector2((instanceGlyph.z + 0.5)/res_meta.x, 0.25));\n\
\n\
// send the correct uv's in the font atlas to the fragment shader\n\
uv = q.xy + vertexPosition*q.zw;\n\
color_index = instanceGlyph.w;\n\
}\n"
}; };
return vertex_shader_source; return vertex_shader_source;
} }
const GLchar ** const GLchar **get_fragment_shader_source() {
get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = { static const GLchar *fragment_shader_source[] = {
"\ "precision mediump float;\n"
\n\ "\n"
in Vector2 uv;\n\ "uniform sampler2D u_texture;\n"
in float color_index;\n\ "\n"
\n\ "varying vec2 v_uv;\n"
uniform sampler2D sampler_font;\n\ "\n"
uniform sampler1D sampler_colors;\n\ "void main() {\n"
uniform float num_colors;\n\ " vec4 col = texture2D(u_texture, v_uv);\n"
\n\ "\n"
out vec4 outColor;\n\ " if (col.r < 0.5) {\n"
\n\ " discard;\n"
void main() {\ " }\n"
vec4 col = texture(sampler_colors, (color_index+0.5)/num_colors);\n\ "\n"
float s = texture(sampler_font, uv).r;\n\ " gl_FragColor = col;\n"
outColor = vec4(col.rgb, s*col.a);\n\ "}"
}\n"
}; };
return fragment_shader_source; return fragment_shader_source;
} }
FontMaterial() { FontMaterial() {
projection_matrix_location = 0;
model_view_matrix_location = 0;
texture_location = 0;
texture = NULL;
} }
GLint projection_matrix_location; GLint projection_matrix_location;
GLint model_view_matrix_location; GLint model_view_matrix_location;
GLint tri_color_uniform_location; GLint texture_location;
Color color;
Texture *texture;
}; };
#endif // TEXT_MATERIAL_H #endif // TEXT_MATERIAL_H

View File

@ -13,8 +13,8 @@ public:
} }
void bind_uniforms() { void bind_uniforms() {
set_uniform(projection_matrix_location, RenderState::projection_matrix_2d); set_uniform(projection_matrix_location, RenderState::projection_matrix_2d);
set_uniform(model_view_matrix_location, RenderState::model_view_matrix_2d); set_uniform(model_view_matrix_location, RenderState::model_view_matrix_2d);
if (texture) { if (texture) {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@ -66,21 +66,20 @@ public:
"varying vec2 v_uv;\n" "varying vec2 v_uv;\n"
"\n" "\n"
"void main() {\n" "void main() {\n"
" vec4 col = texture2D(u_texture, v_uv);\n" " vec4 col = texture2D(u_texture, v_uv);\n"
"\n" "\n"
" if (col.a < 0.1) {\n" " if (col.a < 0.1) {\n"
" discard;\n" " discard;\n"
" }\n" " }\n"
"\n" "\n"
" gl_FragColor = col;\n" " gl_FragColor = col;\n"
"}" "}"
}; };
return fragment_shader_source; return fragment_shader_source;
} }
TextureMaterial2D() : TextureMaterial2D() {
Material() {
projection_matrix_location = 0; projection_matrix_location = 0;
model_view_matrix_location = 0; model_view_matrix_location = 0;