update love-demo2 code to latest version

This commit is contained in:
Zack Buhman 2026-03-20 20:22:45 -05:00
parent d972017f57
commit dfb114b5fc
58 changed files with 837936 additions and 223132 deletions

View File

@ -20,6 +20,7 @@ LDFLAGS += $(shell pkg-config --libs glfw3)
MINECRAFT_OBJS = \
minecraft/love2dworld/inthash.o \
minecraft/grandlecturn/inthash.o \
minecraft/midnightmeadow/inthash.o \
src/minecraft.o \
src/world/world.o \
src/world/entry_table.o
@ -28,7 +29,8 @@ OBJS = \
src/gl.o \
src/opengl.o \
src/test.o \
src/font.o \
src/font/bitmap.o \
src/font/outline.o \
src/window.o \
src/bresenham.o \
src/file.o \
@ -47,6 +49,7 @@ OBJS = \
src/collada/animate.o \
src/lua_api.o \
src/pixel_line_art.o \
src/flame.o \
data/scenes/ship20/ship20.o \
data/scenes/noodle/noodle.o \
data/scenes/shadow_test/shadow_test.o \

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

7
game/include/flame.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
namespace flame {
void load_program();
void load_texture();
void draw(unsigned int light_uniform_buffer, int light_count);
}

View File

@ -0,0 +1,67 @@
#pragma once
namespace font::bitmap {
struct font_desc {
char const * const path;
int const texture_width;
int const texture_height;
int const glyph_width;
int const glyph_height;
};
font_desc const terminus[] = {
{
.path = "font/bitmap/terminus_128x64_6x12.data",
.texture_width = 128,
.texture_height = 64,
.glyph_width = 6,
.glyph_height = 12,
},
{
.path = "font/bitmap/terminus_128x128_8x16.data",
.texture_width = 128,
.texture_height = 128,
.glyph_width = 8,
.glyph_height = 16,
},
{
.path = "font/bitmap/terminus_256x128_10x18.data",
.texture_width = 256,
.texture_height = 128,
.glyph_width = 10,
.glyph_height = 18,
},
{
.path = "font/bitmap/terminus_256x128_12x24.data",
.texture_width = 256,
.texture_height = 128,
.glyph_width = 12,
.glyph_height = 24,
},
{
.path = "font/bitmap/terminus_256x256_16x32.data",
.texture_width = 256,
.texture_height = 256,
.glyph_width = 16,
.glyph_height = 32,
},
};
int const terminus_length = (sizeof (terminus)) / (sizeof (font_desc));
struct font {
font_desc const * desc;
unsigned int texture;
int stride;
struct {
float width;
float height;
} cell;
};
void load_shader();
void load_fonts(font * const fonts, font_desc const * const descs, int length);
int best_font(font_desc const * const descs, int length);
void draw_start(font const& font, unsigned int vertex_array_object, unsigned int index_buffer);
int draw_string(font const& font, char const * const s, int x, int y);
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "outline_types.h"
namespace font::outline {
struct font_desc {
char const * const path;
};
font_desc const uncial_antiqua[] = {
{
.path = "font/outline/uncial_antiqua_36.data",
},
};
int const uncial_antiqua_length = (sizeof (uncial_antiqua)) / (sizeof (font_desc));
struct font {
unsigned int texture;
types::font const * font;
types::glyph const * glyphs;
};
void load_shader();
void load_fonts(font * const fonts, font_desc const * const descs, int length);
void draw_start(font const& font, unsigned int vertex_array_object, unsigned int index_buffer);
int draw_string(font const& font, char const * const s, int x, int y);
}

View File

@ -0,0 +1,49 @@
// this file is designed to be platform-agnostic
#pragma once
#include <stdint.h>
namespace font::outline::types {
// metrics are 26.6 fixed point
struct glyph_metrics {
int32_t horiBearingX;
int32_t horiBearingY;
int32_t horiAdvance;
} __attribute__ ((packed));
static_assert((sizeof (struct glyph_metrics)) == ((sizeof (int32_t)) * 3));
struct glyph_bitmap {
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} __attribute__ ((packed));
static_assert((sizeof (struct glyph_bitmap)) == ((sizeof (uint16_t)) * 4));
struct glyph {
struct glyph_bitmap bitmap;
struct glyph_metrics metrics;
} __attribute__ ((packed));
static_assert((sizeof (struct glyph)) == ((sizeof (struct glyph_bitmap)) + (sizeof (struct glyph_metrics))));
struct font {
uint32_t first_char_code;
uint32_t last_char_code;
struct face_metrics {
int32_t height; // 26.6 fixed point
int32_t max_advance; // 26.6 fixed point
} face_metrics;
uint16_t glyph_count;
uint16_t _texture_stride;
uint16_t texture_width;
uint16_t texture_height;
uint32_t max_z_curve_ix;
} __attribute__ ((packed));
static_assert((sizeof (struct font)) == ((sizeof (uint32_t)) * 7));
}

View File

@ -1,5 +1,7 @@
#pragma once
#include "directxmath/directxmath.h"
namespace view {
struct view_state {
// positions

View File

@ -8,6 +8,7 @@ extern "C" {
uint32_t love2dworld_hash(const int32_t key);
uint32_t grandlecturn_hash(const int32_t key);
uint32_t midnightmeadow_hash(const int32_t key);
#ifdef __cplusplus
}

View File

@ -22,6 +22,7 @@ namespace world {
enum {
LOVE2DWORLD = 0,
GRANDLECTURN = 1,
MIDNIGHTMEADOW = 2,
};
};

View File

@ -1,291 +1,265 @@
-- local ffi = require 'ffi'
-- local joysticks
local ffi = require 'ffi'
local joysticks
-- function init()
-- joysticks = love.joystick.getJoysticks()
-- for i, joystick in ipairs(joysticks) do
-- print(i, joystick:getName())
-- end
function init()
joysticks = love.joystick.getJoysticks()
for i, joystick in ipairs(joysticks) do
print(i, joystick:getName())
end
-- ffi.cdef[[
-- void load(const char * source_path);
-- void update_window(int width, int height);
-- void draw();
-- void update_keyboard(int up, int down, int left, int right,
-- int w, int s, int a, int d,
-- int t, int g, int f, int h,
-- int i, int k, int j, int l);
-- void update_mouse(int x, int y);
-- void update_joystick(int joystick_index,
-- float lx, float ly, float rx, float ry, float tl, float tr,
-- int up, int down, int left, int right,
-- int a, int b, int x, int y,
-- int leftshoulder, int rightshoulder,
-- int start);
-- void update(float time);
ffi.cdef[[
void load(const char * source_path);
void update_window(int width, int height);
void draw();
void update_keyboard(int up, int down, int left, int right,
int w, int s, int a, int d,
int t, int g, int f, int h,
int i, int k, int j, int l);
void update_mouse(int x, int y);
void update_joystick(int joystick_index,
float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right,
int a, int b, int x, int y,
int leftshoulder, int rightshoulder,
int start);
void update(float time);
-- int draw_font_start();
-- int draw_font(int font_ix, char const * text, int x, int y);
int draw_font_start();
int draw_font(int font_ix, char const * text, int x, int y);
-- void draw_line_quad_start();
-- void draw_line(int x1, int y1, int x2, int y2);
-- void draw_set_color(float r, float g, float b);
-- void draw_quad(int x1, int y1, int x2, int y2,
-- int x3, int y3, int x4, int y4);
-- ]]
-- local source_path = love.filesystem.getSource()
-- test = ffi.load(source_path .. "/test.so")
-- test.load(source_path)
void draw_line_quad_start();
void draw_line(int x1, int y1, int x2, int y2);
void draw_set_color(float r, float g, float b);
void draw_quad(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4);
]]
local source_path = love.filesystem.getSource()
test = ffi.load(source_path .. "/test.so")
test.load(source_path)
end
local update = function(time)
for joystick_index, joystick in ipairs(joysticks) do
if joystick_index > 8 then
break
end
local lx = joystick:getGamepadAxis("leftx")
local ly = joystick:getGamepadAxis("lefty")
local rx = joystick:getGamepadAxis("rightx")
local ry = joystick:getGamepadAxis("righty")
local tl = joystick:getGamepadAxis("triggerleft")
local tr = joystick:getGamepadAxis("triggerright")
local up = joystick:isGamepadDown("dpup")
local down = joystick:isGamepadDown("dpdown")
local left = joystick:isGamepadDown("dpleft")
local right = joystick:isGamepadDown("dpright")
local a = joystick:isGamepadDown("a")
local b = joystick:isGamepadDown("b")
local x = joystick:isGamepadDown("x")
local y = joystick:isGamepadDown("y")
local leftshoulder = joystick:isGamepadDown("leftshoulder")
local rightshoulder = joystick:isGamepadDown("rightshoulder")
local start = joystick:isGamepadDown("start")
--print("start", i, start)
test.update_joystick(joystick_index - 1,
lx, ly, rx, ry, tl, tr,
up, down, left, right,
a, b, x, y,
leftshoulder, rightshoulder,
start)
end
local up = love.keyboard.isDown("up")
local down = love.keyboard.isDown("down")
local left = love.keyboard.isDown("left")
local right = love.keyboard.isDown("right")
local w = love.keyboard.isDown("w")
local s = love.keyboard.isDown("s")
local a = love.keyboard.isDown("a")
local d = love.keyboard.isDown("d")
local t = love.keyboard.isDown("t")
local g = love.keyboard.isDown("g")
local f = love.keyboard.isDown("f")
local h = love.keyboard.isDown("h")
local i = love.keyboard.isDown("i")
local k = love.keyboard.isDown("k")
local j = love.keyboard.isDown("j")
local l = love.keyboard.isDown("l")
test.update_keyboard(up, down, left, right,
w, s, a, d,
t, g, f, h,
i, k, j, l);
test.update(time)
end
local draw = function()
test.draw()
end
local nico_draw = function()
----------------------------------------------------------------------
-- font drawing
----------------------------------------------------------------------
-- call "draw_font_start()" prior each "group" of "draw_font()" calls
--
-- a "group" of draw_font() calls are back-to-back/consecutive,
-- with no non-font drawing between them.
--
-- For example:
local font_ix = test.draw_font_start()
local x = 512
local y = 50
y = y + test.draw_font(font_ix, "lua test", x, y)
y = y + test.draw_font(font_ix, "cool", x, y)
-- note that "font_ix" is the current "best font" as calculated
-- from the current window size, and might change next frame if the
-- window is resized.
--
-- Any of this of course could be changed to match your precise
-- requirements.
----------------------------------------------------------------------
-- line drawing
----------------------------------------------------------------------
-- call "draw_line_quad_start()" prior to each "group" of
-- "draw_line()" or "draw_quad()" calls
--
-- a "group" of draw_line()/draw_quad() calls are
-- back-to-back/consecutive, with no non-line/quad drawing between
-- them.
--
-- For example:
test.draw_line_quad_start()
test.draw_set_color(1.0, 0.0, 0.0) -- r, g, b (0.0 to 1.0)
test.draw_line(0, 0, 1024, 1024) -- x1, y1, x2, y2
test.draw_line(700, 300, 400, 500)
test.draw_set_color(0.0, 1.0, 0.0)
test.draw_line(700, 300, 400, 700)
-- x1, y1, x2, y2,
-- x3, y3, x4, y4,
--
-- vertices must be specified In "counter clockwise" order, as in:
--
-- 2──1
-- │ │ valid (counter clockwise)
-- 3──4
--
-- these can also be rotated, as in:
--
-- 3
-- ╱ ╲
-- 4 2 valid (counter clockwise)
-- ╲ ╱
-- 1
--
-- however "mirroring" is not valid, as in:
--
-- 1──2
-- │ │ not valid (clockwise)
-- 4──3
--
test.draw_set_color(0.0, 0.0, 1.0)
test.draw_quad(
600, 600, -- top right
500, 600, -- top left
500, 700, -- bottom left
600, 700 -- bottom right
)
test.draw_set_color(0.0, 0.5, 1.0)
test.draw_quad(
900, 900, -- bottom
950, 850, -- right
900, 800, -- top
850, 850 -- left
)
-- If you want to draw a large number of lines or quads in bulk
-- (e.g: 10,000+ lines/quads per frame), this interface might not be good
-- enough, and we should discuss this in more detail.
end
function love.run()
init()
return function()
love.event.pump()
for name, a,b,c,d,e,f,g,h in love.event.poll() do
if name == "quit" then
if c or not love.quit or not love.quit() then
return a or 0, b
end
end
end
local width
local height
local flags
width, height, flags = love.window.getMode()
test.update_window(width, height)
local time = love.timer.getTime()
update(time)
draw()
local mouse_down = love.mouse.isDown(1)
if mouse_down then
local x, y = love.mouse.getPosition()
test.update_mouse(x, y)
end
--nico_draw()
love.graphics.present()
love.timer.sleep(0.001)
end
end
-- local wm = require("world_map")
-- world = {
-- ["top_down_race"] = require("love_src.src.world.top_down_race")(),
-- -- ["main_menu"] = require("love_src.src.world.main_menu")(),
-- -- ["1_intro"] = require("love_src.src.world.1_intro")(),
-- -- ["2_town_square"] = require("love_src.src.world.2_town_square")(),
-- -- ["race"] = require("love_src.src.world.race")(),
-- -- ["train"] = require("love_src.src.world.train")(),
-- };
-- current = wm["top_down_race"]
-- function load_world(world_to_load)
-- current = world_to_load
-- world[current]:reload()
-- end
-- local update = function(time)
-- for joystick_index, joystick in ipairs(joysticks) do
-- if joystick_index > 8 then
-- break
-- end
-- local lx = joystick:getGamepadAxis("leftx")
-- local ly = joystick:getGamepadAxis("lefty")
-- local rx = joystick:getGamepadAxis("rightx")
-- local ry = joystick:getGamepadAxis("righty")
-- local tl = joystick:getGamepadAxis("triggerleft")
-- local tr = joystick:getGamepadAxis("triggerright")
-- local up = joystick:isGamepadDown("dpup")
-- local down = joystick:isGamepadDown("dpdown")
-- local left = joystick:isGamepadDown("dpleft")
-- local right = joystick:isGamepadDown("dpright")
-- local a = joystick:isGamepadDown("a")
-- local b = joystick:isGamepadDown("b")
-- local x = joystick:isGamepadDown("x")
-- local y = joystick:isGamepadDown("y")
-- local leftshoulder = joystick:isGamepadDown("leftshoulder")
-- local rightshoulder = joystick:isGamepadDown("rightshoulder")
-- local start = joystick:isGamepadDown("start")
-- --print("start", i, start)
-- test.update_joystick(joystick_index - 1,
-- lx, ly, rx, ry, tl, tr,
-- up, down, left, right,
-- a, b, x, y,
-- leftshoulder, rightshoulder,
-- start)
-- end
-- local up = love.keyboard.isDown("up")
-- local down = love.keyboard.isDown("down")
-- local left = love.keyboard.isDown("left")
-- local right = love.keyboard.isDown("right")
-- local w = love.keyboard.isDown("w")
-- local s = love.keyboard.isDown("s")
-- local a = love.keyboard.isDown("a")
-- local d = love.keyboard.isDown("d")
-- local t = love.keyboard.isDown("t")
-- local g = love.keyboard.isDown("g")
-- local f = love.keyboard.isDown("f")
-- local h = love.keyboard.isDown("h")
-- local i = love.keyboard.isDown("i")
-- local k = love.keyboard.isDown("k")
-- local j = love.keyboard.isDown("j")
-- local l = love.keyboard.isDown("l")
-- test.update_keyboard(up, down, left, right,
-- w, s, a, d,
-- t, g, f, h,
-- i, k, j, l);
-- test.update(time)
-- function love.load()
-- world[current]:load()
-- end
-- local draw = function()
-- test.draw()
-- end
-- local nico_draw = function()
-- ----------------------------------------------------------------------
-- -- font drawing
-- ----------------------------------------------------------------------
-- -- call "draw_font_start()" prior each "group" of "draw_font()" calls
-- --
-- -- a "group" of draw_font() calls are back-to-back/consecutive,
-- -- with no non-font drawing between them.
-- --
-- -- For example:
-- local font_ix = test.draw_font_start()
-- local x = 512
-- local y = 50
-- y = y + test.draw_font(font_ix, "lua test", x, y)
-- y = y + test.draw_font(font_ix, "cool", x, y)
-- -- note that "font_ix" is the current "best font" as calculated
-- -- from the current window size, and might change next frame if the
-- -- window is resized.
-- --
-- -- Any of this of course could be changed to match your precise
-- -- requirements.
-- ----------------------------------------------------------------------
-- -- line drawing
-- ----------------------------------------------------------------------
-- -- call "draw_line_quad_start()" prior to each "group" of
-- -- "draw_line()" or "draw_quad()" calls
-- --
-- -- a "group" of draw_line()/draw_quad() calls are
-- -- back-to-back/consecutive, with no non-line/quad drawing between
-- -- them.
-- --
-- -- For example:
-- test.draw_line_quad_start()
-- test.draw_set_color(1.0, 0.0, 0.0) -- r, g, b (0.0 to 1.0)
-- test.draw_line(0, 0, 1024, 1024) -- x1, y1, x2, y2
-- test.draw_line(700, 300, 400, 500)
-- test.draw_set_color(0.0, 1.0, 0.0)
-- test.draw_line(700, 300, 400, 700)
-- -- x1, y1, x2, y2,
-- -- x3, y3, x4, y4,
-- --
-- -- vertices must be specified In "counter clockwise" order, as in:
-- --
-- -- 2──1
-- -- │ │ valid (counter clockwise)
-- -- 3──4
-- --
-- -- these can also be rotated, as in:
-- --
-- -- 3
-- -- ╱ ╲
-- -- 4 2 valid (counter clockwise)
-- -- ╲ ╱
-- -- 1
-- --
-- -- however "mirroring" is not valid, as in:
-- --
-- -- 1──2
-- -- │ │ not valid (clockwise)
-- -- 4──3
-- --
-- test.draw_set_color(0.0, 0.0, 1.0)
-- test.draw_quad(
-- 600, 600, -- top right
-- 500, 600, -- top left
-- 500, 700, -- bottom left
-- 600, 700 -- bottom right
-- )
-- test.draw_set_color(0.0, 0.5, 1.0)
-- test.draw_quad(
-- 900, 900, -- bottom
-- 950, 850, -- right
-- 900, 800, -- top
-- 850, 850 -- left
-- )
-- -- If you want to draw a large number of lines or quads in bulk
-- -- (e.g: 10,000+ lines/quads per frame), this interface might not be good
-- -- enough, and we should discuss this in more detail.
-- end
-- function love.run()
-- init()
-- return function()
-- love.event.pump()
-- for name, a,b,c,d,e,f,g,h in love.event.poll() do
-- if name == "quit" then
-- if c or not love.quit or not love.quit() then
-- return a or 0, b
-- end
-- end
-- end
-- local width
-- local height
-- local flags
-- width, height, flags = love.window.getMode()
-- test.update_window(width, height)
-- local time = love.timer.getTime()
-- update(time)
-- draw()
-- local mouse_down = love.mouse.isDown(1)
-- if mouse_down then
-- local x, y = love.mouse.getPosition()
-- test.update_mouse(x, y)
-- end
-- -- nico_draw()
-- love.graphics.present()
-- love.timer.sleep(0.001)
-- end
-- end
-- function love.load(args)
-- init()
-- local width, height, flags = love.window.getMode()
-- test.update_window(width, height)
-- end
-- function love.update(time)
-- update(time)
-- if (love.mouse.isDown(1)) then
-- local x, y = love.mouse.getPosition()
-- test.update_mouse(x, y)
-- end
-- function love.update(dt)
-- world[current]:update(dt)
-- end
-- function love.draw()
-- draw()
-- love.graphics.push()
-- love.graphics.setCanvas()
-- love.graphics.setShader()
-- love.graphics.line(0, 0, love.graphics.getDimensions())
-- love.graphics.pop()
-- world[current]:draw()
-- end
local wm = require("world_map")
-- function love.keyreleased(key, scancode)
-- world[current]:keyreleased(key, scancode)
-- end
world = {
["top_down_race"] = require("love_src.src.world.top_down_race")(),
-- ["main_menu"] = require("love_src.src.world.main_menu")(),
-- ["1_intro"] = require("love_src.src.world.1_intro")(),
-- ["2_town_square"] = require("love_src.src.world.2_town_square")(),
-- ["race"] = require("love_src.src.world.race")(),
-- ["train"] = require("love_src.src.world.train")(),
};
-- function love.keypressed(key, scancode, isrepeat)
-- world[current]:keypressed(key, scancode, isrepeat)
-- end
current = wm["top_down_race"]
function load_world(world_to_load)
current = world_to_load
world[current]:reload()
end
function love.load()
world[current]:load()
end
function love.update(dt)
world[current]:update(dt)
end
function love.draw()
world[current]:draw()
end
function love.keyreleased(key, scancode)
world[current]:keyreleased(key, scancode)
end
function love.keypressed(key, scancode, isrepeat)
world[current]:keypressed(key, scancode, isrepeat)
end
function love.mousereleased(x, y, button, istouch, presses)
world[current]:mousereleased(x, y, button, istouch, presses)
end
-- function love.mousereleased(x, y, button, istouch, presses)
-- world[current]:mousereleased(x, y, button, istouch, presses)
-- end

BIN
game/minecraft/flame.data Normal file

Binary file not shown.

View File

@ -113,8 +113,8 @@ def pack_instance_data(position, block_id, block_data, texture_id):
block_id, block_data, texture_id, special)
return packed
def pack_light_data(position, block_id):
packed = struct.pack("<ffff", position[0], position[1], position[2], block_id)
def pack_light_data(position, block_id, block_data):
packed = struct.pack("<ffff", position[0], position[1], position[2], block_data)
return packed
def build_block_instances(blocks):
@ -174,7 +174,7 @@ def build_block_instances(blocks):
with open(f"{data_path}.lights.vtx", "wb") as f:
for position, block_id, block_data in light_sources:
packed = pack_light_data(position, block_id)
packed = pack_light_data(position, block_id, block_data)
f.write(packed)
def level_table_from_path(level_table, path):

View File

@ -0,0 +1,24 @@
set -eux
#cd ./minecraft/gen
PYTHON=pypy3.11
CROP=-255,-255:382,382
ALL_REGIONS=../midnightmeadow/all_regions.txt
cat <<EOF > $ALL_REGIONS
$HOME/MidnightMeadow/region/r.0.0.mcr
$HOME/MidnightMeadow/region/r.-1.-1.mcr
$HOME/MidnightMeadow/region/r.0.-1.mcr
$HOME/MidnightMeadow/region/r.-1.0.mcr
EOF
$PYTHON mc.py $HOME/MidnightMeadow/region/r.0.0.mcr ../midnightmeadow/region.0.0 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/MidnightMeadow/region/r.-1.-1.mcr ../midnightmeadow/region.-1.-1 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/MidnightMeadow/region/r.0.-1.mcr ../midnightmeadow/region.0.-1 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/MidnightMeadow/region/r.-1.0.mcr ../midnightmeadow/region.-1.0 $ALL_REGIONS $CROP &
wait
cat ../midnightmeadow/region*.lights.vtx > ../midnightmeadow/global.lights.vtx
cat ../midnightmeadow/region*.dump > ../midnightmeadow/global.dump
$PYTHON intkeys.py ../midnightmeadow/global.dump | $HOME/nbperf/nbperf -n midnightmeadow_hash -I -a bpz -c 1.24 -m ../love2dworld/map.txt > ../midnightmeadow/inthash.c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
/home/bilbo/MidnightMeadow/region/r.0.0.mcr
/home/bilbo/MidnightMeadow/region/r.-1.-1.mcr
/home/bilbo/MidnightMeadow/region/r.0.-1.mcr
/home/bilbo/MidnightMeadow/region/r.-1.0.mcr

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

28
game/shader/flame.frag Normal file
View File

@ -0,0 +1,28 @@
#version 430 core
in vec4 PixelTexture;
layout (location = 0, binding = 0) uniform sampler2D FlameSampler;
layout (location = 1) uniform int Frame;
layout (location = 0) out vec3 Position;
layout (location = 1) out vec4 Normal;
layout (location = 2) out vec3 Color;
layout (location = 3) out vec4 Block;
const float frames = 1.0 / 4.0;
void main()
{
vec2 coord = vec2(PixelTexture.x, 1.0 - PixelTexture.y) * vec2(1, frames) + vec2(0, frames * Frame);
vec4 texture_color = texture(FlameSampler, coord);
if (texture_color.w == 0) {
discard;
return;
}
Position = vec3(0, 0, 0);
Normal = vec4(0, 0, 0, 0);
Color = vec3(texture_color.xyz);
Block = vec4(-1, -1, -1, -1);
}

42
game/shader/flame.vert Normal file
View File

@ -0,0 +1,42 @@
#version 430 core
layout (location = 2) uniform mat4 Transform;
layout (location = 3) uniform vec3 Eye;
const vec2 vtx[4] = vec2[](vec2(-1.0, 1.0), // tl
vec2( 1.0, 1.0), // tr
vec2( 1.0, -1.0), // br
vec2(-1.0, -1.0)); // bl
out vec4 PixelTexture;
const vec3 up = vec3(0, 0, 1);
layout (std140, binding = 0) uniform Lights
{
vec4 light[256];
};
void main()
{
vec2 vertex = vtx[gl_VertexID];
PixelTexture = vec4(vertex * 0.5 + 0.5, 0, 0);
vec4 light_instance = light[gl_InstanceID];
bool is_candle = light_instance.w == 5;
float z_offset = is_candle ? 0.17 : 0.5;
float y_offset = float(light_instance.w == 4) - float(light_instance.w == 3);
float x_offset = float(light_instance.w == 2) - float(light_instance.w == 1);
float size = is_candle ? 0.1 : 0.25;
vec3 global_position = light_instance.xzy + vec3(x_offset * 0.2, y_offset * 0.2, z_offset);
vec3 direction = global_position - Eye;
vec3 normal = normalize(vec3(direction.x, direction.y, 0));
vec3 right = normalize(cross(normal, up));
vec3 position = global_position + (vertex.x * right + vertex.y * up) * size;
gl_Position = Transform * vec4(position, 1);
}

View File

@ -1,29 +1,11 @@
#version 330 core
#version 430 core
const vec2 vtx[4] = vec2[](vec2(-1.0, 1.0), // tl
vec2( 1.0, 1.0), // tr
vec2( 1.0, -1.0), // br
vec2(-1.0, -1.0)); // bl
/*
tl tr
br
0 1 2
tr tl br
1 0 2
tl
bl br
2 1 3
br tl bl
2 0 3
1 0 2 3
*/
uniform mat4 Transform;
layout (location = 0) uniform mat4 Transform;
out vec4 PixelTexture;

View File

@ -0,0 +1,17 @@
#version 430 core
layout (location = 1) uniform vec2 TextureSize;
layout (location = 2) uniform vec4 WidthHeightXY;
layout (location = 3, binding = 0) uniform sampler2D TextureSampler;
out vec4 g_color;
in vec4 PixelTexture;
void main()
{
vec2 coord = (PixelTexture.xy * WidthHeightXY.xy + WidthHeightXY.zw) * TextureSize;
vec4 color = texture(TextureSampler, coord);
g_color = vec4(color.x);
}

View File

@ -25,21 +25,28 @@ void main()
vec4 color = texture(ColorSampler, PixelTexture.xy);
vec3 out_color = color.xyz * 0.1;
for (int i = 0; i < LightCount; i++) {
vec3 light_position = light[i].xzy + vec3(0, 0, 0.5);
float light_distance = length(light_position - position.xyz);
vec3 light_direction = normalize(light_position - position.xyz);
float diffuse = max(dot(normal.xyz, light_direction), 0.0);
if (normal.w == 1.0) // two-sided
diffuse = 1.0;
//float attenuation = 1.0 / (1.0 + Linear * light_distance + Quadratic * light_distance * light_distance);
float attenuation = 1.0 / (1.0 + Quadratic * light_distance * light_distance);
out_color += color.xyz * attenuation * diffuse;
if (false) {
for (int i = 0; i < LightCount; i++) {
vec3 light_position = light[i].xzy + vec3(0, 0, 0.5);
float light_distance = length(light_position - position.xyz);
vec3 light_direction = normalize(light_position - position.xyz);
float diffuse = max(dot(normal.xyz, light_direction), 0.0);
if (normal.w == 1.0) // two-sided
diffuse = 1.0;
//float attenuation = 1.0 / (1.0 + Linear * light_distance + Quadratic * light_distance * light_distance);
float attenuation = 1.0 / (1.0 + Quadratic * light_distance * light_distance);
out_color += color.xyz * attenuation * diffuse;
}
} else {
vec3 light_direction = normalize(Eye.xyz - position.xyz);
float diffuse = max(dot(normal.xyz, light_direction), 0.0);
out_color += color.xyz * diffuse;
}
//vec3 light_direction = normalize(Eye.xyz - position.xyz);
//float diffuse = max(dot(normal.xyz, light_direction), 0.0);
if (normal == vec4(0, 0, 0, 0))
out_color = color.xyz;
Color = vec4(out_color, 1.0);
}

View File

@ -46,7 +46,7 @@ void main()
vs_out.Position = position;
vs_out.BlockPosition = BlockPosition;
vs_out.Normal = Normal;
vs_out.Normal = orientation(Normal);
vs_out.Texture = Texture;
vs_out.BlockID = BlockID;
vs_out.Data = Data;

106
game/src/flame.cpp Normal file
View File

@ -0,0 +1,106 @@
#include <assert.h>
#include <stdlib.h>
#include "glad/gl.h"
#include "file.h"
#include "opengl.h"
#include "flame.h"
#include "view.h"
extern unsigned int quad_index_buffer;
extern unsigned int empty_vertex_array_object;
namespace flame {
static unsigned int program;
static unsigned int flame_texture;
static unsigned int vertex_array_object;
const int per_instance_size = 4 * (sizeof (float));
struct layout {
struct {
unsigned int flame_sampler;
unsigned int frame;
unsigned int transform;
unsigned int eye;
} uniform;
struct {
unsigned int lights;
} binding;
};
layout layout = {
.uniform = {
.flame_sampler = 0,
.frame = 1,
.transform = 2,
.eye = 3,
},
.binding = {
.lights = 0,
},
};
void load_program()
{
program = compile_from_files("shader/flame.vert",
nullptr,
"shader/flame.frag");
}
void load_texture()
{
unsigned int texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int texture_data_size;
void * texture_data = read_file("minecraft/flame.data", &texture_data_size);
assert(texture_data != nullptr);
int width = 16;
int height = 80;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
free(texture_data);
glBindTexture(GL_TEXTURE_2D, 0);
flame_texture = texture;
}
static int frame = 0;
void draw(unsigned int light_uniform_buffer, int light_count)
{
glUseProgram(program);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, flame_texture);
glUniform1i(layout.uniform.frame, (frame / 20) % 4);
frame++;
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&view::state.float_transform);
XMFLOAT3 eye;
XMStoreFloat3(&eye, view::state.eye);
glUniform3fv(layout.uniform.eye, 1, (float *)&eye);
glBindBufferBase(GL_UNIFORM_BUFFER, layout.binding.lights, light_uniform_buffer);
glBindVertexArray(empty_vertex_array_object);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0, light_count);
}
}

169
game/src/font/bitmap.cpp Normal file
View File

@ -0,0 +1,169 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "directxmath/directxmath.h"
#include "glad/gl.h"
#include "opengl.h"
#include "file.h"
#include "font/bitmap.h"
#include "window.h"
namespace font::bitmap {
struct location {
struct {
unsigned int transform;
unsigned int texture_sampler;
unsigned int cell;
unsigned int glyph;
} uniform;
};
static location location;
static unsigned int font_program = -1;
void load_shader()
{
unsigned int program = compile_from_files("shader/font.vert",
NULL, // geom
"shader/font.frag");
location.uniform.transform = glGetUniformLocation(program, "Transform");
location.uniform.texture_sampler = glGetUniformLocation(program, "TextureSampler");
location.uniform.cell = glGetUniformLocation(program, "Cell");
location.uniform.glyph = glGetUniformLocation(program, "Glyph");
printf("font program:\n");
printf(" uniforms:\n transform %u\n texture_sampler %u\n cell %u\n glyph %u\n",
location.uniform.transform,
location.uniform.texture_sampler,
location.uniform.cell,
location.uniform.glyph
);
font_program = program;
}
static inline font load_font(font_desc const& desc)
{
unsigned int texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int texture_data_size;
void * texture_data = read_file(desc.path, &texture_data_size);
assert(texture_data != nullptr);
int width = desc.texture_width;
int height = desc.texture_height;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, texture_data);
free(texture_data);
glBindTexture(GL_TEXTURE_2D, 0);
return (font){
.desc = &desc,
.texture = texture,
.stride = desc.texture_width / desc.glyph_width,
.cell = { (float)desc.glyph_width / (float)desc.texture_width,
(float)desc.glyph_height / (float)desc.texture_height },
};
}
static inline int min(int a, int b)
{
return a < b ? a : b;
}
int best_font(font_desc const * const descs, int length)
{
int dimension = min(window::width, window::height);
int ideal_height = (16 * dimension) / 1024;
//printf("ideal_height: %d\n", ideal_height);
int nearest = dimension;
int nearest_ix = -1;
for (int i = 0; i < length; i++) {
font_desc const& desc = descs[i];
int distance = abs(desc.glyph_height - ideal_height);
if (distance < nearest) {
nearest = distance;
nearest_ix = i;
}
}
assert(nearest_ix != -1);
//printf("selected %d\n", descs[nearest_ix].glyph_height);
return nearest_ix;
}
void load_fonts(font * const fonts, font_desc const * const descs, int length)
{
for (int i = 0; i < length; i++) {
fonts[i] = load_font(descs[i]);
}
}
inline static XMFLOAT2 glyph_coordinate(font const& font, int ord)
{
int c = ord - 32;
int x = c % font.stride;
int y = c / font.stride;
XMVECTOR coord = XMVectorSet(x, y, 0, 0);
XMFLOAT2 coordf;
XMStoreFloat2(&coordf, coord);
return coordf;
}
inline static XMFLOAT4X4 glyph_transform(font const& font, int x, int y)
{
XMMATRIX transform
= XMMatrixScaling(font.desc->glyph_width, font.desc->glyph_height, 0)
* XMMatrixTranslation(x, -y, 0)
* XMMatrixScaling(2.0f / window::width, 2.0f / window::height, 0)
* XMMatrixTranslation(-1, 1, 0);
XMFLOAT4X4 transformf;
XMStoreFloat4x4(&transformf, transform);
return transformf;
}
void draw_start(font const& font, unsigned int vertex_array_object, unsigned int index_buffer)
{
glUseProgram(font_program);
glDepthFunc(GL_ALWAYS);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, font.texture);
glUniform1i(location.uniform.texture_sampler, 0);
glUniform2fv(location.uniform.cell, 1, (float *)&font.cell);
glBindVertexArray(vertex_array_object);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
}
int draw_string(font const& font, char const * const s, int x, int y)
{
int i = 0;
while (s[i] != 0) {
char c = s[i++];
if (!(c <= 0x20 || c > 0x7f)) {
XMFLOAT4X4 transform = glyph_transform(font, x, y);
glUniformMatrix4fv(location.uniform.transform, 1, GL_FALSE, (float *)&transform);
XMFLOAT2 glyph = glyph_coordinate(font, c);
glUniform2fv(location.uniform.glyph, 1, (float *)&glyph);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
}
x += font.desc->glyph_width;
}
return x;
}
}

150
game/src/font/outline.cpp Normal file
View File

@ -0,0 +1,150 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "directxmath/directxmath.h"
#include "glad/gl.h"
#include "opengl.h"
#include "file.h"
#include "font/outline.h"
#include "font/outline_types.h"
#include "window.h"
namespace font::outline {
struct layout {
struct {
unsigned int transform;
unsigned int texture_size;
unsigned int width_height_xy;
unsigned int texture_sampler;
} uniform;
};
static layout const layout = {
.uniform = {
.transform = 0,
.texture_size = 1,
.width_height_xy = 2,
.texture_sampler = 3,
}
};
static unsigned int font_program = -1;
void load_shader()
{
unsigned int program = compile_from_files("shader/font.vert",
NULL, // geom
"shader/font_outline.frag");
font_program = program;
}
static inline font load_font(font_desc const& desc)
{
int font_data_size;
void * font_data = read_file(desc.path, &font_data_size);
assert(font_data != nullptr);
types::font * font = (types::font *)font_data;
types::glyph * glyphs = (types::glyph *)(((ptrdiff_t)font_data) + (sizeof (types::font)));
void * texture_data = (void *)(((ptrdiff_t)glyphs) + (sizeof (types::glyph)) * font->glyph_count);
ptrdiff_t font_end = ((ptrdiff_t)font_data) + font_data_size;
int texture_size = font->texture_width * font->texture_height;
assert(font_end - ((ptrdiff_t)texture_data) == texture_size);
unsigned int texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int width = font->texture_width;
int height = font->texture_height;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, texture_data);
glBindTexture(GL_TEXTURE_2D, 0);
return (outline::font){
.texture = texture,
.font = font,
.glyphs = glyphs,
};
}
void load_fonts(font * const fonts, font_desc const * const descs, int length)
{
for (int i = 0; i < length; i++) {
fonts[i] = load_font(descs[i]);
}
}
void draw_start(font const& font, unsigned int vertex_array_object, unsigned int index_buffer)
{
glUseProgram(font_program);
glDepthFunc(GL_ALWAYS);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, font.texture);
glBindVertexArray(vertex_array_object);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
XMFLOAT2 texture_size = {1.0f / font.font->texture_width, 1.0f / font.font->texture_height};
glUniform2fv(layout.uniform.texture_size, 1, (float *)&texture_size);
}
inline static XMFLOAT4X4 glyph_transform(float width, float height, float x, float y)
{
XMMATRIX transform
= XMMatrixScaling(width, height, 0)
* XMMatrixTranslation(x, -y, 0)
* XMMatrixScaling(2.0f / window::width, 2.0f / window::height, 0)
* XMMatrixTranslation(-1, 1, 0);
XMFLOAT4X4 transformf;
XMStoreFloat4x4(&transformf, transform);
return transformf;
}
int draw_string(font const& font, char const * const s, int x, int y)
{
int advance = 0;
const float fp = 1.0f / 64.0f;
int i = 0;
while (s[i] != 0) {
char c = s[i++];
if (!(c >= 0x20 && c <= 0x7f))
continue;
types::glyph const & glyph = font.glyphs[c - 0x20];
if (c > 0x20 && c <= 0x7f) {
XMFLOAT4 width_height_xy = {
(float)glyph.bitmap.width, (float)glyph.bitmap.height,
(float)glyph.bitmap.x, (float)glyph.bitmap.y,
};
XMFLOAT4X4 transform = glyph_transform(glyph.bitmap.width, glyph.bitmap.height,
x + ((float)(advance + glyph.metrics.horiBearingX) * fp),
y - ((float)(glyph.metrics.horiBearingY) * fp));
glUniform4fv(layout.uniform.width_height_xy, 1, (float *)&width_height_xy);
glUniformMatrix4fv(layout.uniform.transform, 1, GL_FALSE, (float *)&transform);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
}
advance += glyph.metrics.horiAdvance;
}
return x + (advance >> 6);
}
}

View File

@ -3,19 +3,18 @@
#include "directxmath/directxmath.h"
#include "font.h"
#include "font/bitmap.h"
#include "view.h"
extern font::font * terminus_fonts;
extern font::bitmap::font * terminus_fonts;
extern unsigned int empty_vertex_array_object;
extern unsigned int quad_index_buffer;
extern float current_time;
extern float last_frame_time;
// depends on:
// - font::load
// - font::bitmap::load
// - load_quad_program
// - load_quad_index_buffer
// - empty_vertex_array_object
@ -34,10 +33,10 @@ namespace hud {
buf[label_length + len] = 0;
}
inline static float draw_vector(font::font const& ter_best, char * const buf, float y, char const * const label, XMVECTOR vec)
inline static float draw_vector(font::bitmap::font const& ter_best, char * const buf, float y, char const * const label, XMVECTOR vec)
{
labeled_value<float>(buf, label, ": %5.2f %5.2f %5.2f %5.2f", XMVectorGetX(vec), XMVectorGetY(vec), XMVectorGetZ(vec), XMVectorGetW(vec));
font::draw_string(ter_best, buf, 10, y);
font::bitmap::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
return y;
}
@ -73,48 +72,42 @@ namespace hud {
return rolling_sum * (1.0f / 16.0f);
}
template <typename T, typename... Args>
static float draw_label(font::bitmap::font const& font, char * buf, float x, float y, char const * const label, char const * const format, Args... args)
{
labeled_value<T>(buf, label, format, args...);
font::bitmap::draw_string(font, buf, x, y);
return y + font.desc->glyph_height;
}
void draw()
{
char buf[512];
static char buf[512];
float y = 10.0f;
int font_ix = font::best_font(font::terminus, font::terminus_length);
font::font const& ter_best = terminus_fonts[font_ix];
font::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
int font_ix = font::bitmap::best_font(font::bitmap::terminus, font::bitmap::terminus_length);
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
font::bitmap::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
labeled_value<float>(buf, "fov: ", "%.3f", view::state.fov);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<int>(buf, "font_height: ", "%d", ter_best.desc->glyph_height);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
y = draw_label<float>(ter_best, buf, 10, y, "fov: ", "%.3f", view::state.fov);
y = draw_label<int>(ter_best, buf, 10, y, "font_height: ", "%d", ter_best.desc->glyph_height);
/*
labeled_value<float>(buf, "lighting.quadratic: ", "%.2f", lighting.quadratic);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<float>(buf, "lighting.linear: ", "%.2f", lighting.linear);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
y = draw_label<float>(ter_best, buf, 10, y, "lighting.quadratic: ", "%.2f", lighting.quadratic);
y = draw_label<float>(ter_best, buf, 10, y, "lighting.linear: ", "%.2f", lighting.linear);
*/
y = draw_vector(ter_best, buf, y, "eye", view::state.eye);
y = draw_vector(ter_best, buf, y, "at", view::state.at);
y = draw_vector(ter_best, buf, y, "forward", view::state.forward);
y = draw_vector(ter_best, buf, y, "eye", XMVectorSetW(view::state.eye, 0));
y = draw_vector(ter_best, buf, y, "at", XMVectorSetW(view::state.at, 0));
y = draw_vector(ter_best, buf, y, "forward", XMVectorSetW(view::state.forward, 0));
labeled_value<float>(buf, "pitch: ", "%.4f", view::state.pitch);
font::draw_string(ter_best, buf, 10, y);
y = draw_label<float>(ter_best, buf, 10, y, "pitch: ", "%.4f", view::state.pitch);
y = draw_label<float>(ter_best, buf, 10, y, "frame_rate_avg: ", "%.2f", 1.0f / update_average(current_time - last_frame_time));
font::bitmap::draw_string(ter_best, "mouse:", 10, y);
y += ter_best.desc->glyph_height;
labeled_value<float>(buf, "frame_rate_avg: ", "%.2f", 1.0f / update_average(current_time - last_frame_time));
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
font::draw_string(ter_best, "mouse:", 10, y);
y += ter_best.desc->glyph_height;
y = draw_vector(ter_best, buf, y, " position", XMLoadFloat4((XMFLOAT4*)mouse_position));
y = draw_vector(ter_best, buf, y, " block", XMLoadFloat4((XMFLOAT4*)mouse_block));
}

View File

@ -1,24 +1,24 @@
#include "font.h"
#include "font/bitmap.h"
#include "pixel_line_art.h"
#include "lua_api.h"
extern font::font * terminus_fonts;
extern font::bitmap::font * terminus_fonts;
extern unsigned int empty_vertex_array_object;
extern unsigned int quad_index_buffer;
int draw_font_start()
{
int font_ix = font::best_font(font::terminus, font::terminus_length);
font::font const& ter_best = terminus_fonts[font_ix];
font::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
int font_ix = font::bitmap::best_font(font::bitmap::terminus, font::bitmap::terminus_length);
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
font::bitmap::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
return font_ix;
}
int draw_font(int font_ix, char const * text, int x, int y)
{
font::font const& ter_best = terminus_fonts[font_ix];
font::draw_string(ter_best, text, x, y);
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
font::bitmap::draw_string(ter_best, text, x, y);
return ter_best.desc->glyph_height;
}

View File

@ -44,7 +44,7 @@ namespace minecraft {
static unsigned int texture;
static const int world_count = 2;
static const int world_count = 3;
static world::state world_state[world_count];
world::state * current_world;
@ -269,7 +269,7 @@ namespace minecraft {
continue;
per_world::load_world(&world::descriptors[i], world_state[i]);
}
current_world = &world_state[world::world_id::GRANDLECTURN];
current_world = &world_state[world::world_id::MIDNIGHTMEADOW];
}
static inline int popcount(int x)

View File

@ -7,7 +7,8 @@
#include "opengl.h"
#include "directxmath/directxmath.h"
#include "test.h"
#include "font.h"
#include "font/bitmap.h"
#include "font/outline.h"
#include "window.h"
#include "bresenham.h"
#include "file.h"
@ -25,6 +26,8 @@
#include "collada/types.h"
#include "collada/instance_types.h"
#include "pixel_line_art.h"
#include "flame.h"
#include "new.h"
#include "world/entry_table.h"
#include "world/world.h"
@ -66,7 +69,8 @@ unsigned int quad_index_buffer = -1;
float current_time;
float last_frame_time;
font::font * terminus_fonts;
font::bitmap::font * terminus_fonts;
font::outline::font * uncial_antiqua_fonts;
geometry_buffer<4> geometry_buffer_pnc = {};
static target_type const geometry_buffer_pnc_types[4] = {
@ -141,10 +145,13 @@ void load(const char * source_path)
// font
//////////////////////////////////////////////////////////////////////
font::load_shader();
font::bitmap::load_shader();
terminus_fonts = New<font::bitmap::font>(font::bitmap::terminus_length);
font::bitmap::load_fonts(terminus_fonts, font::bitmap::terminus, font::bitmap::terminus_length);
terminus_fonts = (font::font *)malloc((sizeof (font::font)) * font::terminus_length);
font::load_fonts(terminus_fonts, font::terminus, font::terminus_length);
font::outline::load_shader();
uncial_antiqua_fonts = New<font::outline::font>(font::outline::uncial_antiqua_length);
font::outline::load_fonts(uncial_antiqua_fonts, font::outline::uncial_antiqua, font::outline::uncial_antiqua_length);
//////////////////////////////////////////////////////////////////////
// pixel_line_art
@ -195,6 +202,13 @@ void load(const char * source_path)
//node_at = scene_state.find_node_by_name("Camera001.Target");
//assert(node_at != nullptr);
//////////////////////////////////////////////////////////////////////
// flame
//////////////////////////////////////////////////////////////////////
flame::load_program();
flame::load_texture();
}
void update_keyboard(int up, int down, int left, int right,
@ -418,17 +432,24 @@ void draw()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
minecraft::draw();
//draw_line();
non_block::draw();
flame::draw(minecraft::current_world->light_uniform_buffer,
minecraft::current_world->light_count);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
lighting::draw(minecraft::current_world->light_uniform_buffer,
minecraft::current_world->light_count);
//draw_quad();
hud::draw();
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//font::outline::draw_start(uncial_antiqua_fonts[0], empty_vertex_array_object, quad_index_buffer);
//font::outline::draw_string(uncial_antiqua_fonts[0], "test", 150, 500);
} else {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

View File

@ -97,14 +97,19 @@ namespace view {
state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
state.fov = 1.5;
state.pitch = -0.7;
state.pitch = -0.5520;
state.forward = XMVector3Normalize(XMVectorSet(-0.64, 0.77, 0, 0));
state.forward = XMVector3Normalize(XMVectorSet(0.66, -0.75, 0, 0));
state.normal = get_normal(); // on forward change
state.direction = get_direction(); // on forward/normal/pitch change
// position
state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1);
// grandlecturn
//state.eye = XMVectorSet(4.71f, 65.30, 57.92, 1);
// midnightmeadow
state.eye = XMVectorSet(13.71f, -3.36, 90.92, 1);
state.at = state.eye + state.direction * at_distance;
//state.at = XMVectorSet(0, 0, 0, 1);
//state.eye = XMVectorSet(0, -100, 0, 1);

View File

@ -16,6 +16,13 @@ namespace world {
{ "minecraft/grandlecturn/region.-1.-1.instance.vtx", "minecraft/grandlecturn/region.-1.-1.instance.cfg" },
};
static vtx_cfg const midnightmeadow_vertex_paths[] = {
{ "minecraft/midnightmeadow/region.0.0.instance.vtx", "minecraft/midnightmeadow/region.0.0.instance.cfg" },
{ "minecraft/midnightmeadow/region.-1.0.instance.vtx", "minecraft/midnightmeadow/region.-1.0.instance.cfg" },
{ "minecraft/midnightmeadow/region.0.-1.instance.vtx", "minecraft/midnightmeadow/region.0.-1.instance.cfg" },
{ "minecraft/midnightmeadow/region.-1.-1.instance.vtx", "minecraft/midnightmeadow/region.-1.-1.instance.cfg" },
};
descriptor const descriptors[] = {
[world_id::LOVE2DWORLD] = {
.region_count = 4,
@ -31,6 +38,13 @@ namespace world {
.lights_path = "minecraft/grandlecturn/global.lights.vtx",
.hash_func = grandlecturn_hash,
},
[world_id::MIDNIGHTMEADOW] = {
.region_count = 4,
.vertex_paths = midnightmeadow_vertex_paths,
.entry_table_path = "minecraft/midnightmeadow/global.dump",
.lights_path = "minecraft/midnightmeadow/global.lights.vtx",
.hash_func = midnightmeadow_hash,
},
};
int const descriptors_length = (sizeof (descriptors)) / (sizeof (descriptors[0]));
}