Clean up TextureAtlas, fix swaying and offsetting, add pillar blockmodel.
parent
60051a7d41
commit
838680f0fc
|
@ -14,6 +14,7 @@
|
|||
<file path="$PROJECT_DIR$/.vscode" />
|
||||
<file path="$PROJECT_DIR$/.github" />
|
||||
<file path="$PROJECT_DIR$/worlds" />
|
||||
<file path="$PROJECT_DIR$/src/CMakeFiles" />
|
||||
<file path="$PROJECT_DIR$/cmake-build-debug" />
|
||||
<file path="$PROJECT_DIR$/cmake-build-install" />
|
||||
<file path="$PROJECT_DIR$/cmake-build-release" />
|
||||
|
@ -27,4 +28,4 @@
|
|||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
cmake_minimum_required (VERSION 3.12 FATAL_ERROR)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
|
||||
|
||||
# Set warnings
|
||||
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||
add_compile_options(
|
||||
-Werror -Wall -Wextra -pedantic -pedantic-errors
|
||||
-Wnon-virtual-dtor -Wmisleading-indentation -Wlogical-op -Wnull-dereference
|
||||
-Wno-unused-parameter -Wno-reorder -Wno-sign-compare)
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/permissive /W4 /w14640)
|
||||
endif()
|
||||
|
||||
set(PROJECT_NAME "Zepha")
|
||||
set(MAIN_EXEC_NAME "Zepha")
|
||||
# set(TEST_EXEC_NAME "ZephaTest")
|
||||
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
find_path(GLEW_HEADERS GL/glew.h)
|
||||
find_path(GLFW_HEADERS GLFW/glfw3.h)
|
||||
find_path(LUA_HEADERS lua.hpp
|
||||
/usr/include/lua5.3
|
||||
/usr/local/include/lua5.3)
|
||||
find_path(ASSIMP_HEADERS assimp/Importer.hpp)
|
||||
find_path(ENET_HEADERS enet/enet.h)
|
||||
find_path(NOISE_HEADERS NAMES libnoise/noise.h libnoise/module/modulebase.h)
|
||||
find_path(GLM_HEADERS glm/glm.hpp)
|
||||
find_path(PTHREAD_HEADERS pthread.h)
|
||||
|
||||
find_library(ENET_LIB enet)
|
||||
find_library(NOISE_LIB NAMES libnoise noise)
|
||||
|
||||
if (WIN32)
|
||||
find_library(PTHREAD_LIB pthreadVC3)
|
||||
else()
|
||||
find_library(PTHREAD_LIB pthread)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${GLM_HEADERS}
|
||||
${GLEW_HEADERS}
|
||||
${LUA_HEADERS}
|
||||
${ASSIMP_HEADERS}
|
||||
${ENET_HEADERS}
|
||||
${NOISE_HEADERS}
|
||||
${PTHREAD_HEADERS}
|
||||
lib/fastnoise2/include
|
||||
lib/catch2/include
|
||||
lib/gzip/include
|
||||
lib/cute_files/include
|
||||
lib/stb_image/include
|
||||
lib/json/include
|
||||
lib/sol/include
|
||||
)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_executable(${MAIN_EXEC_NAME} src/Main.cpp)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} Zepha_Core)
|
||||
|
||||
target_include_directories(${MAIN_EXEC_NAME} PRIVATE ${GLFW_HEADERS})
|
||||
|
||||
# Enet
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${ENET_LIB})
|
||||
|
||||
# Find and Link OpenGL
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLUT REQUIRED)
|
||||
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})
|
||||
|
||||
# Build GLFW
|
||||
if (WIN32)
|
||||
find_library(GLFW_LIB glfw3dll)
|
||||
else()
|
||||
find_library(GLFW_LIB NAMES GLFW glfw glfw3)
|
||||
endif()
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${GLFW_LIB})
|
||||
|
||||
# Link GLEW
|
||||
if (WIN32)
|
||||
find_library(GLEW_LIB glew32)
|
||||
else()
|
||||
find_library(GLEW_LIB NAMES GLEW glew3)
|
||||
endif()
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${GLEW_LIB})
|
||||
|
||||
# Build and Link Assimp
|
||||
|
||||
if (WIN32)
|
||||
find_library(ASSIMP_LIB assimp-vc142-mt)
|
||||
else()
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(ASSIMP_NO_EXPORT ON)
|
||||
set(ASSIMP_BUILD_TESTS OFF)
|
||||
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF)
|
||||
|
||||
set(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT OFF)
|
||||
set(ASSIMP_BUILD_B3D_IMPORTER ON)
|
||||
set(ASSIMP_BUILD_X3D_IMPORTER ON) # Doesn't compile if not defined
|
||||
|
||||
add_subdirectory(lib/assimp)
|
||||
target_compile_options(assimp PRIVATE -w)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} assimp)
|
||||
endif()
|
||||
|
||||
# Build and Link FastNoise2
|
||||
|
||||
add_subdirectory(lib/fastnoise2)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} FastNoise)
|
||||
|
||||
# Link Lua 5.3.5
|
||||
find_library(LUA_LIB NAMES lua lua5.3)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${LUA_LIB})
|
||||
|
||||
# Link Noise
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${NOISE_LIB})
|
||||
|
||||
# Link PThread Dynamically
|
||||
target_link_libraries (${MAIN_EXEC_NAME} ${PTHREAD_LIB})
|
||||
|
||||
# Link Z Dynamically
|
||||
target_link_libraries (${MAIN_EXEC_NAME} z)
|
||||
|
||||
# Fix Win32 networking
|
||||
if(WIN32)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} winmm ws2_32)
|
||||
endif()
|
||||
|
||||
# Test Build
|
||||
# add_subdirectory(test)
|
||||
# add_executable(${TEST_EXEC_NAME} test/Main.cpp)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} Zepha_Core)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} Zepha_Test)
|
||||
|
||||
# target_include_directories(${TEST_EXEC_NAME} PRIVATE ${GLFW_HEADERS})
|
||||
# target_link_libraries(${TEST_EXEC_NAME} ${LUA_LIB})
|
||||
# target_link_libraries (${TEST_EXEC_NAME} z)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} ${ENET_LIB})
|
|
@ -5,4 +5,5 @@ require(_PATH .. "cross_large")
|
|||
require(_PATH .. "block_slab")
|
||||
require(_PATH .. "block_slab_foliage")
|
||||
require(_PATH .. "leaf_like")
|
||||
require(_PATH .. "cross_plant")
|
||||
require(_PATH .. "cross_plant")
|
||||
require(_PATH .. "pillar")
|
|
@ -0,0 +1,104 @@
|
|||
--
|
||||
-- Basic 'pillar' model, represents an 8-sided pillar.
|
||||
-- Texture order is: top, bottom, side
|
||||
--
|
||||
|
||||
zepha.register_blockmodel("base:pillar", {
|
||||
parts = {
|
||||
{
|
||||
face = "left",
|
||||
tex = 3,
|
||||
points = {
|
||||
0, 0, 4/16, 0, 1,
|
||||
0, 0, 12/16, 8/16, 1,
|
||||
0, 1, 12/16, 8/16, 0,
|
||||
0, 1, 4/16, 0, 0
|
||||
}
|
||||
}, {
|
||||
face = "right",
|
||||
tex = 3,
|
||||
points = {
|
||||
1, 1, 12/16, 0, 0,
|
||||
1, 0, 12/16, 0, 1,
|
||||
1, 0, 4/16, 8/16, 1,
|
||||
1, 1, 4/16, 8/16, 0
|
||||
}
|
||||
-- }, {
|
||||
-- face = "top",
|
||||
-- tex = 1,
|
||||
-- points = {
|
||||
-- 0, 1, 0, 0, 0,
|
||||
-- 0, 1, 1, 0, 1,
|
||||
-- 1, 1, 1, 1, 1,
|
||||
-- 1, 1, 0, 1, 0
|
||||
-- }
|
||||
-- }, {
|
||||
-- face = "bottom",
|
||||
-- tex = 2,
|
||||
-- points = {
|
||||
-- 0, 0, 0, 0, 0,
|
||||
-- 1, 0, 0, 1, 0,
|
||||
-- 1, 0, 1, 1, 1,
|
||||
-- 0, 0, 1, 0, 1
|
||||
-- }
|
||||
}, {
|
||||
face = "front",
|
||||
tex = 3,
|
||||
points = {
|
||||
4/16, 0, 1, 0, 1,
|
||||
12/16, 0, 1, 8/16, 1,
|
||||
12/16, 1, 1, 8/16, 0,
|
||||
4/16, 1, 1, 0, 0
|
||||
}
|
||||
}, {
|
||||
face = "back",
|
||||
tex = 3,
|
||||
points = {
|
||||
4/16, 0, 0, 8/16, 1,
|
||||
4/16, 1, 0, 8/16, 0,
|
||||
12/16, 1, 0, 0, 0,
|
||||
12/16, 0, 0, 0, 1
|
||||
}
|
||||
},
|
||||
{
|
||||
face = "nocull",
|
||||
tex = 3,
|
||||
points = {
|
||||
0, 0, 4/16, 10/16, 0,
|
||||
0, 1, 4/16, 10/16, 1,
|
||||
4/16, 1, 0, 1, 1,
|
||||
4/16, 0, 0, 1, 0
|
||||
}
|
||||
},
|
||||
{
|
||||
face = "nocull",
|
||||
tex = 3,
|
||||
points = {
|
||||
12/16, 0, 0, 1, 0,
|
||||
12/16, 1, 0, 1, 1,
|
||||
1, 1, 4/16, 10/16, 1,
|
||||
1, 0, 4/16, 10/16, 0
|
||||
}
|
||||
},
|
||||
{
|
||||
face = "nocull",
|
||||
tex = 3,
|
||||
points = {
|
||||
4/16, 0, 1, 1, 0,
|
||||
4/16, 1, 1, 1, 1,
|
||||
0, 1, 12/16, 10/16, 1,
|
||||
0, 0, 12/16, 10/16, 0
|
||||
}
|
||||
},
|
||||
{
|
||||
face = "nocull",
|
||||
tex = 3,
|
||||
points = {
|
||||
1, 0, 12/16, 10/16, 0,
|
||||
1, 1, 12/16, 10/16, 1,
|
||||
12/16, 1, 1, 1, 1,
|
||||
12/16, 0, 1, 1, 0
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
|
@ -82,7 +82,7 @@ void main() {
|
|||
vec4 origin = vec4(round(unpackFloat(gs_in[i].modValues.x) * 8 + 8), 1);
|
||||
vec3 bsp = vec3(pos - origin);
|
||||
vec3 worldPos = (model * pos).xyz;
|
||||
if (bsp.x*bsp.y*bsp.z != 0 && bsp.x*bsp.y*bsp.z != 1) {
|
||||
if (bsp.x * bsp.y * bsp.z != 0 && bsp.x * bsp.y * bsp.z != 1) {
|
||||
vec3 sway = (texture(swayTex, worldPos.xz * (worldPos.y / 16.f) / 16.f).xyz - .5f) * vec3(gs_in[i].modValues.y, gs_in[i].modValues.y / 2, gs_in[i].modValues.y);
|
||||
pos += vec4(sway, 0);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ layout (location = 2) in ivec3 aBlend;
|
|||
layout (location = 5) in ivec4 aLight;
|
||||
|
||||
layout (location = 6) in int aShaderMod;
|
||||
layout (location = 7) in ivec3 aModValues;
|
||||
layout (location = 7) in vec3 aModValues;
|
||||
|
||||
out VS_OUT {
|
||||
vec3 pos;
|
||||
|
|
|
@ -28,7 +28,7 @@ f64 Client::getDelta() {
|
|||
}
|
||||
|
||||
void Client::startLocalServer(const string& subgame) {
|
||||
//TODO: Implement Local Server
|
||||
// TODO: Implement Local Server
|
||||
// localServer = std::make_shared<LocalServerInstance>(executablePath, addr.port, state.subgame);
|
||||
// localServer->start();
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "util/GL.h"
|
||||
#include <util/Util.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "Input.h"
|
||||
|
||||
#include "Window.h"
|
||||
#include "util/Util.h"
|
||||
#include "client/Window.h"
|
||||
|
||||
void Input::init(GLFWwindow* window) {
|
||||
this->window = window;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "util/Types.h"
|
||||
#include "client/Callback.h"
|
||||
|
||||
class GLFWwindow;
|
||||
|
||||
/**
|
||||
* Manages callbacks for key and mouse input, allows toggling mouse locking.
|
||||
*/
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
// Created by aurailus on 2019-10-31.
|
||||
//
|
||||
|
||||
#include "LocalServerInstance.h"
|
||||
#include "util/Log.h"
|
||||
#include "server/Server.h"
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
#include "LocalServerInstance.h"
|
||||
|
||||
#include "server/Server.h"
|
||||
|
||||
LocalServerInstance::LocalServerInstance(const std::string& path, unsigned short port, const std::string& subgame) :
|
||||
port(port),
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "util/Log.h"
|
||||
#include "util/GL.h"
|
||||
|
||||
Window::Window() : Window({ 800, 600 }) {};
|
||||
|
|
|
@ -32,7 +32,7 @@ void ClientNetworkInterpreter::update() {
|
|||
default: break;
|
||||
case ENET_EVENT_TYPE_CONNECT: {
|
||||
std::cout << Log::info << "Connected to server "
|
||||
<< NetHandler::intToIPString(*reinterpret_cast<unsigned int*>(&event.peer->address.host))
|
||||
<< NetHandler::intToIPString(*reinterpret_cast<u32*>(&event.peer->address.host))
|
||||
<< ":" << event.peer->address.port << "." << Log::endl;
|
||||
break;
|
||||
}
|
||||
|
@ -42,7 +42,9 @@ void ClientNetworkInterpreter::update() {
|
|||
break;
|
||||
}
|
||||
case ENET_EVENT_TYPE_DISCONNECT: {
|
||||
//std::cout << Log::info << "Disconnected from server " << event.peer->address.host << ":" << event.peer->address.port << "." << Log::endl;
|
||||
std::cout << Log::info << "Disconnected from server "
|
||||
<< NetHandler::intToIPString(*reinterpret_cast<u32*>(&event.peer->address.host))
|
||||
<< ":" << event.peer->address.port << "." << Log::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ void ServerConnection::processConnecting() {
|
|||
if (elapsedMs < timeout) {
|
||||
if (enet_host_service(host, &event, 0) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) {
|
||||
std::cout << Log::info << "Connected to "
|
||||
<< NetHandler::intToIPString(*reinterpret_cast<unsigned int*>(&event.peer->address.host))
|
||||
<< NetHandler::intToIPString(*reinterpret_cast<u32*>(&event.peer->address.host))
|
||||
<< ":" << event.peer->address.port << "." << Log::endl;
|
||||
|
||||
state = State::CONNECTED;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
Font::Font(TextureAtlas& atlas, std::shared_ptr<AtlasRef> tex) :
|
||||
fontTex(std::move(tex)),
|
||||
atlasSize(atlas.pixelSize) {
|
||||
atlasSize(atlas.canvasSize) {
|
||||
|
||||
getCharWidths(atlas);
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ void Font::getCharWidths(TextureAtlas& atlas) {
|
|||
for (u16 i = 1; i < C_COUNT + 1; i++) {
|
||||
glm::vec2 charPos = { i % 18 * C_WIDTH, std::floor(i / 18) * C_HEIGHT };
|
||||
|
||||
u32 xBase = static_cast<u32>(fontTex->pos.x) + static_cast<u32>(charPos.x);
|
||||
u32 yBase = static_cast<u32>(fontTex->pos.y) + static_cast<u32>(charPos.y);
|
||||
u32 xBase = static_cast<u32>(fontTex->rawPos.x) + static_cast<u32>(charPos.x);
|
||||
u32 yBase = static_cast<u32>(fontTex->rawPos.y) + static_cast<u32>(charPos.y);
|
||||
|
||||
u16 width = 0;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ void Renderer::update(double delta) {
|
|||
elapsedTime += delta;
|
||||
|
||||
window.update();
|
||||
//world.updateSwayMap(delta);
|
||||
world.updateSwayMap(delta);
|
||||
}
|
||||
|
||||
void Renderer::beginChunkDeferredCalls() {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// Created by aurailus on 29/11/18.
|
||||
//
|
||||
|
||||
#include <stb_image.h>
|
||||
#include <stdexcept>
|
||||
#include <stb_image.h>
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
|
|
|
@ -57,15 +57,15 @@ ChunkMeshGenerator::ChunkMeshGenerator(MeshChunkDetails* meshDetails, LocalDefin
|
|||
default: break;
|
||||
|
||||
case MeshMod::OFFSET_X:
|
||||
// vis.x += blockOffsets[0][vec3(off) / 16.f] * mod.second;
|
||||
vis.x += blockOffsets[0][off] * mod.second;
|
||||
break;
|
||||
|
||||
case MeshMod::OFFSET_Y:
|
||||
// vis.y += blockOffsets[1][vec3(off) / 16.f] * mod.second;
|
||||
vis.y += blockOffsets[1][off] * mod.second;
|
||||
break;
|
||||
|
||||
case MeshMod::OFFSET_Z:
|
||||
// vis.z += blockOffsets[2][vec3(off) / 16.f] * mod.second;
|
||||
vis.z += blockOffsets[2][off] * mod.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,5 +32,5 @@ MeshChunk::Mesh::Mesh(const vec<Vertex>& vertices, const vec<u32>& indices) {
|
|||
createVertexAttrib(idx++, 1, GL_FLOAT, false, STRIDE_OFFSET(Vertex, normal));
|
||||
createVertexAttrib(idx++, 4, GL_UNSIGNED_BYTE, true, STRIDE_OFFSET(Vertex, light));
|
||||
createVertexAttrib(idx++, 1, GL_UNSIGNED_BYTE, true, STRIDE_OFFSET(Vertex, shaderMod));
|
||||
createVertexAttrib(idx, 3, GL_UNSIGNED_BYTE, true, STRIDE_OFFSET(Vertex, modValues));
|
||||
createVertexAttrib(idx++, 3, GL_FLOAT , false, STRIDE_OFFSET(Vertex, modValues));
|
||||
}
|
|
@ -26,7 +26,7 @@ public:
|
|||
u8vec4 light;
|
||||
|
||||
u8 shaderMod;
|
||||
u8vec3 modValues;
|
||||
vec3 modValues;
|
||||
};
|
||||
|
||||
/** Represents a MeshChunk's underlying mesh. */
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include "util/GL.h"
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
struct GuiUniforms {
|
||||
glm::mat4 matrix;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Created by aurailus on 25/09/19.
|
||||
//
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "WorldGeometryShader.h"
|
||||
|
||||
|
@ -11,7 +11,11 @@ WorldGeometryShader::WorldGeometryShader(glm::ivec2 windowSize, float bufferScal
|
|||
bufferScale(bufferScale),
|
||||
swayData(16 * 4 * 16) {
|
||||
|
||||
swayNoise = FastNoise::New<FastNoise::Constant>();
|
||||
let simplex = FastNoise::New<FastNoise::Simplex>();
|
||||
let generator = FastNoise::New<FastNoise::DomainScale>();
|
||||
generator->SetSource(simplex);
|
||||
generator->SetScale(500.f);
|
||||
swayGenerator = generator;
|
||||
}
|
||||
|
||||
void WorldGeometryShader::postCreate() {
|
||||
|
@ -33,15 +37,14 @@ void WorldGeometryShader::windowResized(glm::ivec2 windowSize) {
|
|||
}
|
||||
|
||||
void WorldGeometryShader::updateSwayMap(double delta) {
|
||||
swayOffset += delta * 2.8;
|
||||
for (int i = 0; i < 16 * 16; i++) {
|
||||
swayData[i * 4] = static_cast<unsigned char>(
|
||||
(fmax(-1, fmin(1, swayNoise->GenSingle3D((i / 16) / 3.f, (i % 16) / 3.f, swayOffset, 0))) + 1) / 2.f * 255.f);
|
||||
swayData[i * 4 + 1] = static_cast<unsigned char>(
|
||||
(fmax(-1, fmin(1, swayNoise->GenSingle3D((i / 16) / 3.f, (i % 16) / 3.f, swayOffset + 50, 0))) + 1) / 2.f * 255.f);
|
||||
swayData[i * 4 + 2] = static_cast<unsigned char>(
|
||||
(fmax(-1, fmin(1, swayNoise->GenSingle3D((i / 16) / 3.f, (i % 16) / 3.f, swayOffset + 100, 0))) + 1) / 2.f *
|
||||
255.f);
|
||||
swayOffset += delta * 0.001;
|
||||
for (u16 i = 0; i < 16 * 16; i++) {
|
||||
swayData[i * 4] = static_cast<u8>((fmax(-1, fmin(1,
|
||||
swayGenerator->GenSingle3D((i / 16) / 3.f, (i % 16) / 3.f, swayOffset, 0))) + 1) / 2.f * 255.f);
|
||||
swayData[i * 4 + 1] = static_cast<u8>((fmax(-1, fmin(1,
|
||||
swayGenerator->GenSingle3D((i / 16) / 3.f, (i % 16) / 3.f, swayOffset + 50, 0))) + 1) / 2.f * 255.f);
|
||||
swayData[i * 4 + 2] = static_cast<u8>((fmax(-1, fmin(1,
|
||||
swayGenerator->GenSingle3D((i / 16) / 3.f, (i % 16) / 3.f, swayOffset + 100, 0))) + 1) / 2.f * 255.f);
|
||||
}
|
||||
swayTex.updateTexture(0, 0, 16, 16, &swayData[0]);
|
||||
}
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <FastNoise/FastNoise.h>
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
#include "../Texture.h"
|
||||
#include "util/Types.h"
|
||||
#include "client/graph/Texture.h"
|
||||
|
||||
class WorldGeometryShader : public Shader {
|
||||
public:
|
||||
|
@ -34,9 +34,9 @@ public:
|
|||
Uniforms uniforms{};
|
||||
|
||||
Texture swayTex;
|
||||
double swayOffset = 0;
|
||||
FastNoise::SmartNode<> swayNoise;
|
||||
std::vector<unsigned char> swayData{};
|
||||
vec<u8> swayData{};
|
||||
f64 swayOffset = 0;
|
||||
FastNoise::SmartNode<> swayGenerator;
|
||||
|
||||
glm::ivec2 windowSize{};
|
||||
float bufferScale = 1;
|
||||
|
|
|
@ -130,6 +130,7 @@ bool Gui::Element::handleMouseClick(ivec2 mousePos, u32 button, bool down) {
|
|||
}
|
||||
|
||||
void Gui::Element::draw(Renderer& renderer) {
|
||||
if (!getStyle<bool>(Gui::Prop::VISIBLE, true)) return;
|
||||
entity.draw(renderer);
|
||||
for (let& child : children) child->draw(renderer);
|
||||
}
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
#include "Gui.h"
|
||||
#include "util/Util.h"
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
Gui::Expression::Expression(const string& exp) {
|
||||
setExpression(exp);
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace Gui {
|
|||
enum class Prop {
|
||||
ID,
|
||||
CLASS,
|
||||
VISIBLE,
|
||||
|
||||
POS,
|
||||
SIZE,
|
||||
|
|
|
@ -138,8 +138,8 @@ void ConnectScene::update() {
|
|||
string uncompressed = gzip::decompress(data.data(), data.length());
|
||||
|
||||
client.game->textures.addImage(
|
||||
reinterpret_cast<unsigned char*>(const_cast<char*>(uncompressed.data())),
|
||||
assetName, true, width, height);
|
||||
assetName, true, u16vec2(width, height),
|
||||
reinterpret_cast<u8*>(const_cast<char*>(uncompressed.data())));
|
||||
}
|
||||
else if (t == AssetType::MODEL) {
|
||||
string format = p.d.read<string>();
|
||||
|
@ -213,7 +213,7 @@ void ConnectScene::draw() {
|
|||
renderer.beginChunkDeferredCalls();
|
||||
renderer.endDeferredCalls();
|
||||
renderer.beginGUIDrawCalls();
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.texture);
|
||||
|
||||
root.draw(renderer);
|
||||
}
|
|
@ -47,18 +47,18 @@ void GameScene::draw() {
|
|||
|
||||
perf.start("draw:world");
|
||||
renderer.beginChunkDeferredCalls();
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.texture);
|
||||
world.l()->drawChunks();
|
||||
|
||||
perf.start("draw:entities");
|
||||
renderer.beginEntityDeferredCalls();
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.texture);
|
||||
world.l()->drawEntities();
|
||||
renderer.endDeferredCalls();
|
||||
|
||||
perf.start("draw:interface");
|
||||
renderer.beginGUIDrawCalls();
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.texture);
|
||||
world.l()->drawInterface();
|
||||
|
||||
perf.start("idle");
|
||||
|
|
|
@ -37,7 +37,7 @@ void LuaErrorScene::draw() {
|
|||
renderer.beginChunkDeferredCalls();
|
||||
renderer.endDeferredCalls();
|
||||
renderer.beginGUIDrawCalls();
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.texture);
|
||||
|
||||
root.draw(renderer);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <cute_files.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "MainMenuScene.h"
|
||||
|
||||
|
@ -211,6 +211,6 @@ void MainMenuScene::draw() {
|
|||
renderer.endDeferredCalls();
|
||||
|
||||
renderer.beginGUIDrawCalls();
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.texture);
|
||||
root.draw(renderer);
|
||||
}
|
|
@ -12,22 +12,16 @@
|
|||
#include "world/dim/LocalDimension.h"
|
||||
|
||||
MeshGenStream::MeshGenStream(SubgamePtr game, LocalDimension& dimension): dimension(dimension),
|
||||
noiseSampler({ NoiseSample(u16vec3(16), 4), NoiseSample(u16vec3(16), 4), NoiseSample(u16vec3(16), 4) }) {
|
||||
/*noise::module::Perlin offsetBaseNoise;
|
||||
offsetBaseNoise.SetFrequency(8);
|
||||
offsetBaseNoise.SetOctaveCount(3);
|
||||
|
||||
noise::module::Turbulence offsetTurbulence;
|
||||
offsetTurbulence.SetSourceModule(0, offsetBaseNoise);
|
||||
offsetTurbulence.SetFrequency(4.0);
|
||||
offsetTurbulence.SetPower(0.125);*/
|
||||
|
||||
generator = FastNoise::New<FastNoise::Constant>();
|
||||
noiseSampler({ NoiseSample(u16vec3(16), 1), NoiseSample(u16vec3(16), 1), NoiseSample(u16vec3(16), 1) }) {
|
||||
let simplex = FastNoise::New<FastNoise::Simplex>();
|
||||
let generator = FastNoise::New<FastNoise::DomainScale>();
|
||||
generator->SetSource(simplex);
|
||||
generator->SetScale(1000.f);
|
||||
|
||||
// 8 is just a random value to offset results
|
||||
// noiseSampler[0].generate(u16vec3(8, 0, 0), generator);
|
||||
// noiseSampler[1].generate(u16vec3(0, 8, 0), generator);
|
||||
// noiseSampler[2].generate(u16vec3(0, 0, 8), generator);
|
||||
noiseSampler[0].generate(u16vec3(8, 0, 0), generator);
|
||||
noiseSampler[1].generate(u16vec3(0, 8, 0), generator);
|
||||
noiseSampler[2].generate(u16vec3(0, 0, 8), generator);
|
||||
|
||||
threads.reserve(THREADS);
|
||||
for (int i = 0; i < THREADS; i++) threads.emplace_back(*game.l(), noiseSampler);
|
||||
|
|
|
@ -70,7 +70,5 @@ private:
|
|||
std::unordered_set<glm::vec3, Vec::vec3> queuedMap;
|
||||
|
||||
constexpr const static u8 HIGH_DETAIL_RANGE = 4;
|
||||
|
||||
FastNoise::SmartNode<> generator;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
|
||||
LocalSubgame::LocalSubgame(const std::string& baseAssets) :
|
||||
textures(2048),
|
||||
textures(u16vec2(2048)),
|
||||
|
||||
lua(std::make_unique<LocalLuaParser>(*this)),
|
||||
biomes(std::make_unique<LocalBiomeAtlas>()),
|
||||
|
|
|
@ -1,26 +1,21 @@
|
|||
//
|
||||
// Created by aurailus on 16/04/19.
|
||||
//
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <stb_image.h>
|
||||
#include <cute_files.h>
|
||||
#include <util/Types.h>
|
||||
#include <util/Util.h>
|
||||
|
||||
#include "TextureAtlas.h"
|
||||
|
||||
#include "util/Log.h"
|
||||
#include "util/Util.h"
|
||||
#include "game/atlas/asset/AtlasRef.h"
|
||||
|
||||
TextureAtlas::TextureAtlas(unsigned int width, unsigned int height) :
|
||||
pixelSize(width, (height == 0 ? width : height)),
|
||||
tileSize(pixelSize.x / 16, pixelSize.y / 16),
|
||||
atlasData(pixelSize.x * 4 * pixelSize.y) {
|
||||
|
||||
maxTextureSlots = tileSize.x * tileSize.y;
|
||||
TextureAtlas::TextureAtlas(uvec2 size) :
|
||||
canvasSize(size),
|
||||
canvasTileSize(size / 16u),
|
||||
atlasData(size.x * 4 * size.y),
|
||||
maxTextureSlots(canvasTileSize.x * canvasTileSize.y),
|
||||
empty(canvasTileSize.x * canvasTileSize.y, true) {
|
||||
|
||||
// int maxTexSize, texUnits;
|
||||
//
|
||||
|
@ -30,14 +25,13 @@ TextureAtlas::TextureAtlas(unsigned int width, unsigned int height) :
|
|||
// glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &texUnits);
|
||||
// std::cout << Log::info << "This GPU supports " << texUnits << " texture units." << Log::endl;
|
||||
|
||||
empty = std::vector<bool>(tileSize.x * tileSize.y, true);
|
||||
atlasTexture.loadFromBytes(&atlasData[0], pixelSize.x, pixelSize.y);
|
||||
texture.loadFromBytes(&atlasData[0], size.x, size.y);
|
||||
|
||||
createMissingImage();
|
||||
createMissingTexture();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<AtlasRef>> TextureAtlas::loadDirectory(const std::string& path, bool base, bool recursive) {
|
||||
std::vector<std::shared_ptr<AtlasRef>> refs{};
|
||||
vec<sptr<AtlasRef>> TextureAtlas::loadDirectory(const string& path, bool base, bool recurse) {
|
||||
vec<sptr<AtlasRef>> refs {};
|
||||
|
||||
cf_dir_t dir;
|
||||
cf_dir_open(&dir, (path).c_str());
|
||||
|
@ -45,17 +39,15 @@ std::vector<std::shared_ptr<AtlasRef>> TextureAtlas::loadDirectory(const std::st
|
|||
while (dir.has_next) {
|
||||
cf_file_t file;
|
||||
cf_read_file(&dir, &file);
|
||||
std::string_view name = file.name;
|
||||
|
||||
if (!file.is_dir && strcmp(file.ext, ".png") == 0) {
|
||||
refs.push_back(
|
||||
loadImage(file.path, std::string(file.name).substr(0, std::string(file.name).size() - 4), base));
|
||||
}
|
||||
if (!file.is_dir && strcmp(file.ext, ".png") == 0)
|
||||
refs.push_back(loadImage(file.path, string(name.substr(0, name.size() - 4)), base));
|
||||
|
||||
if (recursive && file.is_dir && strncmp(file.name, ".", 1) != 0) {
|
||||
auto vec = loadDirectory(file.path, base, recursive);
|
||||
if (recurse && file.is_dir && name.data()[0] != '.') {
|
||||
let vec = loadDirectory(file.path, base, true);
|
||||
refs.insert(refs.end(), vec.begin(), vec.end());
|
||||
}
|
||||
|
||||
cf_dir_next(&dir);
|
||||
}
|
||||
cf_dir_close(&dir);
|
||||
|
@ -63,95 +55,75 @@ std::vector<std::shared_ptr<AtlasRef>> TextureAtlas::loadDirectory(const std::st
|
|||
return refs;
|
||||
}
|
||||
|
||||
std::shared_ptr<AtlasRef> TextureAtlas::loadImage(const std::string& path, const std::string& name, bool base) {
|
||||
int width, height;
|
||||
unsigned char* data = stbi_load(path.data(), &width, &height, nullptr, 4);
|
||||
auto ref = addImage(data, name, base, width, height);
|
||||
sptr<AtlasRef> TextureAtlas::loadImage(const string& path, const string& name, bool base) {
|
||||
i32 width, height;
|
||||
u8* data = stbi_load(path.data(), &width, &height, nullptr, 4);
|
||||
let ref = addImage(name, base, u16vec2(width, height), data);
|
||||
free(data);
|
||||
return ref;
|
||||
}
|
||||
|
||||
void TextureAtlas::update() {
|
||||
auto it = textures.cbegin();
|
||||
|
||||
while (it != textures.cend()) {
|
||||
auto curr = it++;
|
||||
|
||||
if (!curr->second->base && curr->second.unique()) {
|
||||
deleteImage(curr->second);
|
||||
textures.erase(curr);
|
||||
for (let it = textures.begin(); it != textures.end();) {
|
||||
if (!it->second->base && it->second.unique()) {
|
||||
deleteImage(it->second);
|
||||
it = textures.erase(it);
|
||||
}
|
||||
else it++;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec4 TextureAtlas::sampleTexturePixel(const std::shared_ptr<AtlasRef>& atlasRef, glm::vec2 pixel) {
|
||||
glm::vec2 absPos = { atlasRef->pos.x + pixel.x, atlasRef->pos.y + pixel.y };
|
||||
unsigned int index = (static_cast<unsigned int>(absPos.y) * pixelSize.x + static_cast<unsigned int>(absPos.x)) * 4;
|
||||
vec4 TextureAtlas::getPixel(const sptr<AtlasRef>& ref, ivec2 pos) {
|
||||
uvec2 absPos = { ref->rawPos.x + pos.x, ref->rawPos.y + pos.y };
|
||||
u32 index = (static_cast<u32>(absPos.y) * canvasSize.x + static_cast<u32>(absPos.x)) * 4;
|
||||
|
||||
return {
|
||||
static_cast<float>(atlasData[index]) / 255.f,
|
||||
static_cast<float>(atlasData[index + 1]) / 255.f,
|
||||
static_cast<float>(atlasData[index + 2]) / 255.f,
|
||||
static_cast<float>(atlasData[index + 3]) / 255.f,
|
||||
};
|
||||
return { atlasData[index] / 255.f, atlasData[index + 1] / 255.f,
|
||||
atlasData[index + 2] / 255.f, atlasData[index + 3] / 255.f };
|
||||
}
|
||||
|
||||
std::shared_ptr<AtlasRef>
|
||||
TextureAtlas::addImage(unsigned char* data, const std::string& name, bool base, int texWidth, int texHeight) {
|
||||
std::shared_ptr<AtlasRef> ref;
|
||||
sptr<AtlasRef> TextureAtlas::addImage(const string& name, bool base, u16vec2 size, u8* data) {
|
||||
sptr<AtlasRef> ref;
|
||||
u16vec2 tileSize = u16vec2(glm::ceil(vec2(size) / 16.f));
|
||||
|
||||
if (textures.count(name) != 0) ref = textures[name];
|
||||
else ref = std::make_shared<AtlasRef>();
|
||||
let posOpt = findImageSpace(tileSize);
|
||||
if (!posOpt) throw std::runtime_error("Failed to find space in the dynamic definition atlas.");
|
||||
u16vec2 pos = *posOpt;
|
||||
|
||||
ref->name = name;
|
||||
ref->base = base;
|
||||
ref->width = texWidth;
|
||||
ref->height = texHeight;
|
||||
textureSlotsUsed += tileSize.x * tileSize.y;
|
||||
|
||||
auto tileWidth = static_cast<int>(std::ceil(texWidth / 16.0f));
|
||||
auto tileHeight = static_cast<int>(std::ceil(texHeight / 16.0f));
|
||||
textures.erase(name);
|
||||
ref = make_shared<AtlasRef>(AtlasRef {
|
||||
pos,
|
||||
tileSize,
|
||||
uvec2(pos) * 16u,
|
||||
size,
|
||||
vec4(pos.x * 16 / static_cast<f32>(canvasSize.x), pos.y * 16 / static_cast<f32>(canvasSize.y),
|
||||
(pos.x * 16 + size.x) / static_cast<f32>(canvasSize.x), (pos.y * 16 + size.y) / static_cast<f32>(canvasSize.y)),
|
||||
name,
|
||||
base
|
||||
});
|
||||
|
||||
if (tileWidth != ref->tileWidth || tileHeight != ref->tileHeight) {
|
||||
ref->tileWidth = tileWidth;
|
||||
ref->tileHeight = tileHeight;
|
||||
|
||||
auto space = findImageSpace(tileWidth, tileHeight);
|
||||
if (space.x < 0) throw std::runtime_error("Failed to find space in the dynamic definition atlas.");
|
||||
|
||||
textureSlotsUsed += tileWidth * tileHeight;
|
||||
|
||||
ref->tileX = static_cast<int>(space.x);
|
||||
ref->tileY = static_cast<int>(space.y);
|
||||
|
||||
ref->pos = { space.x * 16, space.y * 16, space.x * 16 + texWidth, space.y * 16 + texHeight };
|
||||
ref->uv = { (space.x * 16) / pixelSize.x, (space.y * 16) / pixelSize.y,
|
||||
(space.x * 16 + texWidth) / pixelSize.x, (space.y * 16 + texHeight) / pixelSize.y };
|
||||
|
||||
textures.insert({ name, ref });
|
||||
}
|
||||
textures.insert({ name, ref });
|
||||
|
||||
updateAtlas(ref->tileX, ref->tileY, texWidth, texHeight, data);
|
||||
updateAtlas(ref->rawPos, ref->rawSize, data);
|
||||
return ref;
|
||||
}
|
||||
|
||||
std::shared_ptr<AtlasRef> TextureAtlas::generateCrackImage(const std::string& name, unsigned short crackLevel) {
|
||||
sptr<AtlasRef> TextureAtlas::generateCrackImage(const string& name, u8 crackLevel) {
|
||||
RawTexData base = getBytesOfTex(name);
|
||||
|
||||
std::string crackStr("zeus:default:crack_" + std::to_string(crackLevel));
|
||||
RawTexData crack = getBytesOfTex(crackStr);
|
||||
|
||||
for (int i = 0; i < base.width * base.height; i++) {
|
||||
for (int i = 0; i < base.size.x * base.size.y; i++) {
|
||||
float alpha = crack.data[i * 4 + 3] / 255.f;
|
||||
|
||||
base.data[i * 4 + 0] = static_cast<unsigned char>(base.data[i * 4 + 0] * (1 - alpha) +
|
||||
crack.data[i * 4 + 0] * alpha);
|
||||
base.data[i * 4 + 1] = static_cast<unsigned char>(base.data[i * 4 + 1] * (1 - alpha) +
|
||||
crack.data[i * 4 + 1] * alpha);
|
||||
base.data[i * 4 + 2] = static_cast<unsigned char>(base.data[i * 4 + 2] * (1 - alpha) +
|
||||
crack.data[i * 4 + 2] * alpha);
|
||||
base.data[i * 4 + 0] = static_cast<u8>(base.data[i * 4 + 0] * (1 - alpha) + crack.data[i * 4 + 0] * alpha);
|
||||
base.data[i * 4 + 1] = static_cast<u8>(base.data[i * 4 + 1] * (1 - alpha) + crack.data[i * 4 + 1] * alpha);
|
||||
base.data[i * 4 + 2] = static_cast<u8>(base.data[i * 4 + 2] * (1 - alpha) + crack.data[i * 4 + 2] * alpha);
|
||||
}
|
||||
|
||||
auto ref = addImage(base.data, name + "_crack_" + std::to_string(crackLevel), false, base.width, base.height);
|
||||
auto ref = addImage(name + "_crack_" + std::to_string(crackLevel), false, base.size, base.data);
|
||||
|
||||
delete[] base.data;
|
||||
delete[] crack.data;
|
||||
|
@ -159,16 +131,16 @@ std::shared_ptr<AtlasRef> TextureAtlas::generateCrackImage(const std::string& na
|
|||
return ref;
|
||||
}
|
||||
|
||||
std::shared_ptr<AtlasRef> TextureAtlas::operator[](const std::string& name) {
|
||||
sptr<AtlasRef> TextureAtlas::operator[](const string& name) {
|
||||
if (textures.count(name)) return textures[name];
|
||||
|
||||
std::shared_ptr<AtlasRef> gen = generateTexture(name);
|
||||
sptr<AtlasRef> gen = generateTexture(name);
|
||||
if (gen) return gen;
|
||||
|
||||
throw std::runtime_error("Invalid texture: '" + name + "'");
|
||||
}
|
||||
|
||||
std::shared_ptr<AtlasRef> TextureAtlas::generateTexture(std::string req) {
|
||||
sptr<AtlasRef> TextureAtlas::generateTexture(string req) {
|
||||
req.erase(std::remove(req.begin(), req.end(), ' '), req.end());
|
||||
|
||||
if (req.find_first_of('(') != std::string::npos) {
|
||||
|
@ -176,15 +148,15 @@ std::shared_ptr<AtlasRef> TextureAtlas::generateTexture(std::string req) {
|
|||
throw std::runtime_error("Mismatched braces.");
|
||||
}
|
||||
|
||||
std::string::size_type paramsBegin = req.find_first_of('(');
|
||||
std::string::size_type paramsEnd = req.find_last_of(')');
|
||||
string::size_type paramsBegin = req.find_first_of('(');
|
||||
string::size_type paramsEnd = req.find_last_of(')');
|
||||
|
||||
std::string paramName = req.substr(0, paramsBegin);
|
||||
std::string paramsString = req.substr(paramsBegin + 1, paramsEnd - paramsBegin - 1);
|
||||
string paramName = req.substr(0, paramsBegin);
|
||||
string paramsString = req.substr(paramsBegin + 1, paramsEnd - paramsBegin - 1);
|
||||
|
||||
std::vector<std::string> params;
|
||||
std::string::size_type pos;
|
||||
while ((pos = paramsString.find(',')) != std::string::npos) {
|
||||
vec<string> params;
|
||||
string::size_type pos;
|
||||
while ((pos = paramsString.find(',')) != string::npos) {
|
||||
params.push_back(paramsString.substr(0, pos));
|
||||
paramsString.erase(0, pos + 1);
|
||||
}
|
||||
|
@ -192,26 +164,26 @@ std::shared_ptr<AtlasRef> TextureAtlas::generateTexture(std::string req) {
|
|||
|
||||
if (paramName == "crop") {
|
||||
if (params.size() != 5) throw std::runtime_error("crop() requires 5 parameters.");
|
||||
glm::ivec4 loc = { atof(params[0].data()), atof(params[1].data()), atof(params[2].data()),
|
||||
atof(params[3].data()) };
|
||||
std::shared_ptr<AtlasRef> src = operator[](params[4]);
|
||||
uvec2 pos = { atoi(params[0].data()), atoi(params[1].data()) };
|
||||
uvec2 size = { atoi(params[2].data()), atoi(params[3].data()) };
|
||||
sptr<AtlasRef> src = operator[](params[4]);
|
||||
|
||||
auto data = getBytesAtPos({ src->pos.x + loc.x, src->pos.y + loc.y }, { loc.z, loc.w }).data;
|
||||
return addImage(data, req, false, loc.z, loc.w);
|
||||
let data = getBytesAtPos(src->rawPos + pos, size).data;
|
||||
return addImage(req, false, size, data);
|
||||
}
|
||||
else if (paramName == "multiply") {
|
||||
if (params.size() != 2) throw std::runtime_error("multiply() requires 2 parameters.");
|
||||
vec4 multiple = Util::hexToColorVec(params[1]);
|
||||
auto tex = getBytesOfTex(params[0]);
|
||||
|
||||
for (int i = 0; i < tex.width * tex.height; i++) {
|
||||
for (int i = 0; i < tex.size.x * tex.size.y; i++) {
|
||||
tex.data[i * 4 + 0] *= multiple.x;
|
||||
tex.data[i * 4 + 1] *= multiple.y;
|
||||
tex.data[i * 4 + 2] *= multiple.z;
|
||||
tex.data[i * 4 + 3] *= multiple.w;
|
||||
}
|
||||
|
||||
return addImage(tex.data, req, false, tex.width, tex.height);
|
||||
return addImage(req, false, tex.size, tex.data);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Invalid parameter.");
|
||||
|
@ -221,48 +193,44 @@ std::shared_ptr<AtlasRef> TextureAtlas::generateTexture(std::string req) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
TextureAtlas::RawTexData TextureAtlas::getBytesOfTex(const std::string& name) {
|
||||
glm::vec4 pos;
|
||||
TextureAtlas::RawTexData TextureAtlas::getBytesOfTex(const string& name) {
|
||||
let it = textures.find(name);
|
||||
if (it != textures.end()) return getBytesAtPos(it->second->rawPos, it->second->rawSize);
|
||||
|
||||
if (textures.count(name)) pos = textures[name]->pos;
|
||||
else {
|
||||
std::cout << Log::err << "Invalid base texture \"" << name << "\"." << Log::endl;
|
||||
pos = textures["_missing"]->pos;
|
||||
}
|
||||
|
||||
return getBytesAtPos({ pos.x, pos.y }, { pos.z - pos.x, pos.w - pos.y });
|
||||
std::cout << Log::err << "Invalid base texture '" << name << "'." << Log::endl;
|
||||
let& missing = textures["_missing"];
|
||||
return getBytesAtPos(missing->rawPos, missing->rawSize);
|
||||
}
|
||||
|
||||
TextureAtlas::RawTexData TextureAtlas::getBytesAtPos(glm::ivec2 pos, glm::ivec2 dims) {
|
||||
RawTexData data{};
|
||||
data.width = dims.x;
|
||||
data.height = dims.y;
|
||||
TextureAtlas::RawTexData TextureAtlas::getBytesAtPos(uvec2 pos, uvec2 size) {
|
||||
RawTexData data {};
|
||||
data.size = size;
|
||||
|
||||
auto pixels = new unsigned char[data.width * data.height * 4];
|
||||
let pixels = new u8[size.x * size.y * 4];
|
||||
|
||||
for (int i = 0; i < data.width * data.height; i++) {
|
||||
int xx = pos.x + (i % data.width);
|
||||
int yy = pos.y + (i / data.width);
|
||||
for (u32 i = 0; i < size.x * size.y; i++) {
|
||||
u32 x = pos.x + (i % size.x);
|
||||
u32 y = pos.y + (i / size.y);
|
||||
|
||||
pixels[i * 4 + 0] = atlasData[xx * 4 + yy * (pixelSize.x * 4)];
|
||||
pixels[i * 4 + 1] = atlasData[xx * 4 + 1 + yy * (pixelSize.x * 4)];
|
||||
pixels[i * 4 + 2] = atlasData[xx * 4 + 2 + yy * (pixelSize.x * 4)];
|
||||
pixels[i * 4 + 3] = atlasData[xx * 4 + 3 + yy * (pixelSize.x * 4)];
|
||||
pixels[i * 4 + 0] = atlasData[x * 4 + y * (canvasSize.x * 4)];
|
||||
pixels[i * 4 + 1] = atlasData[x * 4 + 1 + y * (canvasSize.x * 4)];
|
||||
pixels[i * 4 + 2] = atlasData[x * 4 + 2 + y * (canvasSize.x * 4)];
|
||||
pixels[i * 4 + 3] = atlasData[x * 4 + 3 + y * (canvasSize.x * 4)];
|
||||
}
|
||||
|
||||
data.data = pixels;
|
||||
return data;
|
||||
}
|
||||
|
||||
glm::vec2 TextureAtlas::findImageSpace(int w, int h) {
|
||||
for (int j = 0; j < tileSize.y - (h - 1); j++) {
|
||||
for (int i = 0; i < tileSize.x - (w - 1); i++) {
|
||||
if (empty[j * tileSize.x + i]) {
|
||||
optional<u16vec2> TextureAtlas::findImageSpace(u16vec2 tileSize) {
|
||||
for (u16 j = 0; j < canvasTileSize.y - (tileSize.y - 1); j++) {
|
||||
for (u16 i = 0; i < canvasTileSize.x - (tileSize.x - 1); i++) {
|
||||
if (empty[j * canvasTileSize.x + i]) {
|
||||
bool space = true;
|
||||
|
||||
for (int k = 0; k < h; k++) {
|
||||
for (int l = 0; l < w; l++) {
|
||||
if (!empty[(j + k) * tileSize.x + (i + l)]) {
|
||||
for (int k = 0; k < tileSize.y; k++) {
|
||||
for (int l = 0; l < tileSize.x; l++) {
|
||||
if (!empty[(j + k) * canvasTileSize.x + (i + l)]) {
|
||||
space = false;
|
||||
break;
|
||||
}
|
||||
|
@ -272,25 +240,25 @@ glm::vec2 TextureAtlas::findImageSpace(int w, int h) {
|
|||
}
|
||||
|
||||
if (space) {
|
||||
for (int k = 0; k < h; k++) {
|
||||
for (int l = 0; l < w; l++) {
|
||||
empty[(j + k) * tileSize.x + (i + l)] = false;
|
||||
for (int k = 0; k < tileSize.y; k++) {
|
||||
for (int l = 0; l < tileSize.x; l++) {
|
||||
empty[(j + k) * canvasTileSize.x + (i + l)] = false;
|
||||
}
|
||||
}
|
||||
return glm::vec2(i, j);
|
||||
return u16vec2(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return glm::vec2(-1, -1);
|
||||
return {};
|
||||
}
|
||||
|
||||
void TextureAtlas::createMissingImage() {
|
||||
auto data = new unsigned char[16 * 4 * 16];
|
||||
for (int i = 0; i < 16 * 16; i++) {
|
||||
void TextureAtlas::createMissingTexture() {
|
||||
auto data = new u8[16 * 4 * 16];
|
||||
for (u16 i = 0; i < 16 * 16; i++) {
|
||||
|
||||
unsigned char m = 0;
|
||||
u8 m = 0;
|
||||
if ((i % 16 < 8) ^ ((i / 16) < 8)) m = 255;
|
||||
|
||||
data[i * 4 + 0] = m;
|
||||
|
@ -299,26 +267,23 @@ void TextureAtlas::createMissingImage() {
|
|||
data[i * 4 + 3] = 255;
|
||||
}
|
||||
|
||||
addImage(data, "_missing", true, 16, 16);
|
||||
addImage("_missing", true, u16vec2(16), data);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void TextureAtlas::updateAtlas(int tileX, int tileY, int texWidth, int texHeight, unsigned char* data) {
|
||||
int baseX = tileX * 16;
|
||||
int baseY = tileY * 16;
|
||||
void TextureAtlas::updateAtlas(u16vec2 pos, u16vec2 size, u8* data) {
|
||||
texture.updateTexture(pos.x, pos.y, size.x, size.y, data);
|
||||
|
||||
atlasTexture.updateTexture(baseX, baseY, texWidth, texHeight, data);
|
||||
|
||||
for (int i = 0; i < texWidth * texHeight * 4; i++) {
|
||||
int xx = (i / 4) % texWidth;
|
||||
int yy = (i / 4) / texWidth;
|
||||
int of = i % 4;
|
||||
for (u32 i = 0; i < size.x * size.y * 4; i++) {
|
||||
u32 x = (i / 4) % size.x;
|
||||
u32 y = (i / 4) / size.x;
|
||||
u32 of = i % 4;
|
||||
|
||||
atlasData[(baseX + xx + (baseY + yy) * pixelSize.x) * 4 + of] = data[(xx + yy * texWidth) * 4 + of];
|
||||
atlasData[(pos.x + x + (pos.y + y) * canvasSize.x) * 4 + of] = data[(x + y * size.x) * 4 + of];
|
||||
}
|
||||
}
|
||||
|
||||
void TextureAtlas::deleteImage(std::shared_ptr<AtlasRef> ref) {
|
||||
void TextureAtlas::deleteImage(sptr<AtlasRef> ref) {
|
||||
// Actually delete the image from the texture (for debugging)
|
||||
|
||||
//auto data = new unsigned char[ref->width * ref->height * 4];
|
||||
|
@ -330,11 +295,11 @@ void TextureAtlas::deleteImage(std::shared_ptr<AtlasRef> ref) {
|
|||
//updateAtlas(ref->tileX, ref->tileY, ref->width, ref->height, data);
|
||||
//delete[] data;
|
||||
|
||||
textureSlotsUsed -= ref->tileWidth * ref->tileHeight;
|
||||
textureSlotsUsed -= ref->size.x * ref->size.y;
|
||||
|
||||
for (float i = ref->tileX; i < ref->tileX + ref->tileWidth; i++) {
|
||||
for (float j = ref->tileY; j < ref->tileY + ref->tileHeight; j++) {
|
||||
empty[j * tileSize.x + i] = true;
|
||||
for (u32 x = ref->pos.x; x < ref->pos.x + ref->size.x; x++) {
|
||||
for (u32 y = ref->pos.y; y < ref->pos.y + ref->size.y; y++) {
|
||||
empty[y * canvasTileSize.x + x] = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +1,59 @@
|
|||
//
|
||||
// Created by aurailus on 16/04/19.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "util/Types.h"
|
||||
#include "client/graph/Texture.h"
|
||||
|
||||
class AtlasRef;
|
||||
|
||||
class TextureAtlas {
|
||||
public:
|
||||
struct RawTexData {
|
||||
unsigned char* data;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
public:
|
||||
struct RawTexData { u8* data; uvec2 size; };
|
||||
|
||||
TextureAtlas() = default;
|
||||
|
||||
explicit TextureAtlas(unsigned int width, unsigned int height = 0);
|
||||
explicit TextureAtlas(uvec2 size);
|
||||
|
||||
void update();
|
||||
|
||||
std::vector<std::shared_ptr<AtlasRef>>
|
||||
loadDirectory(const std::string& path, bool base = true, bool recursive = true);
|
||||
vec<sptr<AtlasRef>> loadDirectory(const string& path, bool base = true, bool recurse = true);
|
||||
|
||||
std::shared_ptr<AtlasRef> loadImage(const std::string& path, const std::string& name, bool base = false);
|
||||
sptr<AtlasRef> loadImage(const string& path, const string& name, bool base = false);
|
||||
|
||||
glm::vec4 sampleTexturePixel(const std::shared_ptr<AtlasRef>& atlasRef, glm::vec2 pixel);
|
||||
sptr<AtlasRef> addImage(const string& name, bool base, u16vec2 size, u8* data);
|
||||
|
||||
std::shared_ptr<AtlasRef> operator[](const std::string& name);
|
||||
sptr<AtlasRef> operator[](const string& name);
|
||||
|
||||
std::shared_ptr<AtlasRef>
|
||||
addImage(unsigned char* data, const std::string& name, bool base, int texWidth, int texHeight);
|
||||
vec4 getPixel(const sptr<AtlasRef>& ref, ivec2 pos);
|
||||
|
||||
std::shared_ptr<AtlasRef> generateCrackImage(const std::string& name, unsigned short crackLevel);
|
||||
sptr<AtlasRef> generateCrackImage(const string& name, u8 crackLevel);
|
||||
|
||||
glm::ivec2 pixelSize{};
|
||||
glm::ivec2 tileSize{};
|
||||
ivec2 canvasSize;
|
||||
ivec2 canvasTileSize;
|
||||
|
||||
Texture atlasTexture{};
|
||||
std::vector<unsigned char> atlasData;
|
||||
Texture texture {};
|
||||
vec<u8> atlasData;
|
||||
|
||||
unsigned int textureSlotsUsed = 0;
|
||||
unsigned int maxTextureSlots = 0;
|
||||
private:
|
||||
std::shared_ptr<AtlasRef> generateTexture(std::string req);
|
||||
u32 textureSlotsUsed = 0;
|
||||
u32 maxTextureSlots = 0;
|
||||
|
||||
private:
|
||||
sptr<AtlasRef> generateTexture(string req);
|
||||
|
||||
RawTexData getBytesOfTex(const std::string& name);
|
||||
RawTexData getBytesOfTex(const string& name);
|
||||
|
||||
RawTexData getBytesAtPos(glm::ivec2 pos, glm::ivec2 dims);
|
||||
RawTexData getBytesAtPos(uvec2 pos, uvec2 size);
|
||||
|
||||
glm::vec2 findImageSpace(int w, int h);
|
||||
optional<u16vec2> findImageSpace(u16vec2 tileSize);
|
||||
|
||||
void createMissingImage();
|
||||
void createMissingTexture();
|
||||
|
||||
void updateAtlas(int tileX, int tileY, int texWidth, int texHeight, unsigned char* data);
|
||||
void updateAtlas(u16vec2 pos, u16vec2 size, u8* data);
|
||||
|
||||
void deleteImage(std::shared_ptr<AtlasRef> ref);
|
||||
void deleteImage(sptr<AtlasRef> ref);
|
||||
|
||||
std::map<std::string, std::shared_ptr<AtlasRef>> textures;
|
||||
std::vector<bool> empty;
|
||||
vec<bool> empty;
|
||||
std::unordered_map<string, sptr<AtlasRef>> textures;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,22 +4,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
#include "util/Util.h"
|
||||
|
||||
struct AtlasRef {
|
||||
int tileX = 0;
|
||||
int tileY = 0;
|
||||
int tileWidth = 0;
|
||||
int tileHeight = 0;
|
||||
u16vec2 pos {};
|
||||
u16vec2 size {};
|
||||
uvec2 rawPos {};
|
||||
uvec2 rawSize {};
|
||||
vec4 uv {};
|
||||
|
||||
string name = "";
|
||||
bool base = false;
|
||||
|
||||
glm::vec4 pos{};
|
||||
glm::vec4 uv{};
|
||||
std::string name = "";
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -44,11 +44,11 @@ void CraftItemDef::createModel(TextureAtlas& atlas) {
|
|||
for (unsigned int i = 0; i < 16 * 16; i++) {
|
||||
glm::vec2 samplePos = { i % 16, i / 16 };
|
||||
glm::vec2 off{ samplePos.x / 16.f, samplePos.y / 16.f };
|
||||
glm::vec4 col = atlas.sampleTexturePixel(ref, samplePos);
|
||||
glm::vec4 col = atlas.getPixel(ref, samplePos);
|
||||
|
||||
if (col.w < 0.5) continue;
|
||||
|
||||
if (samplePos.y == 0 || atlas.sampleTexturePixel(ref, { samplePos.x, samplePos.y - 1 }).w < 0.5) {
|
||||
if (samplePos.y == 0 || atlas.getPixel(ref, { samplePos.x, samplePos.y - 1 }).w < 0.5) {
|
||||
std::vector<EntityVertex> myVerts = {
|
||||
{{ -xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}},
|
||||
{{ -xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}},
|
||||
|
@ -61,7 +61,7 @@ void CraftItemDef::createModel(TextureAtlas& atlas) {
|
|||
indOffset += 4;
|
||||
}
|
||||
|
||||
if (samplePos.y == 15 || atlas.sampleTexturePixel(ref, { samplePos.x, samplePos.y + 1 }).w < 0.5) {
|
||||
if (samplePos.y == 15 || atlas.getPixel(ref, { samplePos.x, samplePos.y + 1 }).w < 0.5) {
|
||||
std::vector<EntityVertex> myVerts = {
|
||||
{{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}},
|
||||
{{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}},
|
||||
|
@ -74,7 +74,7 @@ void CraftItemDef::createModel(TextureAtlas& atlas) {
|
|||
indOffset += 4;
|
||||
}
|
||||
|
||||
if (samplePos.x == 0 || atlas.sampleTexturePixel(ref, { samplePos.x - 1, samplePos.y }).w < 0.5) {
|
||||
if (samplePos.x == 0 || atlas.getPixel(ref, { samplePos.x - 1, samplePos.y }).w < 0.5) {
|
||||
std::vector<EntityVertex> myVerts = {
|
||||
{{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}},
|
||||
{{ -xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}},
|
||||
|
@ -87,7 +87,7 @@ void CraftItemDef::createModel(TextureAtlas& atlas) {
|
|||
indOffset += 4;
|
||||
}
|
||||
|
||||
if (samplePos.x == 15 || atlas.sampleTexturePixel(ref, { samplePos.x + 1, samplePos.y }).w < 0.5) {
|
||||
if (samplePos.x == 15 || atlas.getPixel(ref, { samplePos.x + 1, samplePos.y }).w < 0.5) {
|
||||
std::vector<EntityVertex> myVerts = {
|
||||
{{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}},
|
||||
{{ -xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}},
|
||||
|
|
|
@ -5,30 +5,30 @@
|
|||
#include "LocalLuaParser.h"
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "ErrorFormatter.h"
|
||||
#include "lua/ModException.h"
|
||||
#include "register/RegisterItem.h"
|
||||
#include "register/RegisterBlock.h"
|
||||
#include "register/RegisterBiome.h"
|
||||
#include "register/RegisterKeybind.h"
|
||||
#include "lua/ErrorFormatter.h"
|
||||
#include "lua/register/RegisterItem.h"
|
||||
#include "lua/register/RegisterBlock.h"
|
||||
#include "lua/register/RegisterBiome.h"
|
||||
#include "lua/register/RegisterKeybind.h"
|
||||
|
||||
// Usertypes
|
||||
#include "usertype/Target.h"
|
||||
#include "usertype/Player.h"
|
||||
#include "usertype/Entity.h"
|
||||
#include "usertype/Inventory.h"
|
||||
#include "usertype/Dimension.h"
|
||||
#include "usertype/ItemStack.h"
|
||||
#include "usertype/InventoryList.h"
|
||||
#include "usertype/AnimationManager.h"
|
||||
|
||||
#include "usertype/GuiElement.h"
|
||||
#include "lua/usertype/Target.h"
|
||||
#include "lua/usertype/Player.h"
|
||||
#include "lua/usertype/Entity.h"
|
||||
#include "lua/usertype/Inventory.h"
|
||||
#include "lua/usertype/Dimension.h"
|
||||
#include "lua/usertype/ItemStack.h"
|
||||
#include "lua/usertype/GuiElement.h"
|
||||
#include "lua/usertype/KeyObserver.h"
|
||||
#include "lua/usertype/InventoryList.h"
|
||||
#include "lua/usertype/AnimationManager.h"
|
||||
|
||||
// Modules
|
||||
#include "modules/Time.h"
|
||||
#include "modules/Message.h"
|
||||
#include "modules/Dimension.h"
|
||||
#include "modules/Structure.h"
|
||||
#include "lua/modules/Time.h"
|
||||
#include "lua/modules/Message.h"
|
||||
#include "lua/modules/Dimension.h"
|
||||
#include "lua/modules/Structure.h"
|
||||
|
||||
// Util
|
||||
#include "lua/register/CreateRegister.h"
|
||||
|
@ -37,9 +37,10 @@ LocalLuaParser::LocalLuaParser(LocalSubgame& game) : LuaParser(game) {}
|
|||
|
||||
void LocalLuaParser::init(WorldPtr world, PlayerPtr player, Client& client) {
|
||||
this->client = &client;
|
||||
this->player = player;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::debug);
|
||||
|
||||
loadApi(world, player);
|
||||
loadApi(world);
|
||||
|
||||
try {
|
||||
runFileSandboxed("base/init");
|
||||
|
@ -87,8 +88,6 @@ void LocalLuaParser::init(WorldPtr world, PlayerPtr player, Client& client) {
|
|||
|
||||
throw ModException(err);
|
||||
}
|
||||
|
||||
// client.renderer.window.input.setCallback(Util::bind_this(&keybinds, &LuaKeybindHandler::keybindHandler));
|
||||
}
|
||||
|
||||
void LocalLuaParser::update(double delta) {
|
||||
|
@ -108,7 +107,17 @@ void LocalLuaParser::setModLoadOrder(const vec<string> order) {
|
|||
modLoadOrder = order;
|
||||
}
|
||||
|
||||
void LocalLuaParser::loadApi(WorldPtr world, PlayerPtr player) {
|
||||
void LocalLuaParser::addKBObserver(usize id) {
|
||||
kbObservers.emplace(id);
|
||||
player.l()->setKBIndicatorVisible(true);
|
||||
}
|
||||
|
||||
void LocalLuaParser::removeKBObserver(usize id) {
|
||||
kbObservers.erase(id);
|
||||
player.l()->setKBIndicatorVisible(kbObservers.size());
|
||||
}
|
||||
|
||||
void LocalLuaParser::loadApi(WorldPtr world) {
|
||||
//Create Zepha Table
|
||||
core = lua.create_table();
|
||||
lua["zepha"] = core;
|
||||
|
@ -124,6 +133,7 @@ void LocalLuaParser::loadApi(WorldPtr world, PlayerPtr player) {
|
|||
Api::Usertype::GuiElement::bind(lua, core, player.l()->getRoot());
|
||||
Api::Usertype::InventoryList::bind(Api::State::CLIENT, lua, core);
|
||||
Api::Usertype::LocalAnimationManager::bind(Api::State::CLIENT, lua, core);
|
||||
Api::Usertype::KeyObserver::bind(lua, core, client->renderer.window.input, *this);
|
||||
|
||||
core["client"] = true;
|
||||
core["player"] = Api::Usertype::LocalPlayer(player);
|
||||
|
@ -191,4 +201,4 @@ sol::protected_function_result LocalLuaParser::runFileSandboxed(const std::strin
|
|||
return res;
|
||||
}
|
||||
throw std::runtime_error("Error opening \"" + file + "\", file not found.");
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "lua/LuaParser.h"
|
||||
|
@ -30,15 +31,21 @@ public:
|
|||
|
||||
void setModLoadOrder(const vec<string> order);
|
||||
|
||||
void addKBObserver(usize id);
|
||||
|
||||
void removeKBObserver(usize id);
|
||||
|
||||
private:
|
||||
void loadApi(WorldPtr world, PlayerPtr player);
|
||||
void loadApi(WorldPtr world);
|
||||
|
||||
sol::protected_function_result runFileSandboxed(const std::string& file);
|
||||
|
||||
Client* client;
|
||||
PlayerPtr player;
|
||||
double accumulatedDelta = 0;
|
||||
|
||||
vec<CallbackRef> refs;
|
||||
vec<string> modLoadOrder {};
|
||||
std::unordered_set<usize> kbObservers {};
|
||||
std::unordered_map<string, LuaMod> mods {};
|
||||
};
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <gzip/compress.hpp>
|
||||
#include <stb_image.h>
|
||||
#include <cute_files.h>
|
||||
#include <gzip/compress.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "ServerModHandler.h"
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "lua/Lua.h"
|
||||
|
||||
#include "util/Types.h"
|
||||
|
||||
namespace Gui {
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "KeyObserver.h"
|
||||
|
||||
#include "client/Input.h"
|
||||
#include "lua/LocalLuaParser.h"
|
||||
|
||||
usize Api::Usertype::KeyObserver::ID_NEXT = 0;
|
||||
|
||||
void Api::Usertype::KeyObserver::start() {
|
||||
if (nativeCBs.size()) return;
|
||||
parser.addKBObserver(id);
|
||||
nativeCBs.emplace_back(input.events.bind(Input::CBType::KEY, [&](i32 key, u32 state) {
|
||||
if (state == GLFW_PRESS && on_press) on_press(key);
|
||||
else if (state == GLFW_RELEASE && on_release) on_release(key);
|
||||
}));
|
||||
}
|
||||
|
||||
void Api::Usertype::KeyObserver::stop() {
|
||||
parser.removeKBObserver(id);
|
||||
nativeCBs.clear();
|
||||
}
|
||||
|
||||
Api::Usertype::KeyObserver::~KeyObserver() {
|
||||
stop();
|
||||
}
|
||||
|
||||
void Api::Usertype::KeyObserver::bind(sol::state& lua, sol::table& core, Input& input, LocalLuaParser& parser) {
|
||||
lua.new_usertype<KeyObserver>("KeyObserver",
|
||||
sol::meta_function::construct, sol::factories([&]() {
|
||||
return make_shared<KeyObserver>(input, parser);
|
||||
}),
|
||||
|
||||
"start", &KeyObserver::start,
|
||||
"stop", &KeyObserver::stop,
|
||||
|
||||
"on_press", &KeyObserver::on_press,
|
||||
"on_release", &KeyObserver::on_release,
|
||||
"on_change", &KeyObserver::on_change
|
||||
);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "lua/Lua.h"
|
||||
#include "util/Types.h"
|
||||
#include "client/Callback.h"
|
||||
|
||||
class Input;
|
||||
class LocalLuaParser;
|
||||
|
||||
namespace Api::Usertype {
|
||||
class KeyObserver {
|
||||
public:
|
||||
KeyObserver(Input& input, LocalLuaParser& parser): input(input), parser(parser), id(ID_NEXT++) {}
|
||||
|
||||
~KeyObserver();
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
static void bind(sol::state& lua, sol::table& core, Input& input, LocalLuaParser& parser);
|
||||
|
||||
private:
|
||||
sol::protected_function on_press = sol::nil;
|
||||
sol::protected_function on_release = sol::nil;
|
||||
sol::protected_function on_change = sol::nil;
|
||||
|
||||
vec<CallbackRef> nativeCBs {};
|
||||
|
||||
usize id = 0;
|
||||
bool active = false;
|
||||
|
||||
Input& input;
|
||||
LocalLuaParser& parser;
|
||||
|
||||
static usize ID_NEXT;
|
||||
};
|
||||
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
/** Checks if boxes or points are within the camera's frustum cone. */
|
||||
class Frustum {
|
||||
private:
|
||||
enum class Direction : uint8_t {
|
||||
enum class Direction : u8 {
|
||||
TOP = 0,
|
||||
BOTTOM,
|
||||
LEFT,
|
||||
|
|
|
@ -79,7 +79,7 @@ void NetHandler::initClient(Address hostAddress, int attempts, int timeout) {
|
|||
ENetEvent event;
|
||||
if (enet_host_service(host, &event, (enet_uint32) timeout) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) {
|
||||
std::cout << Log::info << "Connected to "
|
||||
<< NetHandler::intToIPString(*reinterpret_cast<unsigned int*>(&event.peer->address.host))
|
||||
<< NetHandler::intToIPString(*reinterpret_cast<u32*>(&event.peer->address.host))
|
||||
<< ":" << event.peer->address.port << "." << Log::endl;
|
||||
state = NetState::CLIENT;
|
||||
break;
|
||||
|
|
|
@ -18,8 +18,8 @@ std::tuple<glm::vec3, glm::vec3> Collision::applyVel(SubgamePtr game, DimensionP
|
|||
const SelectionBox& collisionBox, glm::vec3 pos, glm::vec3 vel, float delta) {
|
||||
constexpr static double INC = 0.05;
|
||||
|
||||
for (unsigned char i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < std::abs(vel[i] * delta) / INC; j++) {
|
||||
for (u8 i = 0; i < 3; i++) {
|
||||
for (u32 j = 0; j < std::abs(vel[i] * delta) / INC; j++) {
|
||||
double moveAmount = std::max(std::min(INC, std::abs(vel[i] * delta) - (j * INC)), 0.);
|
||||
|
||||
glm::vec3 newPos = pos;
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
#include "world/dim/chunk/Chunk.h"
|
||||
#include "game/atlas/DefinitionAtlas.h"
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
MapGen::MapGen(Subgame& game, World& world, u32 seed, std::unordered_set<string> biomes) :
|
||||
game(game), world(world), props(seed) {
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
//
|
||||
// Created by aurailus on 2020-04-05.
|
||||
//
|
||||
|
||||
#include "MapGenProps.h"
|
||||
|
||||
MapGenProps::MapGenProps(unsigned int seed) : seed(seed) {
|
||||
MapGenProps::MapGenProps(u32 seed) : seed(seed) {
|
||||
/*temperatureBase.SetSeed(seed);
|
||||
temperatureBase.SetFrequency(0.02);
|
||||
temperatureBase.SetOctaveCount(4);
|
||||
|
|
|
@ -1,26 +1,10 @@
|
|||
//
|
||||
// Created by aurailus on 2020-04-05.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
//#include <libnoise/noise.h>
|
||||
#include "util/Util.h"
|
||||
|
||||
class MapGenProps {
|
||||
public:
|
||||
MapGenProps(unsigned int seed);
|
||||
public:
|
||||
MapGenProps(u32 seed);
|
||||
|
||||
unsigned int seed;
|
||||
|
||||
/*noise::module::Perlin temperatureBase;
|
||||
noise::module::Turbulence temperatureTurbulence;
|
||||
noise::module::ScaleBias temperature;
|
||||
|
||||
noise::module::Perlin humidityBase;
|
||||
noise::module::Turbulence humidityTurbulence;
|
||||
noise::module::ScaleBias humidity;
|
||||
|
||||
noise::module::Perlin roughnessBase;
|
||||
noise::module::Turbulence roughnessTurbulence;
|
||||
noise::module::ScaleBias roughness;*/
|
||||
u32 seed;
|
||||
};
|
||||
|
|
|
@ -20,6 +20,13 @@ LocalPlayer::LocalPlayer(SubgamePtr game, LocalWorld& world, DimensionPtr dim, R
|
|||
hud(root.body->append<Gui::BoxElement>({{ { Gui::Prop::CLASS, vec<string> { "_GUI_ROOT" } } }})),
|
||||
menu(root.body->append<Gui::BoxElement>({{ { Gui::Prop::CLASS, vec<string> { "_GUI_ROOT" } } }})),
|
||||
debug(root.body->append<Gui::BoxElement>({{ { Gui::Prop::CLASS, vec<string> { "_GUI_ROOT" } } }})),
|
||||
indicators(root.body->append<Gui::BoxElement>({{ { Gui::Prop::CLASS, vec<string> { "_GUI_ROOT" } } }})),
|
||||
kbIndicator(indicators->append<Gui::BoxElement>({{
|
||||
{ Gui::Prop::VISIBLE, false },
|
||||
{ Gui::Prop::BACKGROUND, string("key_observing") },
|
||||
{ Gui::Prop::POS, array<Gui::Expression, 2> { Gui::Expression("100cw - 100sw - 2dp"), Gui::Expression("100ch - 100sh - 2dp") } },
|
||||
{ Gui::Prop::SIZE, array<Gui::Expression, 2> { Gui::Expression("20px * 2"), Gui::Expression("16px * 2") } }
|
||||
}})),
|
||||
wireframe(game, dim, { 1, 1, 1 }),
|
||||
renderer(renderer) {
|
||||
handItemModel.parent = &handModel;
|
||||
|
@ -30,6 +37,10 @@ LocalPlayer::LocalPlayer(SubgamePtr game, LocalWorld& world, DimensionPtr dim, R
|
|||
{ Gui::Prop::SIZE, array<Gui::Expression, 2> { Gui::Expression("100cw"), Gui::Expression("100ch") }}
|
||||
}}}
|
||||
});
|
||||
|
||||
debug->setProp(Gui::Prop::VISIBLE, false);
|
||||
|
||||
indicators->append<Gui::BoxElement>();
|
||||
}
|
||||
|
||||
void LocalPlayer::update(f64 delta, vec2 mouseDelta) {
|
||||
|
@ -48,8 +59,7 @@ void LocalPlayer::update(f64 delta, vec2 mouseDelta) {
|
|||
findTarget();
|
||||
updateWireframe();
|
||||
|
||||
// if (!gameGui.isInMenu())
|
||||
updateInteract(delta);
|
||||
if (!isInMenu()) updateInteract(delta);
|
||||
}
|
||||
|
||||
string LocalPlayer::getUsername() {
|
||||
|
@ -139,6 +149,11 @@ void LocalPlayer::setHudVisible(bool visible) {
|
|||
// gameGui.setVisible(hudVisible);
|
||||
}
|
||||
|
||||
void LocalPlayer::setKBIndicatorVisible(bool visible) {
|
||||
kbIndicator->setProp(Gui::Prop::VISIBLE, visible);
|
||||
kbIndicator->updateElement();
|
||||
}
|
||||
|
||||
void LocalPlayer::draw(Renderer&) {
|
||||
wireframe.draw(renderer);
|
||||
handItemModel.draw(renderer);
|
||||
|
@ -151,6 +166,7 @@ void LocalPlayer::drawHud(Renderer&) {
|
|||
|
||||
void LocalPlayer::drawMenu(Renderer&) {
|
||||
menu->draw(renderer);
|
||||
indicators->draw(renderer);
|
||||
}
|
||||
|
||||
void LocalPlayer::assertField(Packet packet) {
|
||||
|
@ -222,6 +238,7 @@ void LocalPlayer::handleAssertion(Deserializer& d) {
|
|||
}
|
||||
|
||||
bool LocalPlayer::getKey(LocalPlayer::PlayerControl control) {
|
||||
if (isInMenu()) return false;
|
||||
return renderer.window.input.isKeyDown(
|
||||
control == PlayerControl::FORWARD ? GLFW_KEY_COMMA :
|
||||
control == PlayerControl::BACKWARD ? GLFW_KEY_O :
|
||||
|
|
|
@ -80,6 +80,9 @@ public:
|
|||
/** Sets whether or not the hud should be visible. */
|
||||
void setHudVisible(bool visible);
|
||||
|
||||
/** Sets whether or not the KBIndicator is visible. */
|
||||
void setKBIndicatorVisible(bool visible);
|
||||
|
||||
/** Draws the player's target wireframe and held item. */
|
||||
void draw(Renderer& renderer) override;
|
||||
|
||||
|
@ -122,7 +125,7 @@ private:
|
|||
Gui::Root root;
|
||||
|
||||
/** Element roots for the hud and menu, respectively. */
|
||||
sptr<Gui::BoxElement> hud, menu, debug;
|
||||
sptr<Gui::BoxElement> hud, menu, debug, indicators, kbIndicator;
|
||||
|
||||
/** A reference to the renderer. */
|
||||
Renderer& renderer;
|
||||
|
|
|
@ -24,13 +24,42 @@ local chat_menu = zepha.Gui.Box {
|
|||
zepha.Gui.Box {
|
||||
id = 'chat_input',
|
||||
size = { '256dp', '10dp' },
|
||||
pos = { '0dp', 3 + max_messages * 8 .. 'dp' }
|
||||
pos = { '0dp', 3 + max_messages * 8 .. 'dp' },
|
||||
|
||||
zepha.Gui.Text {
|
||||
id = 'chat_input_text',
|
||||
pos = '2dp',
|
||||
text_size = '2px',
|
||||
content = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local chat_menu_box = chat_menu:get('chat_box')
|
||||
local chat_menu_tabs = chat_menu:get('chat_tabs')
|
||||
local chat_menu_input = chat_menu:get('chat_input')
|
||||
local chat_menu_input_text = chat_menu:get('chat_input_text')
|
||||
|
||||
local chat_buffer = ''
|
||||
local pipe = '`r` `c1|'
|
||||
local has_pipe = false
|
||||
local observer = KeyObserver.new()
|
||||
observer.on_press = function(keycode)
|
||||
local key = zepha.keycodes[keycode]
|
||||
if key == 'enter' then return
|
||||
elseif key == 'space' then chat_buffer = chat_buffer .. ' '
|
||||
elseif key == 'backspace' then chat_buffer = chat_buffer:sub(1, chat_buffer:len() - 1)
|
||||
else chat_buffer = chat_buffer .. key end
|
||||
|
||||
chat_menu_input_text.content = chat_buffer .. (has_pipe and pipe or '')
|
||||
end
|
||||
|
||||
zepha.after(function()
|
||||
if not chat.open then return true end
|
||||
has_pipe = not has_pipe
|
||||
chat_menu_input_text.content = chat_buffer .. (has_pipe and pipe or '')
|
||||
return true
|
||||
end, 0.5)
|
||||
|
||||
-- Rerenders the chat gui.
|
||||
chat._refresh = function()
|
||||
|
@ -104,6 +133,13 @@ chat.set_open = function(open)
|
|||
if open == nil then chat.open = not chat.open
|
||||
else chat.open = open end
|
||||
|
||||
if chat.open then
|
||||
observer:start()
|
||||
else
|
||||
observer:stop()
|
||||
chat_buffer = ''
|
||||
end
|
||||
|
||||
zepha.player.menu = chat.open and chat_menu or nil
|
||||
|
||||
chat._refresh()
|
||||
|
@ -113,5 +149,19 @@ end
|
|||
zepha.register_keybind(":open_chat", {
|
||||
description = "Open Chat",
|
||||
default = zepha.keys.p,
|
||||
on_press = chat.set_open
|
||||
on_press = function()
|
||||
if chat.open then return end
|
||||
chat.set_open()
|
||||
end
|
||||
})
|
||||
|
||||
-- Keyboard shortcut to send the message
|
||||
zepha.register_keybind(":send_message", {
|
||||
description = "Send Message",
|
||||
default = zepha.keys.enter,
|
||||
on_press = function()
|
||||
if not chat.open then return end
|
||||
chat.send(chat_buffer)
|
||||
chat.set_open()
|
||||
end
|
||||
})
|
|
@ -1,12 +1,13 @@
|
|||
zepha.register_block(":wood", {
|
||||
name = "Log",
|
||||
|
||||
model = "base:block",
|
||||
model = "base:pillar",
|
||||
textures = {
|
||||
"zeus:default:oak_log_top",
|
||||
"zeus:default:oak_log_top",
|
||||
"zeus:default:oak_log_side"
|
||||
"zeus:default:oak_log_side_pillar"
|
||||
},
|
||||
culls = false,
|
||||
|
||||
tool_props = {
|
||||
health = 30,
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
require(_PATH .. "blocks/index")
|
||||
require(_PATH .. "entity/index")
|
||||
|
||||
local chat_down = false
|
||||
zepha.register_keybind("zeus:default:open_chat", {
|
||||
description = "Open Chat",
|
||||
default = zepha.keys.t,
|
||||
on_press = function() print "Opened chat!" end
|
||||
})
|
||||
|
||||
-- Flying toggles
|
||||
local function toggleFlying()
|
||||
zepha.player.flying = not zepha.player.flying
|
||||
|
@ -19,7 +12,7 @@ zepha.register_keybind("zeus:default:toggle_flying", {
|
|||
on_press = toggleFlying
|
||||
})
|
||||
|
||||
local last_press = -100
|
||||
local last_press = -1
|
||||
zepha.register_keybind("zeus:default:double_jump_fly", {
|
||||
description = "Double Jump to Toggle Flying",
|
||||
default = zepha.keys.space,
|
||||
|
|
Loading…
Reference in New Issue