update love-demo2 code to latest version
This commit is contained in:
parent
da9030fa90
commit
045f2707f7
@ -20,6 +20,7 @@ LDFLAGS += $(shell pkg-config --libs glfw3)
|
|||||||
MINECRAFT_OBJS = \
|
MINECRAFT_OBJS = \
|
||||||
minecraft/love2dworld/inthash.o \
|
minecraft/love2dworld/inthash.o \
|
||||||
minecraft/grandlecturn/inthash.o \
|
minecraft/grandlecturn/inthash.o \
|
||||||
|
minecraft/midnightmeadow/inthash.o \
|
||||||
src/minecraft.o \
|
src/minecraft.o \
|
||||||
src/world/world.o \
|
src/world/world.o \
|
||||||
src/world/entry_table.o
|
src/world/entry_table.o
|
||||||
@ -28,7 +29,8 @@ OBJS = \
|
|||||||
src/gl.o \
|
src/gl.o \
|
||||||
src/opengl.o \
|
src/opengl.o \
|
||||||
src/test.o \
|
src/test.o \
|
||||||
src/font.o \
|
src/font/bitmap.o \
|
||||||
|
src/font/outline.o \
|
||||||
src/window.o \
|
src/window.o \
|
||||||
src/bresenham.o \
|
src/bresenham.o \
|
||||||
src/file.o \
|
src/file.o \
|
||||||
@ -47,6 +49,7 @@ OBJS = \
|
|||||||
src/collada/animate.o \
|
src/collada/animate.o \
|
||||||
src/lua_api.o \
|
src/lua_api.o \
|
||||||
src/pixel_line_art.o \
|
src/pixel_line_art.o \
|
||||||
|
src/flame.o \
|
||||||
data/scenes/ship20/ship20.o \
|
data/scenes/ship20/ship20.o \
|
||||||
data/scenes/noodle/noodle.o \
|
data/scenes/noodle/noodle.o \
|
||||||
data/scenes/shadow_test/shadow_test.o \
|
data/scenes/shadow_test/shadow_test.o \
|
||||||
|
|||||||
BIN
game/font/bitmap/terminus_128x128_8x16.data
Normal file
BIN
game/font/bitmap/terminus_128x128_8x16.data
Normal file
Binary file not shown.
BIN
game/font/bitmap/terminus_128x64_6x12.data
Normal file
BIN
game/font/bitmap/terminus_128x64_6x12.data
Normal file
Binary file not shown.
BIN
game/font/bitmap/terminus_256x128_10x18.data
Normal file
BIN
game/font/bitmap/terminus_256x128_10x18.data
Normal file
Binary file not shown.
BIN
game/font/bitmap/terminus_256x128_12x24.data
Normal file
BIN
game/font/bitmap/terminus_256x128_12x24.data
Normal file
Binary file not shown.
BIN
game/font/bitmap/terminus_256x256_16x32.data
Normal file
BIN
game/font/bitmap/terminus_256x256_16x32.data
Normal file
Binary file not shown.
BIN
game/font/outline/uncial_antiqua_36.data
Normal file
BIN
game/font/outline/uncial_antiqua_36.data
Normal file
Binary file not shown.
7
game/include/flame.h
Normal file
7
game/include/flame.h
Normal 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);
|
||||||
|
}
|
||||||
67
game/include/font/bitmap.h
Normal file
67
game/include/font/bitmap.h
Normal 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);
|
||||||
|
}
|
||||||
29
game/include/font/outline.h
Normal file
29
game/include/font/outline.h
Normal 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);
|
||||||
|
}
|
||||||
49
game/include/font/outline_types.h
Normal file
49
game/include/font/outline_types.h
Normal 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));
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
namespace view {
|
namespace view {
|
||||||
struct view_state {
|
struct view_state {
|
||||||
// positions
|
// positions
|
||||||
|
|||||||
@ -8,6 +8,7 @@ extern "C" {
|
|||||||
|
|
||||||
uint32_t love2dworld_hash(const int32_t key);
|
uint32_t love2dworld_hash(const int32_t key);
|
||||||
uint32_t grandlecturn_hash(const int32_t key);
|
uint32_t grandlecturn_hash(const int32_t key);
|
||||||
|
uint32_t midnightmeadow_hash(const int32_t key);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ namespace world {
|
|||||||
enum {
|
enum {
|
||||||
LOVE2DWORLD = 0,
|
LOVE2DWORLD = 0,
|
||||||
GRANDLECTURN = 1,
|
GRANDLECTURN = 1,
|
||||||
|
MIDNIGHTMEADOW = 2,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
532
game/main.lua
532
game/main.lua
@ -1,291 +1,265 @@
|
|||||||
-- local ffi = require 'ffi'
|
local ffi = require 'ffi'
|
||||||
-- local joysticks
|
local joysticks
|
||||||
|
|
||||||
-- function init()
|
function init()
|
||||||
-- joysticks = love.joystick.getJoysticks()
|
joysticks = love.joystick.getJoysticks()
|
||||||
-- for i, joystick in ipairs(joysticks) do
|
for i, joystick in ipairs(joysticks) do
|
||||||
-- print(i, joystick:getName())
|
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);
|
||||||
|
|
||||||
|
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)
|
||||||
|
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
|
-- end
|
||||||
|
|
||||||
-- ffi.cdef[[
|
-- function love.load()
|
||||||
-- void load(const char * source_path);
|
-- world[current]:load()
|
||||||
-- 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);
|
|
||||||
|
|
||||||
-- 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
|
-- end
|
||||||
|
|
||||||
-- local update = function(time)
|
-- function love.update(dt)
|
||||||
-- for joystick_index, joystick in ipairs(joysticks) do
|
-- world[current]:update(dt)
|
||||||
-- 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
|
|
||||||
|
|
||||||
-- 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
|
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- function love.draw()
|
-- function love.draw()
|
||||||
-- draw()
|
-- world[current]:draw()
|
||||||
-- love.graphics.push()
|
|
||||||
|
|
||||||
-- love.graphics.setCanvas()
|
|
||||||
-- love.graphics.setShader()
|
|
||||||
-- love.graphics.line(0, 0, love.graphics.getDimensions())
|
|
||||||
-- love.graphics.pop()
|
|
||||||
|
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
local wm = require("world_map")
|
-- function love.keyreleased(key, scancode)
|
||||||
|
-- world[current]:keyreleased(key, scancode)
|
||||||
|
-- end
|
||||||
|
|
||||||
world = {
|
-- function love.keypressed(key, scancode, isrepeat)
|
||||||
["top_down_race"] = require("love_src.src.world.top_down_race")(),
|
-- world[current]:keypressed(key, scancode, isrepeat)
|
||||||
-- ["main_menu"] = require("love_src.src.world.main_menu")(),
|
-- end
|
||||||
-- ["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 love.mousereleased(x, y, button, istouch, presses)
|
||||||
|
-- world[current]:mousereleased(x, y, button, istouch, presses)
|
||||||
function load_world(world_to_load)
|
-- end
|
||||||
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
|
|
||||||
|
|||||||
BIN
game/minecraft/flame.data
Normal file
BIN
game/minecraft/flame.data
Normal file
Binary file not shown.
@ -113,8 +113,8 @@ def pack_instance_data(position, block_id, block_data, texture_id):
|
|||||||
block_id, block_data, texture_id, special)
|
block_id, block_data, texture_id, special)
|
||||||
return packed
|
return packed
|
||||||
|
|
||||||
def pack_light_data(position, block_id):
|
def pack_light_data(position, block_id, block_data):
|
||||||
packed = struct.pack("<ffff", position[0], position[1], position[2], block_id)
|
packed = struct.pack("<ffff", position[0], position[1], position[2], block_data)
|
||||||
return packed
|
return packed
|
||||||
|
|
||||||
def build_block_instances(blocks):
|
def build_block_instances(blocks):
|
||||||
@ -174,7 +174,7 @@ def build_block_instances(blocks):
|
|||||||
|
|
||||||
with open(f"{data_path}.lights.vtx", "wb") as f:
|
with open(f"{data_path}.lights.vtx", "wb") as f:
|
||||||
for position, block_id, block_data in light_sources:
|
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)
|
f.write(packed)
|
||||||
|
|
||||||
def level_table_from_path(level_table, path):
|
def level_table_from_path(level_table, path):
|
||||||
|
|||||||
24
game/minecraft/gen/midnightmeadow.sh
Normal file
24
game/minecraft/gen/midnightmeadow.sh
Normal 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
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
4
game/minecraft/midnightmeadow/all_regions.txt
Normal file
4
game/minecraft/midnightmeadow/all_regions.txt
Normal 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
|
||||||
BIN
game/minecraft/midnightmeadow/global.dump
Normal file
BIN
game/minecraft/midnightmeadow/global.dump
Normal file
Binary file not shown.
0
game/minecraft/midnightmeadow/global.lights.vtx
Normal file
0
game/minecraft/midnightmeadow/global.lights.vtx
Normal file
26761
game/minecraft/midnightmeadow/inthash.c
Normal file
26761
game/minecraft/midnightmeadow/inthash.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
game/minecraft/midnightmeadow/region.-1.-1.dump
Normal file
BIN
game/minecraft/midnightmeadow/region.-1.-1.dump
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.-1.-1.instance.cfg
Normal file
BIN
game/minecraft/midnightmeadow/region.-1.-1.instance.cfg
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.-1.-1.instance.vtx
Normal file
BIN
game/minecraft/midnightmeadow/region.-1.-1.instance.vtx
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.-1.0.dump
Normal file
BIN
game/minecraft/midnightmeadow/region.-1.0.dump
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.-1.0.instance.cfg
Normal file
BIN
game/minecraft/midnightmeadow/region.-1.0.instance.cfg
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.-1.0.instance.vtx
Normal file
BIN
game/minecraft/midnightmeadow/region.-1.0.instance.vtx
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.0.-1.dump
Normal file
BIN
game/minecraft/midnightmeadow/region.0.-1.dump
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.0.-1.instance.cfg
Normal file
BIN
game/minecraft/midnightmeadow/region.0.-1.instance.cfg
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.0.-1.instance.vtx
Normal file
BIN
game/minecraft/midnightmeadow/region.0.-1.instance.vtx
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.0.0.dump
Normal file
BIN
game/minecraft/midnightmeadow/region.0.0.dump
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.0.0.instance.cfg
Normal file
BIN
game/minecraft/midnightmeadow/region.0.0.instance.cfg
Normal file
Binary file not shown.
BIN
game/minecraft/midnightmeadow/region.0.0.instance.vtx
Normal file
BIN
game/minecraft/midnightmeadow/region.0.0.instance.vtx
Normal file
Binary file not shown.
0
game/minecraft/midnightmeadow/region.0.0.lights.vtx
Normal file
0
game/minecraft/midnightmeadow/region.0.0.lights.vtx
Normal file
28
game/shader/flame.frag
Normal file
28
game/shader/flame.frag
Normal 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
42
game/shader/flame.vert
Normal 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);
|
||||||
|
}
|
||||||
@ -1,29 +1,11 @@
|
|||||||
#version 330 core
|
#version 430 core
|
||||||
|
|
||||||
const vec2 vtx[4] = vec2[](vec2(-1.0, 1.0), // tl
|
const vec2 vtx[4] = vec2[](vec2(-1.0, 1.0), // tl
|
||||||
vec2( 1.0, 1.0), // tr
|
vec2( 1.0, 1.0), // tr
|
||||||
vec2( 1.0, -1.0), // br
|
vec2( 1.0, -1.0), // br
|
||||||
vec2(-1.0, -1.0)); // bl
|
vec2(-1.0, -1.0)); // bl
|
||||||
|
|
||||||
/*
|
layout (location = 0) uniform mat4 Transform;
|
||||||
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;
|
|
||||||
|
|
||||||
out vec4 PixelTexture;
|
out vec4 PixelTexture;
|
||||||
|
|
||||||
|
|||||||
17
game/shader/font_outline.frag
Normal file
17
game/shader/font_outline.frag
Normal 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);
|
||||||
|
}
|
||||||
@ -25,6 +25,8 @@ void main()
|
|||||||
vec4 color = texture(ColorSampler, PixelTexture.xy);
|
vec4 color = texture(ColorSampler, PixelTexture.xy);
|
||||||
|
|
||||||
vec3 out_color = color.xyz * 0.1;
|
vec3 out_color = color.xyz * 0.1;
|
||||||
|
|
||||||
|
if (false) {
|
||||||
for (int i = 0; i < LightCount; i++) {
|
for (int i = 0; i < LightCount; i++) {
|
||||||
vec3 light_position = light[i].xzy + vec3(0, 0, 0.5);
|
vec3 light_position = light[i].xzy + vec3(0, 0, 0.5);
|
||||||
float light_distance = length(light_position - position.xyz);
|
float light_distance = length(light_position - position.xyz);
|
||||||
@ -37,9 +39,14 @@ void main()
|
|||||||
float attenuation = 1.0 / (1.0 + Quadratic * light_distance * light_distance);
|
float attenuation = 1.0 / (1.0 + Quadratic * light_distance * light_distance);
|
||||||
out_color += color.xyz * attenuation * diffuse;
|
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);
|
if (normal == vec4(0, 0, 0, 0))
|
||||||
//float diffuse = max(dot(normal.xyz, light_direction), 0.0);
|
out_color = color.xyz;
|
||||||
|
|
||||||
Color = vec4(out_color, 1.0);
|
Color = vec4(out_color, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,7 +46,7 @@ void main()
|
|||||||
|
|
||||||
vs_out.Position = position;
|
vs_out.Position = position;
|
||||||
vs_out.BlockPosition = BlockPosition;
|
vs_out.BlockPosition = BlockPosition;
|
||||||
vs_out.Normal = Normal;
|
vs_out.Normal = orientation(Normal);
|
||||||
vs_out.Texture = Texture;
|
vs_out.Texture = Texture;
|
||||||
vs_out.BlockID = BlockID;
|
vs_out.BlockID = BlockID;
|
||||||
vs_out.Data = Data;
|
vs_out.Data = Data;
|
||||||
|
|||||||
106
game/src/flame.cpp
Normal file
106
game/src/flame.cpp
Normal 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
169
game/src/font/bitmap.cpp
Normal 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
150
game/src/font/outline.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,19 +3,18 @@
|
|||||||
|
|
||||||
#include "directxmath/directxmath.h"
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
#include "font.h"
|
#include "font/bitmap.h"
|
||||||
#include "view.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 empty_vertex_array_object;
|
||||||
extern unsigned int quad_index_buffer;
|
extern unsigned int quad_index_buffer;
|
||||||
|
|
||||||
extern float current_time;
|
extern float current_time;
|
||||||
extern float last_frame_time;
|
extern float last_frame_time;
|
||||||
|
|
||||||
|
|
||||||
// depends on:
|
// depends on:
|
||||||
// - font::load
|
// - font::bitmap::load
|
||||||
// - load_quad_program
|
// - load_quad_program
|
||||||
// - load_quad_index_buffer
|
// - load_quad_index_buffer
|
||||||
// - empty_vertex_array_object
|
// - empty_vertex_array_object
|
||||||
@ -34,10 +33,10 @@ namespace hud {
|
|||||||
buf[label_length + len] = 0;
|
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));
|
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;
|
y += ter_best.desc->glyph_height;
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
@ -73,48 +72,42 @@ namespace hud {
|
|||||||
return rolling_sum * (1.0f / 16.0f);
|
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()
|
void draw()
|
||||||
{
|
{
|
||||||
char buf[512];
|
static char buf[512];
|
||||||
|
|
||||||
float y = 10.0f;
|
float y = 10.0f;
|
||||||
|
|
||||||
int font_ix = font::best_font(font::terminus, font::terminus_length);
|
int font_ix = font::bitmap::best_font(font::bitmap::terminus, font::bitmap::terminus_length);
|
||||||
font::font const& ter_best = terminus_fonts[font_ix];
|
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
|
||||||
font::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
|
font::bitmap::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
|
||||||
|
|
||||||
labeled_value<float>(buf, "fov: ", "%.3f", view::state.fov);
|
y = draw_label<float>(ter_best, buf, 10, y, "fov: ", "%.3f", view::state.fov);
|
||||||
font::draw_string(ter_best, buf, 10, y);
|
y = draw_label<int>(ter_best, buf, 10, y, "font_height: ", "%d", ter_best.desc->glyph_height);
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
labeled_value<float>(buf, "lighting.quadratic: ", "%.2f", lighting.quadratic);
|
y = draw_label<float>(ter_best, buf, 10, y, "lighting.quadratic: ", "%.2f", lighting.quadratic);
|
||||||
font::draw_string(ter_best, buf, 10, y);
|
y = draw_label<float>(ter_best, buf, 10, y, "lighting.linear: ", "%.2f", lighting.linear);
|
||||||
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_vector(ter_best, buf, y, "eye", view::state.eye);
|
y = draw_vector(ter_best, buf, y, "eye", XMVectorSetW(view::state.eye, 0));
|
||||||
y = draw_vector(ter_best, buf, y, "at", view::state.at);
|
y = draw_vector(ter_best, buf, y, "at", XMVectorSetW(view::state.at, 0));
|
||||||
y = draw_vector(ter_best, buf, y, "forward", view::state.forward);
|
y = draw_vector(ter_best, buf, y, "forward", XMVectorSetW(view::state.forward, 0));
|
||||||
|
|
||||||
labeled_value<float>(buf, "pitch: ", "%.4f", view::state.pitch);
|
y = draw_label<float>(ter_best, buf, 10, y, "pitch: ", "%.4f", view::state.pitch);
|
||||||
font::draw_string(ter_best, buf, 10, y);
|
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;
|
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, " position", XMLoadFloat4((XMFLOAT4*)mouse_position));
|
||||||
y = draw_vector(ter_best, buf, y, " block", XMLoadFloat4((XMFLOAT4*)mouse_block));
|
y = draw_vector(ter_best, buf, y, " block", XMLoadFloat4((XMFLOAT4*)mouse_block));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,24 @@
|
|||||||
#include "font.h"
|
#include "font/bitmap.h"
|
||||||
#include "pixel_line_art.h"
|
#include "pixel_line_art.h"
|
||||||
|
|
||||||
#include "lua_api.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 empty_vertex_array_object;
|
||||||
extern unsigned int quad_index_buffer;
|
extern unsigned int quad_index_buffer;
|
||||||
|
|
||||||
int draw_font_start()
|
int draw_font_start()
|
||||||
{
|
{
|
||||||
int font_ix = font::best_font(font::terminus, font::terminus_length);
|
int font_ix = font::bitmap::best_font(font::bitmap::terminus, font::bitmap::terminus_length);
|
||||||
font::font const& ter_best = terminus_fonts[font_ix];
|
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
|
||||||
font::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
|
font::bitmap::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
|
||||||
return font_ix;
|
return font_ix;
|
||||||
}
|
}
|
||||||
|
|
||||||
int draw_font(int font_ix, char const * text, int x, int y)
|
int draw_font(int font_ix, char const * text, int x, int y)
|
||||||
{
|
{
|
||||||
font::font const& ter_best = terminus_fonts[font_ix];
|
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
|
||||||
font::draw_string(ter_best, text, x, y);
|
font::bitmap::draw_string(ter_best, text, x, y);
|
||||||
return ter_best.desc->glyph_height;
|
return ter_best.desc->glyph_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,7 +44,7 @@ namespace minecraft {
|
|||||||
|
|
||||||
static unsigned int texture;
|
static unsigned int texture;
|
||||||
|
|
||||||
static const int world_count = 2;
|
static const int world_count = 3;
|
||||||
static world::state world_state[world_count];
|
static world::state world_state[world_count];
|
||||||
world::state * current_world;
|
world::state * current_world;
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ namespace minecraft {
|
|||||||
continue;
|
continue;
|
||||||
per_world::load_world(&world::descriptors[i], world_state[i]);
|
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)
|
static inline int popcount(int x)
|
||||||
|
|||||||
@ -7,7 +7,8 @@
|
|||||||
#include "opengl.h"
|
#include "opengl.h"
|
||||||
#include "directxmath/directxmath.h"
|
#include "directxmath/directxmath.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "font.h"
|
#include "font/bitmap.h"
|
||||||
|
#include "font/outline.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "bresenham.h"
|
#include "bresenham.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
@ -25,6 +26,8 @@
|
|||||||
#include "collada/types.h"
|
#include "collada/types.h"
|
||||||
#include "collada/instance_types.h"
|
#include "collada/instance_types.h"
|
||||||
#include "pixel_line_art.h"
|
#include "pixel_line_art.h"
|
||||||
|
#include "flame.h"
|
||||||
|
#include "new.h"
|
||||||
|
|
||||||
#include "world/entry_table.h"
|
#include "world/entry_table.h"
|
||||||
#include "world/world.h"
|
#include "world/world.h"
|
||||||
@ -66,7 +69,8 @@ unsigned int quad_index_buffer = -1;
|
|||||||
float current_time;
|
float current_time;
|
||||||
float last_frame_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 = {};
|
geometry_buffer<4> geometry_buffer_pnc = {};
|
||||||
static target_type const geometry_buffer_pnc_types[4] = {
|
static target_type const geometry_buffer_pnc_types[4] = {
|
||||||
@ -141,10 +145,13 @@ void load(const char * source_path)
|
|||||||
// font
|
// 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::outline::load_shader();
|
||||||
font::load_fonts(terminus_fonts, font::terminus, font::terminus_length);
|
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
|
// pixel_line_art
|
||||||
@ -195,6 +202,13 @@ void load(const char * source_path)
|
|||||||
|
|
||||||
//node_at = scene_state.find_node_by_name("Camera001.Target");
|
//node_at = scene_state.find_node_by_name("Camera001.Target");
|
||||||
//assert(node_at != nullptr);
|
//assert(node_at != nullptr);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// flame
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
flame::load_program();
|
||||||
|
flame::load_texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_keyboard(int up, int down, int left, int right,
|
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);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
minecraft::draw();
|
minecraft::draw();
|
||||||
//draw_line();
|
|
||||||
non_block::draw();
|
non_block::draw();
|
||||||
|
|
||||||
|
flame::draw(minecraft::current_world->light_uniform_buffer,
|
||||||
|
minecraft::current_world->light_count);
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
lighting::draw(minecraft::current_world->light_uniform_buffer,
|
lighting::draw(minecraft::current_world->light_uniform_buffer,
|
||||||
minecraft::current_world->light_count);
|
minecraft::current_world->light_count);
|
||||||
//draw_quad();
|
//draw_quad();
|
||||||
hud::draw();
|
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 {
|
} else {
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|||||||
@ -97,14 +97,19 @@ namespace view {
|
|||||||
state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
|
state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
state.fov = 1.5;
|
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.normal = get_normal(); // on forward change
|
||||||
state.direction = get_direction(); // on forward/normal/pitch change
|
state.direction = get_direction(); // on forward/normal/pitch change
|
||||||
|
|
||||||
// position
|
// 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 = state.eye + state.direction * at_distance;
|
||||||
//state.at = XMVectorSet(0, 0, 0, 1);
|
//state.at = XMVectorSet(0, 0, 0, 1);
|
||||||
//state.eye = XMVectorSet(0, -100, 0, 1);
|
//state.eye = XMVectorSet(0, -100, 0, 1);
|
||||||
|
|||||||
@ -16,6 +16,13 @@ namespace world {
|
|||||||
{ "minecraft/grandlecturn/region.-1.-1.instance.vtx", "minecraft/grandlecturn/region.-1.-1.instance.cfg" },
|
{ "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[] = {
|
descriptor const descriptors[] = {
|
||||||
[world_id::LOVE2DWORLD] = {
|
[world_id::LOVE2DWORLD] = {
|
||||||
.region_count = 4,
|
.region_count = 4,
|
||||||
@ -31,6 +38,13 @@ namespace world {
|
|||||||
.lights_path = "minecraft/grandlecturn/global.lights.vtx",
|
.lights_path = "minecraft/grandlecturn/global.lights.vtx",
|
||||||
.hash_func = grandlecturn_hash,
|
.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]));
|
int const descriptors_length = (sizeof (descriptors)) / (sizeof (descriptors[0]));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user