Faster atlas creation

Block selection
Chunk de/compression now uses internal buffer directly (0-copy)
Optimized Chunk vertices list order (faster vert access from GPU cache)
F5 Debug info: added triangle count
Implemented ladder climb
Road + jump pad makes you jump farther
Fixed bad fog color blending (alpha-channel)
Changed LZFX and enet compilation to Release, -O3
master
Dorian Wouters 2015-03-28 14:31:39 +01:00
parent 8e0e3babde
commit f2062d6fe7
58 changed files with 499 additions and 410 deletions

View File

@ -1,8 +1,13 @@
#include "AtlasCreator.hpp"
#include "stb_image.h"
//#include <chrono>
#include <cmath>
#include <stdexcept>
#include <cstring>
#define ENABLE_TIMING 0
#if ENABLE_TIMING
#include <chrono>
#endif
namespace Diggler {
@ -14,7 +19,7 @@ AtlasCreator::AtlasCreator(int w, int h, int uw, int uh) : atlasWidth(w), atlasH
throw std::invalid_argument("Atlas W/H is not divisor of Coord's type");
atlasData = new uint8[w * h * 4];
std::fill_n(atlasData, w * h * 4, static_cast<uint8>(0));
memset(atlasData, w * h * 4, 0);
}
AtlasCreator::Coord AtlasCreator::add(const std::string& path) {
@ -62,16 +67,18 @@ AtlasCreator::Coord AtlasCreator::add(int width, int height, int channels, const
targetY = lastY;
}
//auto t1 = std::chrono::high_resolution_clock::now();
#if ENABLE_TIMING
auto t1 = std::chrono::high_resolution_clock::now();
#endif
// Blit the texture onto the atlas
for(int sourceY = 0; sourceY < height; ++sourceY) {
int fromPad = sourceY * width;
int toPad = (targetY + sourceY) * atlasWidth;
memcpy(&atlasData[(toPad+targetX)*4], &data[fromPad*4], width*4);
#if 0 // For platforms where memcpy would be slow
for(int sourceX = 0; sourceX < width; sourceX += 2) {
int from = (fromPad + sourceX) * 4;
int to = (toPad + (targetX + sourceX)) * 4;
// MMX-like copy, fast (actual MMX/SSE would be f'kin fast)
#if HAS_NATIVE_64BIT
*((int64*)(&atlasData[to])) = *((int64*)(&data[from]));
#else
@ -79,9 +86,12 @@ AtlasCreator::Coord AtlasCreator::add(int width, int height, int channels, const
*((int32*)(&atlasData[to + 4])) = *((int32*)(&data[from + 4]));
#endif
}
#endif
}
//auto t2 = std::chrono::high_resolution_clock::now();
//getDebugStream() << std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count() << std::endl;
#if ENABLE_TIMING
auto t2 = std::chrono::high_resolution_clock::now();
getDebugStream() << std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count() << std::endl;
#endif
lastX = targetX + unitWidth;
lastY = targetY;

View File

@ -1,31 +1,64 @@
#include "Blocks.hpp"
#include "GlobalProperties.hpp"
#include "stb_perlin.h"
#define NON 0x0
#define RED Blocks::TeamRed
#define BLU Blocks::TeamBlue
#define ANY (RED | BLU)
namespace Diggler {
BlockTex sideTextures[(int)BlockType::LAST][6] = {
/* Air */ {BlockTex::None, BlockTex::None, BlockTex::None, BlockTex::None, BlockTex::None, BlockTex::None},
/* Dirt */ {BlockTex::Dirt, BlockTex::Dirt, BlockTex::Dirt, BlockTex::Dirt, BlockTex::Dirt, BlockTex::Dirt},
/* Ore */ {BlockTex::Ore, BlockTex::Ore, BlockTex::Ore, BlockTex::Ore, BlockTex::Ore, BlockTex::Ore},
/* Gold */ {BlockTex::Gold, BlockTex::Gold, BlockTex::Gold, BlockTex::Gold, BlockTex::Gold, BlockTex::Gold},
/*Diamond*/ {BlockTex::Diamond, BlockTex::Diamond, BlockTex::Diamond, BlockTex::Diamond, BlockTex::Diamond, BlockTex::Diamond},
/* Rock */ {BlockTex::Rock, BlockTex::Rock, BlockTex::Rock, BlockTex::Rock, BlockTex::Rock, BlockTex::Rock},
/* Ladder */{BlockTex::Ladder, BlockTex::Ladder, BlockTex::LadderTop, BlockTex::LadderTop, BlockTex::Ladder, BlockTex::Ladder},
/* TNT*/ {BlockTex::Explosive, BlockTex::Explosive, BlockTex::Explosive, BlockTex::Explosive, BlockTex::Explosive, BlockTex::Explosive},
/* Jump */ {BlockTex::Jump, BlockTex::Jump, BlockTex::JumpTop, BlockTex::TeleBottom, BlockTex::Jump, BlockTex::Jump},
/* Shock */ {BlockTex::TeleSideA, BlockTex::TeleSideA, BlockTex::TeleBottom, BlockTex::Spikes, BlockTex::TeleSideB, BlockTex::TeleSideB},
/*BankRed*/ {BlockTex::BankFrontRed, BlockTex::BankBackRed, BlockTex::BankTopRed, BlockTex::BankTopRed, BlockTex::BankLeftRed, BlockTex::BankRightRed},
/*BankBlue*/{BlockTex::BankFrontBlue, BlockTex::BankBackBlue, BlockTex::BankTopBlue, BlockTex::BankTopBlue, BlockTex::BankLeftBlue, BlockTex::BankRightBlue},
/*BeaconR*/ {BlockTex::TeleSideA, BlockTex::TeleSideA, BlockTex::BeaconRed, BlockTex::LadderTop, BlockTex::TeleSideB, BlockTex::TeleSideB},
/*BeaconB*/ {BlockTex::TeleSideA, BlockTex::TeleSideA, BlockTex::BeaconBlue, BlockTex::LadderTop, BlockTex::TeleSideB, BlockTex::TeleSideB},
/* Road */ {BlockTex::Road, BlockTex::Road, BlockTex::Road, BlockTex::Road, BlockTex::Road, BlockTex::Road},
/* SolidR */{BlockTex::SolidRed, BlockTex::SolidRed, BlockTex::SolidRed, BlockTex::SolidRed, BlockTex::SolidRed, BlockTex::SolidRed},
/* SolidB */{BlockTex::SolidBlue, BlockTex::SolidBlue, BlockTex::SolidBlue, BlockTex::SolidBlue, BlockTex::SolidBlue, BlockTex::SolidBlue},
/* Metal */ {BlockTex::Metal, BlockTex::Metal, BlockTex::Metal, BlockTex::Metal, BlockTex::Metal, BlockTex::Metal},
/*DirtSign*/{BlockTex::DirtSign, BlockTex::DirtSign, BlockTex::DirtSign, BlockTex::DirtSign, BlockTex::DirtSign, BlockTex::DirtSign},
/* Lava */ {BlockTex::Lava, BlockTex::Lava, BlockTex::Lava, BlockTex::Lava, BlockTex::Lava, BlockTex::Lava},
/* TransR */{BlockTex::TransRed, BlockTex::TransRed, BlockTex::TransRed, BlockTex::TransRed, BlockTex::TransRed, BlockTex::TransRed},
/* TransB */{BlockTex::TransBlue, BlockTex::TransBlue, BlockTex::TransBlue, BlockTex::TransBlue, BlockTex::TransBlue, BlockTex::TransBlue},
typedef BlockType Type;
const Blocks::TypeInfo Blocks::TypeInfos[(int)Type::LAST] = {
{Type::Air, "Air", 0, 0, 0, NON, "deconstruction.png"},
{Type::Dirt, "Dirt", 0, 0, 0, NON, nullptr},
{Type::Ore, "Ore", 0, 25, 0, NON, nullptr},
{Type::Gold, "Gold", 100, 0, 0, NON, nullptr},
{Type::Diamond, "Diamond", 1000, 25, 0, NON, nullptr},
{Type::Rock, "Rock", 0, 0, 0, NON, nullptr},
{Type::Ladder, "Ladder", 0, 0, 25, ANY, "ladder.png"},
{Type::Explosive, "Explosives", 0, 0, 100, ANY, "explosive.png"},
{Type::Jump, "Jump pad", 0, 0, 25, ANY, "jump.png"},
{Type::Shock, "Shock Block", 0, 0, 50, ANY, "spikes.png"},
{Type::BankRed, "Bank", 0, 0, 50, RED, "bank_red.png"},
{Type::BankBlue, "Bank", 0, 0, 50, BLU, "bank_blue.png"},
{Type::BeaconRed, "Beacon", 0, 0, 50, RED, "beacon.png"},
{Type::BeaconBlue, "Beacon", 0, 0, 50, BLU, "beacon.png"},
{Type::Road, "Road", 0, 0, 10, ANY, "road.png"},
{Type::SolidRed, "Solid Block", 0, 0, 10, RED, "solid_red.png"},
{Type::SolidBlue, "Solid Block", 0, 0, 10, BLU, "solid_blue.png"},
{Type::Metal, "Metal Block", 0, 0, 0, NON, "metal.png"},
{Type::DirtSign, "Dirt", 0, 0, 0, NON, nullptr},
{Type::Lava, "Lava", 0, 0, 0, NON, nullptr},
{Type::TransRed, "Force Field", 0, 0, 25, ANY, "translucent_red.png"},
{Type::TransBlue, "Force Field", 0, 0, 25, ANY, "translucent_blue.png"}
};
typedef BlockTex Tex;
const Tex sideTextures[(int)Type::LAST][6] = {
/* Air */ {Tex::None, Tex::None, Tex::None, Tex::None, Tex::None, Tex::None},
/* Dirt */ {Tex::Dirt, Tex::Dirt, Tex::Dirt, Tex::Dirt, Tex::Dirt, Tex::Dirt},
/* Ore */ {Tex::Ore, Tex::Ore, Tex::Ore, Tex::Ore, Tex::Ore, Tex::Ore},
/* Gold */ {Tex::Gold, Tex::Gold, Tex::Gold, Tex::Gold, Tex::Gold, Tex::Gold},
/*Diamond*/ {Tex::Diamond, Tex::Diamond, Tex::Diamond, Tex::Diamond, Tex::Diamond, Tex::Diamond},
/* Rock */ {Tex::Rock, Tex::Rock, Tex::Rock, Tex::Rock, Tex::Rock, Tex::Rock},
/* Ladder */{Tex::Ladder, Tex::Ladder, Tex::LadderTop, Tex::LadderTop, Tex::Ladder, Tex::Ladder},
/* TNT*/ {Tex::Explosive, Tex::Explosive, Tex::Explosive, Tex::Explosive, Tex::Explosive, Tex::Explosive},
/* Jump */ {Tex::Jump, Tex::Jump, Tex::JumpTop, Tex::TeleBottom, Tex::Jump, Tex::Jump},
/* Shock */ {Tex::TeleSideA, Tex::TeleSideA, Tex::TeleBottom, Tex::Spikes, Tex::TeleSideB, Tex::TeleSideB},
/*BankRed*/ {Tex::BankFrontRed, Tex::BankBackRed, Tex::BankTopRed, Tex::BankTopRed, Tex::BankLeftRed, Tex::BankRightRed},
/*BankBlue*/{Tex::BankFrontBlue, Tex::BankBackBlue, Tex::BankTopBlue, Tex::BankTopBlue, Tex::BankLeftBlue, Tex::BankRightBlue},
/*BeaconR*/ {Tex::TeleSideA, Tex::TeleSideA, Tex::BeaconRed, Tex::LadderTop, Tex::TeleSideB, Tex::TeleSideB},
/*BeaconB*/ {Tex::TeleSideA, Tex::TeleSideA, Tex::BeaconBlue, Tex::LadderTop, Tex::TeleSideB, Tex::TeleSideB},
/* Road */ {Tex::Road, Tex::Road, Tex::Road, Tex::Road, Tex::Road, Tex::Road},
/* SolidR */{Tex::SolidRed, Tex::SolidRed, Tex::SolidRed, Tex::SolidRed, Tex::SolidRed, Tex::SolidRed},
/* SolidB */{Tex::SolidBlue, Tex::SolidBlue, Tex::SolidBlue, Tex::SolidBlue, Tex::SolidBlue, Tex::SolidBlue},
/* Metal */ {Tex::Metal, Tex::Metal, Tex::Metal, Tex::Metal, Tex::Metal, Tex::Metal},
/*DirtSign*/{Tex::DirtSign, Tex::DirtSign, Tex::DirtSign, Tex::DirtSign, Tex::DirtSign, Tex::DirtSign},
/* Lava */ {Tex::Lava, Tex::Lava, Tex::Lava, Tex::Lava, Tex::Lava, Tex::Lava},
/* TransR */{Tex::TransRed, Tex::TransRed, Tex::TransRed, Tex::TransRed, Tex::TransRed, Tex::TransRed},
/* TransB */{Tex::TransBlue, Tex::TransBlue, Tex::TransBlue, Tex::TransBlue, Tex::TransBlue, Tex::TransBlue},
};
bool Blocks::isTransparent(BlockType t) {
@ -50,123 +83,55 @@ bool Blocks::isFaceVisible(BlockType t, BlockType other) {
bool Blocks::canGoThrough(BlockType t, Player::Team team) {
if (t == BlockType::Air)
return true;
if (t != BlockType::TransRed && t != BlockType::TransBlue)
return false;
return (t == BlockType::TransRed && team == Player::Team::Red) ||
(t == BlockType::TransBlue && team == Player::Team::Blue);
}
int32 blend(int32 c1, int32 c2, uint8 val) {
uint ival = 256 - val;
uint v1_1 = c1 & 0xFF00FF;
uint v1_2 = c1 & 0x00FF00;
uint v2_1 = c2 & 0xFF00FF;
uint v2_2 = c2 & 0x00FF00;
uint res =
( ( ( ( v1_1 * ival ) + ( v2_1 * val ) ) >> 8 ) & 0xFF00FF ) |
( ( ( ( v1_2 * ival ) + ( v2_2 * val ) ) >> 8 ) & 0x00FF00 );
return res;
}
int lerp(int a, int b, float x) {
return a*(1-x) + b*x;
}
void makePerlin(int w, int h, uint8 *buf) {
uint8 noise[(h/4)*(w/4)];
for (int i=0; i < (h/4)*(w/4); i++)
noise[i] = FastRand(255);
for (int x=0; x < w; x++) {
for (int y=0; y < h; y++) {
int target = (x/4) + (y/4)*(w/4);
buf[x+y*h] = sqrt(lerp(noise[target], noise[target+1], x%4/4.f) *
lerp(noise[target], noise[target+(w/4)], y%4/4.f));
}
}
}
#define AddTex(x, y) m_coords[(int)x] = m_atlasCreator->add(getAssetPath("blocks", y))
#define AddTexP(i, x, y, z, d) m_coords[(int)i] = m_atlasCreator->add(x, y, z, d)
#define AddTex(b, t) m_coords[(int)b] = m_atlasCreator->add(getAssetPath("blocks", t));
Blocks::Blocks() : m_atlas(nullptr) {
m_atlasCreator = new AtlasCreator(64*8, 64*8); //64*((int)BlockTex::LAST/8));
m_coords = new AtlasCreator::Coord[BlockTex::LAST];
if (GlobalProperties::UseProceduralTextures) {
uint8 *data = new uint8[64*64*4];
uint8 *perlin = new uint8[64*64*4];
makePerlin(64, 64, perlin);
for (int x=0; x < 64; x++) {
for (int y=0; y < 64; y++) {
int32 noise; // = blend(0x292018, 0xBF9860, FastRand(0, 255));
if (x == 0 || x == 63 || y == 0 || y == 63) {
noise = 0x1B120B;
} else {
/*switch (FastRand(0, 4)) {
case 0: noise = 0x292018; break;
case 1: noise = 0x593F28; break;
case 2: noise = 0x87633E; break;
case 3: noise = 0xBF9860; break;
}*/
/*if (perlin[x+y*64] < 64)
noise = 0x292018;
else if (perlin[x+y*64] < 128)
noise = 0x593F28;
else if (perlin[x+y*64] < 192)
noise = 0x87633E;
else
noise = 0xBF9860;*/
noise = ((int)perlin[x+y*64] << 16) + ((int)perlin[x+y*64] << 8) + (int)perlin[x+y*64];
}
data[0 + x*4 + y*64*4] = noise >> 16 & 0xFF;
data[1 + x*4 + y*64*4] = noise >> 8 & 0xFF;
data[2 + x*4 + y*64*4] = noise & 0xFF;
data[3 + x*4 + y*64*4] = 255;
}
}
AddTexP(BlockTex::Dirt, 64, 64, 4, data);
delete[] data;
delete[] perlin;
} else {
AddTex(BlockTex::Dirt, "tex_block_dirt.png");}
AddTex(BlockTex::DirtSign, "tex_block_dirt_sign.png");
AddTex(BlockTex::Rock, "tex_block_rock.png");
AddTex(BlockTex::Ore, "tex_block_ore.png");
AddTex(BlockTex::Gold, "tex_block_silver.png");
AddTex(BlockTex::Diamond, "tex_block_diamond.png");
AddTex(BlockTex::HomeRed, "tex_block_home_red.png");
AddTex(BlockTex::HomeBlue, "tex_block_home_blue.png");
AddTex(BlockTex::SolidRed, "tex_block_red.png");
AddTex(BlockTex::SolidBlue, "tex_block_blue.png");
AddTex(BlockTex::Ladder, "tex_block_ladder.png");
AddTex(BlockTex::LadderTop, "tex_block_ladder_top.png");
AddTex(BlockTex::Spikes, "tex_block_spikes.png");
AddTex(BlockTex::Jump, "tex_block_jump.png");
AddTex(BlockTex::JumpTop, "tex_block_jump_top.png");
AddTex(BlockTex::Explosive, "tex_block_explosive.png");
AddTex(BlockTex::Metal, "tex_block_metal.png");
AddTex(BlockTex::BankTopRed, "tex_block_bank_top_red.png");
AddTex(BlockTex::BankLeftRed, "tex_block_bank_left_red.png");
AddTex(BlockTex::BankFrontRed, "tex_block_bank_front_red.png");
AddTex(BlockTex::BankRightRed, "tex_block_bank_right_red.png");
AddTex(BlockTex::BankBackRed, "tex_block_bank_back_red.png");
AddTex(BlockTex::BankTopBlue, "tex_block_bank_top_blue.png");
AddTex(BlockTex::BankLeftBlue, "tex_block_bank_left_blue.png");
AddTex(BlockTex::BankFrontBlue, "tex_block_bank_front_blue.png");
AddTex(BlockTex::BankRightBlue, "tex_block_bank_right_blue.png");
AddTex(BlockTex::BankBackBlue, "tex_block_bank_back_blue.png");
AddTex(BlockTex::TeleSideA, "tex_block_teleporter_a.png");
AddTex(BlockTex::TeleSideB, "tex_block_teleporter_b.png");
AddTex(BlockTex::TeleTop, "tex_block_teleporter_top.png");
AddTex(BlockTex::TeleBottom, "tex_block_teleporter_bottom.png");
AddTex(BlockTex::Lava, "tex_block_lava.png");
AddTex(BlockTex::Road, "tex_block_road_orig.png");
AddTex(BlockTex::RoadTop, "tex_block_road_top.png");
AddTex(BlockTex::RoadBottom, "tex_block_road_bottom.png");
AddTex(BlockTex::BeaconRed, "tex_block_beacon_top_red.png");
AddTex(BlockTex::BeaconBlue, "tex_block_beacon_top_blue.png");
AddTex(BlockTex::TransRed, "tex_block_trans_red.png");
AddTex(BlockTex::TransBlue, "tex_block_trans_blue.png");
m_atlasCreator = new AtlasCreator(64*8, 64*8); //64*((int)Tex::LAST/8));
m_coords = new AtlasCreator::Coord[Tex::LAST];
AddTex(Tex::Dirt, "tex_block_dirt.png");
AddTex(Tex::DirtSign, "tex_block_dirt_sign.png");
AddTex(Tex::Rock, "tex_block_rock.png");
AddTex(Tex::Ore, "tex_block_ore.png");
AddTex(Tex::Gold, "tex_block_silver.png");
AddTex(Tex::Diamond, "tex_block_diamond.png");
AddTex(Tex::HomeRed, "tex_block_home_red.png");
AddTex(Tex::HomeBlue, "tex_block_home_blue.png");
AddTex(Tex::SolidRed, "tex_block_red.png");
AddTex(Tex::SolidBlue, "tex_block_blue.png");
AddTex(Tex::Ladder, "tex_block_ladder.png");
AddTex(Tex::LadderTop, "tex_block_ladder_top.png");
AddTex(Tex::Spikes, "tex_block_spikes.png");
AddTex(Tex::Jump, "tex_block_jump.png");
AddTex(Tex::JumpTop, "tex_block_jump_top.png");
AddTex(Tex::Explosive, "tex_block_explosive.png");
AddTex(Tex::Metal, "tex_block_metal.png");
AddTex(Tex::BankTopRed, "tex_block_bank_top_red.png");
AddTex(Tex::BankLeftRed, "tex_block_bank_left_red.png");
AddTex(Tex::BankFrontRed, "tex_block_bank_front_red.png");
AddTex(Tex::BankRightRed, "tex_block_bank_right_red.png");
AddTex(Tex::BankBackRed, "tex_block_bank_back_red.png");
AddTex(Tex::BankTopBlue, "tex_block_bank_top_blue.png");
AddTex(Tex::BankLeftBlue, "tex_block_bank_left_blue.png");
AddTex(Tex::BankFrontBlue, "tex_block_bank_front_blue.png");
AddTex(Tex::BankRightBlue, "tex_block_bank_right_blue.png");
AddTex(Tex::BankBackBlue, "tex_block_bank_back_blue.png");
AddTex(Tex::TeleSideA, "tex_block_teleporter_a.png");
AddTex(Tex::TeleSideB, "tex_block_teleporter_b.png");
AddTex(Tex::TeleTop, "tex_block_teleporter_top.png");
AddTex(Tex::TeleBottom, "tex_block_teleporter_bottom.png");
AddTex(Tex::Lava, "tex_block_lava.png");
AddTex(Tex::Road, "tex_block_road_orig.png");
AddTex(Tex::RoadTop, "tex_block_road_top.png");
AddTex(Tex::RoadBottom, "tex_block_road_bottom.png");
AddTex(Tex::BeaconRed, "tex_block_beacon_top_red.png");
AddTex(Tex::BeaconBlue, "tex_block_beacon_top_blue.png");
AddTex(Tex::TransRed, "tex_block_trans_red.png");
AddTex(Tex::TransBlue, "tex_block_trans_blue.png");
m_atlas = m_atlasCreator->getAtlas();
delete m_atlasCreator;
}

View File

@ -9,8 +9,8 @@ namespace Diggler {
enum class BlockType : uint8_t {
Air = 0,
Dirt = 1,
Ore = 2,
Gold = 3,
Ore,
Gold,
Diamond,
Rock,
Ladder,
@ -43,9 +43,9 @@ enum class FaceDirection : uint8_t {
enum class BlockTex : uint8_t {
None = 0,
Dirt = 1,
Ore = 2,
Gold = 3,
Dirt,
Ore,
Gold,
Diamond,
Rock,
Jump,
@ -100,6 +100,16 @@ private:
Blocks& operator=(const Blocks&) = delete;
public:
constexpr static int TeamRed = 0x1,
TeamBlue = 0x2;
const static struct TypeInfo {
BlockType type;
const char *name;
int cashWorth, oreWorth, buildCost;
int teamCanBuild;
const char *icon;
} TypeInfos[(int)BlockType::LAST];
Blocks();
~Blocks();
static bool isTransparent(BlockType t);

View File

@ -168,8 +168,7 @@ static void AddOre(Superchunk &sc, const CaveGenerator::GenConf &gc) {
for (int y = 0; y < ys; y++)
for (int z = 0; z < zs; z++) {
float noise = stb_perlin_noise3(x/8.f, y/8.f+yRand, z/8.f);
if (sc.get(x, y, z) == BlockType::Dirt && noise > gc.ore.thresold)
sc.set(x, y, z, BlockType::Ore);
sc.set(x, y, z, (noise > gc.ore.thresold) ? BlockType::Ore : BlockType::Dirt);
}
}
@ -184,7 +183,7 @@ static void AddDiamond(Superchunk &sc, const CaveGenerator::GenConf &gc) {
int z = FastRand(0, zs);
int y = FastRandF()*(maxY-minY)+minY;
if (y > 2 && sc.get(x, y, z) == BlockType::Dirt) {
if (y > 2 && (sc.get(x, y, z) == BlockType::Dirt || sc.get(x, y, z) == BlockType::Ore)) {
sc.set(x, y, z, BlockType::Diamond);
numDiam--;
}
@ -202,7 +201,7 @@ static void AddGold(Superchunk &sc, const CaveGenerator::GenConf &gc) {
int z = FastRand(0, zs);
int y = FastRandF()*(maxY-minY)+minY;
if (y > 2 && sc.get(x, y, z) == BlockType::Dirt) {
if (y > 2 && (sc.get(x, y, z) == BlockType::Dirt || sc.get(x, y, z) == BlockType::Ore)) {
WalkL(sc, x, y, z, FastRand(gc.gold.minSize, gc.gold.maxSize), 1, BlockType::Gold, false, true);
numVeins--;
}
@ -214,10 +213,15 @@ void CaveGenerator::Generate(Superchunk &sc, const GenConf &gc) {
int groundLevel = ys*gc.groundLevel;
FastRandSeed(gc.seed);
for (int x = 0; x < xs; x++)
for (int y = 0; y < groundLevel; y++)
for (int z = 0; z < zs; z++)
sc.set(x, y, z, BlockType::Dirt);
if (gc.ore.enabled)
AddOre(sc, gc);
else
for (int x = 0; x < xs; x++)
for (int y = 0; y < groundLevel; y++)
for (int z = 0; z < zs; z++)
sc.set(x, y, z, BlockType::Dirt);
// Mountains
int yRand = FastRand(0xFFFF);
for (int y = groundLevel; y < ys; y++) {
float intensity = (groundLevel-y)/(float)(ys-groundLevel)+1;
@ -241,8 +245,6 @@ void CaveGenerator::Generate(Superchunk &sc, const GenConf &gc) {
AddDiamond(sc, gc);
if (gc.gold.enabled)
AddGold(sc, gc);
if (gc.ore.enabled)
AddOre(sc, gc);
}
}

View File

@ -18,7 +18,6 @@ namespace Diggler {
Chunk::Renderer Chunk::R = {0};
Texture *Chunk::TextureAtlas = nullptr;
Blocks *Chunk::BlkInf = nullptr;
struct GLCoord {
uint8 x, y, z, w;
@ -29,26 +28,25 @@ struct GLCoord {
constexpr float Chunk::CullSphereRadius;
constexpr float Chunk::MidX, Chunk::MidY, Chunk::MidZ;
Chunk::Chunk(int scx, int scy, int scz, Game *G) : blk2(nullptr),
Chunk::Chunk(int scx, int scy, int scz, Game *G) : blk2(nullptr), blk(nullptr),
scx(scx), scy(scy), scz(scz), G(G), vbo(nullptr), lavaCount(0) {
dirty = true;
blk = new BlockType[CX*CY*CZ];
for (int i=0; i < CX*CY*CZ; ++i)
blk[i] = BlockType::Air;
memset(blk, (int)BlockType::Air, CX*CY*CZ*sizeof(BlockType));
//for (int i=0; i < CX*CY*CZ; ++i)
// blk[i] = BlockType::Air;
if (GlobalProperties::IsClient) {
vbo = new VBO;
ibo = new VBO;
if (R.prog == nullptr) {
loadShader();
BlkInf = new Blocks();
TextureAtlas = BlkInf->getAtlas();
TextureAtlas = G->B->getAtlas();
}
}
if (GlobalProperties::IsServer) {
blk2 = new BlockType[CX*CY*CZ];
memset(blk, (int)BlockType::Air, CX*CY*CZ*sizeof(BlockType));
}
}
@ -166,6 +164,7 @@ void Chunk::updateServerSwap() {
struct RGB { float r, g, b; };
void Chunk::updateClient() {
mut.lock();
Blocks &B = *G->B;
GLCoord vertex[CX * CY * CZ * 6 /* faces */ * 4 /* vertices */ / 2 /* face removing (HSR) makes a lower vert max */];
GLushort index[CX * CY * CZ * 6 /* faces */ * 4 /* indices */ / 2 /* HSR */];
int v = 0, i = 0;
@ -227,8 +226,8 @@ void Chunk::updateClient() {
if ((mayDisp && bn == BlockType::Lava && get(x-1, y+1, z) != BlockType::Lava)
|| Blocks::isFaceVisible(bt, bn)) {
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
tc = BlkInf->gTC(bt, FaceDirection::XDec);
index[i++] = v+2; index[i++] = v+1; index[i++] = v+3;
tc = B.gTC(bt, FaceDirection::XDec);
vertex[v++] = {x, y, z, 0, tc->x, tc->v, .6f, .6f, .6f};
vertex[v++] = {x, y, z + 1, 0, tc->u, tc->v, .6f, .6f, .6f};
vertex[v++] = {x, y + 1, z, w, tc->x, tc->y, .6f, .6f, .6f};
@ -240,8 +239,8 @@ void Chunk::updateClient() {
if ((mayDisp && bn == BlockType::Lava && get(x+1, y+1, z) != BlockType::Lava)
|| Blocks::isFaceVisible(bt, bn)) {
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
tc = BlkInf->gTC(bt, FaceDirection::XInc);
index[i++] = v+2; index[i++] = v+1; index[i++] = v+3;
tc = B.gTC(bt, FaceDirection::XInc);
vertex[v++] = {x + 1, y, z, 0, tc->u, tc->v, .6f, .6f, .6f};
vertex[v++] = {x + 1, y + 1, z, w, tc->u, tc->y, .6f, .6f, .6f};
vertex[v++] = {x + 1, y, z + 1, 0, tc->x, tc->v, .6f, .6f, .6f};
@ -253,13 +252,13 @@ void Chunk::updateClient() {
if ((hasWaves && bn == BlockType::Lava)
|| Blocks::isFaceVisible(bt, bn)) {
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
index[i++] = v+2; index[i++] = v+1; index[i++] = v+3;
float shade = (blk[I(x,y,z)] == BlockType::Shock) ? 1.5f : .2f;;
tc = BlkInf->gTC(bt, FaceDirection::YDec);
vertex[v++] = {x, y, z, 0, tc->x, tc->v, shade, shade, shade};
vertex[v++] = {x + 1, y, z, 0, tc->u, tc->v, shade, shade, shade};
vertex[v++] = {x, y, z + 1, 0, tc->x, tc->y, shade, shade, shade};
vertex[v++] = {x + 1, y, z + 1, 0, tc->u, tc->y, shade, shade, shade};
tc = B.gTC(bt, FaceDirection::YDec);
vertex[v++] = {x, y, z, 0, tc->u, tc->v, shade, shade, shade};
vertex[v++] = {x + 1, y, z, 0, tc->u, tc->y, shade, shade, shade};
vertex[v++] = {x, y, z + 1, 0, tc->x, tc->v, shade, shade, shade};
vertex[v++] = {x + 1, y, z + 1, 0, tc->x, tc->y, shade, shade, shade};
}
// Positive Y
@ -267,12 +266,12 @@ void Chunk::updateClient() {
if ((hasWaves && bt == BlockType::Lava && bu != BlockType::Lava)
|| Blocks::isFaceVisible(bt, bn)) {
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
tc = BlkInf->gTC(bt, FaceDirection::YInc);
vertex[v++] = {x, y + 1, z, w, tc->u, tc->v, .8f, .8f, .8f};
vertex[v++] = {x, y + 1, z + 1, w, tc->u, tc->y, .8f, .8f, .8f};
vertex[v++] = {x + 1, y + 1, z, w, tc->x, tc->v, .8f, .8f, .8f};
vertex[v++] = {x + 1, y + 1, z + 1, w, tc->x, tc->y, .8f, .8f, .8f};
index[i++] = v+2; index[i++] = v+1; index[i++] = v+3;
tc = B.gTC(bt, FaceDirection::YInc);
vertex[v++] = {x, y + 1, z, w, tc->x, tc->v, .8f, .8f, .8f};
vertex[v++] = {x, y + 1, z + 1, w, tc->u, tc->v, .8f, .8f, .8f};
vertex[v++] = {x + 1, y + 1, z, w, tc->x, tc->y, .8f, .8f, .8f};
vertex[v++] = {x + 1, y + 1, z + 1, w, tc->u, tc->y, .8f, .8f, .8f};
}
// Negative Z
@ -280,8 +279,8 @@ void Chunk::updateClient() {
if ((mayDisp && bn == BlockType::Lava && get(x, y+1, z-1) != BlockType::Lava)
|| Blocks::isFaceVisible(bt, bn)) {
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
tc = BlkInf->gTC(bt, FaceDirection::ZDec);
index[i++] = v+2; index[i++] = v+1; index[i++] = v+3;
tc = B.gTC(bt, FaceDirection::ZDec);
vertex[v++] = {x, y, z, 0, tc->u, tc->v, .4f, .4f, .4f};
vertex[v++] = {x, y + 1, z, w, tc->u, tc->y, .4f, .4f, .4f};
vertex[v++] = {x + 1, y, z, 0, tc->x, tc->v, .4f, .4f, .4f};
@ -293,8 +292,8 @@ void Chunk::updateClient() {
if ((mayDisp && bn == BlockType::Lava && get(x, y+1, z+1) != BlockType::Lava)
|| Blocks::isFaceVisible(bt, bn)) {
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
tc = BlkInf->gTC(bt, FaceDirection::ZInc);
index[i++] = v+2; index[i++] = v+1; index[i++] = v+3;
tc = B.gTC(bt, FaceDirection::ZInc);
vertex[v++] = {x, y, z + 1, 0, tc->x, tc->v, .4f, .4f, .4f};
vertex[v++] = {x + 1, y, z + 1, 0, tc->u, tc->v, .4f, .4f, .4f};
vertex[v++] = {x, y + 1, z + 1, w, tc->x, tc->y, .4f, .4f, .4f};

View File

@ -44,7 +44,6 @@ public:
uni_time;
} R;
static Texture *TextureAtlas;
static Blocks *BlkInf;
BlockType *blk;
int scx, scy, scz;
Game *G;

View File

@ -10,11 +10,8 @@
namespace Diggler {
const Program *Font::RenderProgram = nullptr;
GLint Font::RenderProgram_uni_mvp = -1;
GLint Font::RenderProgram_att_coord = -1;
GLint Font::RenderProgram_att_texcoord = -1;
GLint Font::RenderProgram_att_color = -1;
Font::Renderer Font::R = {0};
static const struct { float r, g, b; } ColorTable[16] = {
{1.0f, 1.0f, 1.0f},
{0.66f, 0.66f, 0.66f},
@ -35,12 +32,12 @@ static const struct { float r, g, b; } ColorTable[16] = {
};
Font::Font(Game *G, const std::string& path) : G(G) {
if (!RenderProgram) {
RenderProgram = G->PM->getProgram(PM_2D | PM_TEXTURED | PM_COLORED);
RenderProgram_att_coord = RenderProgram->att("coord");
RenderProgram_att_texcoord = RenderProgram->att("texcoord");
RenderProgram_att_color = RenderProgram->att("color");
RenderProgram_uni_mvp = RenderProgram->uni("mvp");
if (!R.prog) {
R.prog = G->PM->getProgram(PM_2D | PM_TEXTURED | PM_COLORED);
R.att_coord = R.prog->att("coord");
R.att_texcoord = R.prog->att("texcoord");
R.att_color = R.prog->att("color");
R.uni_mvp = R.prog->uni("mvp");
}
m_texture = new Texture(path, Texture::PixelFormat::RGBA);
std::ifstream source(path + ".fdf", std::ios_base::binary);
@ -68,7 +65,7 @@ struct Vertex { int x, y; float tx, ty; float r, g, b ,a; };
#define eraseCurChar() elements -= 6;
int Font::updateVBO(VBO &vbo, const std::string &text) const {
int Font::updateVBO(VBO &vbo, const std::string &text, GLenum usage) const {
int elements = text.size()*6;
Vertex *verts = new Vertex[elements];
uint8 c, w; int line = 0, cx = 0, v = 0; float l, r;
@ -116,28 +113,28 @@ int Font::updateVBO(VBO &vbo, const std::string &text) const {
v += 6;
cx += w;
}
vbo.setData(verts, elements, GL_STATIC_DRAW);
vbo.setData(verts, elements, usage);
delete[] verts;
return elements;
}
void Font::draw(const Diggler::VBO &vbo, int count, const glm::mat4& matrix) const {
glEnableVertexAttribArray(RenderProgram_att_coord);
glEnableVertexAttribArray(RenderProgram_att_texcoord);
glEnableVertexAttribArray(RenderProgram_att_color);
RenderProgram->bind();
void Font::draw(const VBO &vbo, int count, const glm::mat4& matrix) const {
glEnableVertexAttribArray(R.att_coord);
glEnableVertexAttribArray(R.att_texcoord);
glEnableVertexAttribArray(R.att_color);
R.prog->bind();
m_texture->bind();
vbo.bind();
glUniformMatrix4fv(RenderProgram_uni_mvp, 1, GL_FALSE, glm::value_ptr(matrix));
glVertexAttribPointer(RenderProgram_att_coord, 2, GL_INT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(RenderProgram_att_texcoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, tx));
glVertexAttribPointer(RenderProgram_att_color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, r));
glUniformMatrix4fv(R.uni_mvp, 1, GL_FALSE, glm::value_ptr(matrix));
glVertexAttribPointer(R.att_coord, 2, GL_INT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(R.att_texcoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, tx));
glVertexAttribPointer(R.att_color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, r));
glDrawArrays(GL_TRIANGLES, 0, count);
glDisableVertexAttribArray(RenderProgram_att_color);
glDisableVertexAttribArray(RenderProgram_att_texcoord);
glDisableVertexAttribArray(RenderProgram_att_coord);
glDisableVertexAttribArray(R.att_color);
glDisableVertexAttribArray(R.att_texcoord);
glDisableVertexAttribArray(R.att_coord);
}
Font::Size Font::getSize(const std::string &text) const {

View File

@ -22,8 +22,13 @@ private:
float left, right;
} *texPos;
uint8 height;
static Program const *RenderProgram;
static GLint RenderProgram_uni_mvp, RenderProgram_att_coord, RenderProgram_att_texcoord, RenderProgram_att_color;
static struct Renderer {
const Program *prog;
GLint att_coord,
att_texcoord,
att_color,
uni_mvp;
} R;
Game *G;
Font(const Font &other) = delete;
@ -36,7 +41,7 @@ public:
/// Updates the text VBO
/// @returns the number of elements in the VBO
int updateVBO(VBO &vbo, const std::string &text) const;
int updateVBO(VBO &vbo, const std::string &text, GLenum usage = GL_STATIC_DRAW) const;
void draw(const Diggler::VBO &vbo, int count, const glm::mat4& matrix) const;
Size getSize(const std::string &text) const;
int getHeight() const;

View File

@ -12,6 +12,7 @@ Game::Game() : players(this), CCH(nullptr), GW(nullptr), LP(nullptr), PM(nullptr
void Game::init() {
if (GlobalProperties::IsClient) {
B = new Blocks;
PM = new ProgramManager(*this);
LP = new LocalPlayer(this);
RP = new RenderProperties; { // TODO move somewhere else?
@ -30,6 +31,7 @@ void Game::init() {
Game::~Game() {
if (GlobalProperties::IsClient) {
delete B;
delete PM; delete LP;
delete RP; delete A;
delete KB;

View File

@ -27,6 +27,7 @@ public:
class ChunkChangeHelper *CCH;
// Client
Blocks *B;
class Config *C;
class GameWindow *GW;
UI::Manager *UIM;

View File

@ -138,17 +138,30 @@ GameState::Bloom::~Bloom() {
GameState::BuilderGun::BuilderGun() {
tex = new Texture(getAssetPath("tools", "tex_tool_build.png"), Texture::PixelFormat::RGBA);
blockTexs.emplace(BlockType::Metal, new Texture(getAssetPath("icons", "tex_icon_metal.png")));
currentBlock = BlockType::Metal;
currentBlockTex = blockTexs.at(BlockType::Metal);
index = 0;
deconstruct = false;
for (uint i=0; i < sizeof(Blocks::TypeInfos)/sizeof(*Blocks::TypeInfos); ++i) {
const Blocks::TypeInfo &inf = Blocks::TypeInfos[i];
// TODO change to player's team
if (inf.teamCanBuild & Blocks::TeamRed) {
blockTexs.emplace_back(inf.type, new Texture(getAssetPath("icons", inf.icon), Texture::PixelFormat::RGB));
}
}
select(1);
}
GameState::BuilderGun::~BuilderGun() {
delete tex;
for (auto it : blockTexs)
delete it.second;
for (auto tuple : blockTexs)
delete std::get<1>(tuple);
}
void GameState::BuilderGun::select(int idx) {
int max = blockTexs.size();
if (idx < 0)
idx = max-1;
index = idx % max;
auto tuple = blockTexs.at(index);
currentBlock = std::get<0>(tuple);
currentBlockTex = std::get<1>(tuple);
}
void GameState::setupUI() {
@ -300,7 +313,7 @@ void GameState::onMouseButton(int key, int action, int mods) {
msg.writeU16(face.x);
msg.writeU16(face.y);
msg.writeU16(face.z);
msg.writeU8((uint8)BlockType::Dirt);
msg.writeU8((uint8)m_builderGun.currentBlock);
}
sendMsg(msg, Net::Tfer::Rel, Net::Channels::MapUpdate);
}
@ -341,7 +354,10 @@ void GameState::onResize(int w, int h) {
}
void GameState::onMouseScroll(double x, double y) {
if (y < 0)
m_builderGun.select(m_builderGun.index-1);
if (y > 0)
m_builderGun.select(m_builderGun.index+1);
}
void GameState::updateViewport() {
@ -355,9 +371,21 @@ void GameState::updateViewport() {
bloom.renderer.fbo->resize(w/bloom.scale, h/bloom.scale);
//bloom.renderer.fb->tex->setFiltering(Texture::Filter::Linear, Texture::Filter::Linear);
m_crossHair.mat = glm::scale(glm::translate(*UIM.PM,
glm::vec3(w/2-5, h/2-5, 0)),
glm::vec3(5*UIM.Scale, 5*UIM.Scale, 0));
{ int tw = 5*UIM.Scale, th = 5*UIM.Scale;
m_crossHair.mat = glm::scale(glm::translate(*UIM.PM,
glm::vec3((w-tw)/2, (h-th)/2, 0)),
glm::vec3(tw, tw, 0));
}
{ int scale = 3, tw = 120*scale, th = 126*scale;
m_builderGun.matGun = glm::scale(glm::translate(*UIM.PM,
glm::vec3((w-tw)/2, -46*scale, 0)),
glm::vec3(tw, th, 0));
int iw = 39*scale, ih = 21*scale;
m_builderGun.matIcon = glm::scale(glm::translate(*UIM.PM,
glm::vec3((w-iw)/2-3*scale, 9*scale, 0)),
glm::vec3(iw, ih, 0));
}
int lineHeight = G->F->getHeight()*UIM.Scale;
char str[15]; std::snprintf(str, 15, "Loot: %d/%d", G->LP->ore, Player::getMaxOre(G->LP->playerclass));
@ -386,7 +414,7 @@ void GameState::updateViewport() {
UI.headerBg.mat = glm::scale(glm::translate(*UIM.PM,
glm::vec3(0, h-lineHeight, 0)),
glm::vec3(2*w, lineHeight, 0));
glm::vec3(w, lineHeight, 0));
UI.DebugInfo->setPos(0, h-(lineHeight+UI.DebugInfo->getSize().y));
@ -502,13 +530,13 @@ void GameState::gameLoop() {
LP->forceCameraUpdate();
G->A->update();
LP->setHasNoclip(true);
while (!glfwWindowShouldClose(*W)) {
while (!W->shouldClose()) {
if (!processNetwork()) return;
T = glfwGetTime(); deltaT = T - lastT;
G->Time = T;
if (T > fpsT) {
char str[8]; std::sprintf(str, "FPS: %d", frames); //\f
char str[10]; std::sprintf(str, "FPS: %d", frames);
UI.FPS->setText(std::string(str));
fpsT = T+1;
frames = 0;
@ -527,16 +555,15 @@ void GameState::gameLoop() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_3dFbo->bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (bloom.enable) {
m_3dFbo->bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
LP->update(deltaT);
// TODO: disable teleport and kill player
if (LP->position.y < -32) {
LP->setDead(true, Player::DeathReason::Void, true);
// TODO: remove, TP player
LP->position.y = 10;
}
glm::mat4 m_transform = LP->getPVMatrix();
@ -564,28 +591,27 @@ void GameState::gameLoop() {
m_highlightBox.vbo.bind();
glVertexAttribPointer(m_highlightBox.att_coord, 3, GL_FLOAT, GL_FALSE, 0, 0);
glUniform4f(m_highlightBox.uni_unicolor, 1.f, 0.f, 0.f, .3f);
glUniform4f(m_highlightBox.uni_unicolor, 1.f, 1.f, 1.f, .1f);
glUniformMatrix4fv(m_highlightBox.uni_mvp, 1, GL_FALSE, glm::value_ptr(
glm::scale(glm::translate(m_transform, glm::vec3(pointed)+glm::vec3(.5f)), glm::vec3(0.5*1.1))));
glm::scale(glm::translate(m_transform, glm::vec3(pointed)+glm::vec3(.5f)), glm::vec3(0.5f*1.03f))));
glDrawArrays(GL_TRIANGLES, 0, 6*2*3);
glUniform4f(m_highlightBox.uni_unicolor, 0.f, 0.f, 1.f, .2f);
/*glUniform4f(m_highlightBox.uni_unicolor, 0.f, 0.f, 1.f, .2f);
glUniformMatrix4fv(m_highlightBox.uni_mvp, 1, GL_FALSE, glm::value_ptr(
glm::scale(glm::translate(m_transform, glm::vec3(face)+glm::vec3(.5f)), glm::vec3(0.40f+ sin(G->Time*4)*0.01f ))));
glDrawArrays(GL_TRIANGLES, 0, 6*2*3);
glDrawArrays(GL_TRIANGLES, 0, 6*2*3);*/
glDisableVertexAttribArray(m_highlightBox.att_coord);
}
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
m_3dFbo->unbind();
G->UIM->drawFullTexV(*m_3dFbo->tex);
//G->UIM->drawFullRect(glm::vec4(1.f, 0.f, 0.f, 1-G->LP->health));
LP->render(m_transform);
if (bloom.enable) {
m_3dFbo->unbind();
G->UIM->drawFullTexV(*m_3dFbo->tex);
m_3dFbo->tex->setFiltering(Texture::Filter::Linear, Texture::Filter::Linear);
bloom.extractor.fbo->bind();
glViewport(0, 0, W->getW()/bloom.scale, W->getH()/bloom.scale);
@ -640,6 +666,7 @@ void GameState::gameLoop() {
}
/*** 2D PART ***/
G->UIM->drawFullRect(glm::vec4(1.f, 0.f, 0.f, 1-G->LP->health));
updateUI();
drawUI();
} else {
@ -684,6 +711,16 @@ void GameState::updateUI() {
UI.Altitude->setText(std::string(str));
}
if (showDebugInfo) {
int verts = 0;
const static glm::vec3 cShift(Chunk::MidX, Chunk::MidY, Chunk::MidZ);
for (int x = 0; x < G->SC->getChunksX(); x++)
for (int y = 0; y < G->SC->getChunksY(); y++)
for (int z = 0; z < G->SC->getChunksZ(); z++)
if (G->SC->getChunk(x, y, z))
if (G->LP->camera.frustum.sphereInFrustum(glm::vec3(x * CX, y * CY, z * CZ) + cShift, Chunk::CullSphereRadius)) {
verts += G->SC->getChunk(x, y, z)->vertices;
}
verts /= 3;
std::ostringstream oss;
oss << std::setprecision(3) <<
"HP: " << LP.health << std::endl <<
@ -691,7 +728,8 @@ void GameState::updateUI() {
"y: " << LP.position.y << std::endl <<
"z: " << LP.position.z << std::endl <<
"vy: " << LP.velocity.y << std::endl <<
"rx: " << LP.angle << std::endl;
"rx: " << LP.angle << std::endl <<
"chunk tris: " << verts;
UI.DebugInfo->setText(oss.str());
}
}
@ -703,8 +741,8 @@ void GameState::drawUI() {
G->UIM->drawTex(m_crossHair.mat, *m_crossHair.tex);
// TODO render weapon
//G->UIM->drawTexRect(UI::Element::Area {20, -20*3, 120*3, 126*3}, *m_builderGun.tex);
//G->UIM->drawTexRect(UI::Element::Area {20+37*3, 35*3, 117, 63}, *m_builderGun.currentBlockTex);
G->UIM->drawTex(m_builderGun.matGun, *m_builderGun.tex);
G->UIM->drawTex(m_builderGun.matIcon, *m_builderGun.currentBlockTex);
}
bool GameState::processNetwork() {

View File

@ -73,14 +73,15 @@ private:
} m_highlightBox;
struct BuilderGun {
glm::mat4 matGun, matIcon;
Texture *tex;
std::map<BlockType, Texture*> blockTexs;
std::vector<std::tuple<BlockType, Texture*>> blockTexs;
int index;
bool deconstruct;
BlockType currentBlock;
Texture *currentBlockTex;
BuilderGun();
~BuilderGun();
void select(int idx);
} m_builderGun;
KeyBindings *m_keybinds;

View File

@ -111,6 +111,10 @@ GameWindow::~GameWindow() {
}
}
bool GameWindow::shouldClose() const {
return glfwWindowShouldClose(m_window);
}
void GameWindow::cbChar(char32 unichar) {
m_currentState->onChar(unichar);
}

View File

@ -38,6 +38,7 @@ public:
inline int getW() const { return m_w; }
inline int getH() const { return m_h; }
bool shouldClose() const;
void cbMouseButton(int key, int action, int mods);
void cbCursorPos(double x, double y);

View File

@ -11,8 +11,6 @@ const int GlobalProperties::DefaultServerPort = 17425;
const unsigned int GlobalProperties::PlayerNameMaxLen = 30;
char *GlobalProperties::PlayerName = nullptr;
bool GlobalProperties::UseProceduralTextures = false;
bool GlobalProperties::IsSoundEnabled = true;
int GlobalProperties::UIScale = 2;

View File

@ -13,8 +13,6 @@ namespace GlobalProperties {
extern const unsigned int PlayerNameMaxLen;
extern char *PlayerName;
extern bool UseProceduralTextures;
extern bool IsSoundEnabled;
extern int UIScale;

View File

@ -1,10 +1,11 @@
#include "LocalPlayer.hpp"
#include "Game.hpp"
#include <cstdio>
#include <limits>
#include <sstream>
#include <glm/gtx/rotate_vector.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Audio.hpp"
#include "Game.hpp"
#include "network/NetHelper.hpp"
namespace Diggler {
@ -16,13 +17,14 @@ static float MvmtDamping = 1/(Acceleration*2.f);
static float Gravity = 18.0f; // -Y acceleration (blocks/sec/sec)
static float JumpForce = Gravity/2.7f;
static float LadderClimbSpeed = 3.f;
static float MaxSpeed = 5.f;
static float RoadMaxSpeed = MaxSpeed*2;
static float MinYVelocity = -80.f;
static float HurtYVelocity = -10.5f;
static float HurtYVelocity = -12.f;
static float LethalYVelocity = -16.f;
static int i(const float &f) {
@ -33,7 +35,7 @@ static int i(const float &f) {
LocalPlayer::LocalPlayer(Game *G) : Player(G), goingForward(false), goingBackward(false), goingLeft(false), goingRight(false),
hasGravity(true), hasNoclip(false), health(1) {
size = glm::vec3(0.3f, 1.9f, 0.3f);
size = glm::vec3(0.3f, 1.5f, 0.3f);
eyesPos = glm::vec3(0.f, 1.3f, 0.f);
}
@ -54,8 +56,8 @@ void LocalPlayer::lookAt(const glm::vec3& at) {
G->A->updateAngle();
}
void LocalPlayer::update(const float &delta) {
health += delta/10;
void LocalPlayer::update(float delta) {
health += delta/5;
if (health >= 1)
health = 1;
@ -93,17 +95,27 @@ void LocalPlayer::update(const float &delta) {
if (onGround) {
if (velocity.y <= LethalYVelocity) {
setDead(true, DeathReason::Fall, true);
position.y = (int)(position.y);
velocity = glm::vec3(0);
camera.setPosition(position + eyesPos);
G->A->updatePos();
health = 0;
return;
}
G->A->playSound("hitground");
health -= (velocity.y-HurtYVelocity)/(LethalYVelocity-HurtYVelocity);
if (health < 0)
setDead(true, DeathReason::Fall, true);
}
}
if (onGround) {
BlockType b = G->SC->get(position.x, position.y-1, position.z);
onGround = !Blocks::canGoThrough(b, team);
onRoad = (b == BlockType::Road);
if (onRoad) {
onRoad = (!onGround || b == BlockType::Road || b == BlockType::Jump);
} else {
onRoad = (b == BlockType::Road);
}
}
if (!onGround)
velocity.y -= Gravity * delta;
@ -165,6 +177,10 @@ void LocalPlayer::update(const float &delta) {
setDead(true, DeathReason::Lava, true);
return;
}
if (bNTop == BlockType::Ladder || bNBottom == BlockType::Ladder) {
velocity.y = LadderClimbSpeed;
velocity.z *= 0.75f;
}
velocity.x = 0.f;
}
if (velocity.x < 0.f)
@ -173,6 +189,10 @@ void LocalPlayer::update(const float &delta) {
setDead(true, DeathReason::Lava, true);
return;
}
if (bSTop == BlockType::Ladder || bSBottom == BlockType::Ladder) {
velocity.y = LadderClimbSpeed;
velocity.z *= 0.75f;
}
velocity.x = 0.f;
}
if (velocity.z > 0.f)
@ -181,6 +201,10 @@ void LocalPlayer::update(const float &delta) {
setDead(true, DeathReason::Lava, true);
return;
}
if (bETop == BlockType::Ladder || bEBottom == BlockType::Ladder) {
velocity.y = LadderClimbSpeed;
velocity.x *= 0.75f;
}
velocity.z = 0.f;
}
if (velocity.z < 0.f)
@ -189,6 +213,10 @@ void LocalPlayer::update(const float &delta) {
setDead(true, DeathReason::Lava, true);
return;
}
if (bWTop == BlockType::Ladder || bWBottom == BlockType::Ladder) {
velocity.y = LadderClimbSpeed;
velocity.x *= 0.75f;
}
velocity.z = 0.f;
}
switch (bTop) {
@ -224,6 +252,29 @@ void LocalPlayer::update(const float &delta) {
}
}
void LocalPlayer::render(const glm::mat4 &transform) const {
#if 0
const Program *P = G->PM->getProgram(PM_3D | PM_COLORED);
P->bind();
glEnableVertexAttribArray(P->att("coord"));
glEnableVertexAttribArray(P->att("color"));
glUniformMatrix4fv(P->uni("mvp"), 1, GL_FALSE, glm::value_ptr(transform));
static VBO vbo;
struct { float x, y, z, r, g, b; } pts[] = {
(int)position.x+.5f, (int)(position.y+size.y)+.5f, (int)(position.z+size.z)+.5f, 1.f, 0.f, 0.f,
(int)position.x+.5f, (int)(position.y+size.y)+.5f, (int)position.z+.5f, 0.f, 1.f, 0.f
};
vbo.setData(pts, 2, GL_STREAM_DRAW);
vbo.bind();
glPointSize(4.f);
glVertexAttribPointer(P->att("coord"), 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), 0);
glVertexAttribPointer(P->att("color"), 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (GLvoid*)(3*sizeof(float)));
glDrawArrays(GL_POINTS, 0, 2);
glDisableVertexAttribArray(P->att("color"));
glDisableVertexAttribArray(P->att("coord"));
#endif
}
void LocalPlayer::forceCameraUpdate() {
camera.setPosition(position + eyesPos);
}

View File

@ -31,7 +31,8 @@ public:
inline glm::mat4 getPVMatrix() { return camera.getPVMatrix(); }
void lookAt(const glm::vec3 &at);
inline void setProjection(const glm::mat4 &p) { camera.setProjection(p); }
void update(const float &delta);
void update(float delta);
void render(const glm::mat4 &transform) const;
void forceCameraUpdate();
void goForward(bool enable);
void goBackward(bool enable);

View File

@ -214,7 +214,7 @@ std::ostream& Diggler::getDebugStreamRaw() {
return std::cout;
}
std::ostream &Diggler::getOutputStreamRaw() {
std::ostream& Diggler::getOutputStreamRaw() {
return std::cout;
}

View File

@ -9,10 +9,7 @@
namespace Diggler {
Player::TexInfo ***Player::TexInfos = nullptr;
const Program *Player::RenderProgram = nullptr;
GLint Player::RenderProgram_attrib_texcoord = -1;
GLint Player::RenderProgram_attrib_coord = -1;
GLint Player::RenderProgram_uni_mvp = -1;
Player::Renderer Player::R = {0};
const char* Player::getTeamNameLowercase(Player::Team t) {
switch (t) {
@ -71,10 +68,13 @@ Player::Player(Game *G) : team(Team::Red),
isAlive(true), ore(0), loot(0) {
if (GlobalProperties::IsClient) {
if (TexInfos == nullptr) {
RenderProgram = G->PM->getProgram(PM_3D | PM_TEXTURED | PM_DISCARD);
RenderProgram_attrib_coord = RenderProgram->att("coord");
RenderProgram_attrib_texcoord = RenderProgram->att("texcoord");
RenderProgram_uni_mvp = RenderProgram->uni("mvp");
R.prog = G->PM->getProgram(PM_3D | PM_TEXTURED | PM_FOG | PM_DISCARD);
R.att_coord = R.prog->att("coord");
R.att_texcoord = R.prog->att("texcoord");
R.uni_mvp = R.prog->uni("mvp");
R.uni_unicolor = R.prog->uni("unicolor");
R.uni_fogStart = R.prog->uni("fogStart");
R.uni_fogEnd = R.prog->uni("fogEnd");
TexInfos = new TexInfo**[Team::LAST];
for (uint8 t=0; t < (uint8)Team::LAST; t++) {
@ -159,7 +159,7 @@ static inline int getSide(float angle) {
}
void Player::render(const glm::mat4 &transform) const {
RenderProgram->bind();
R.prog->bind();
TexInfos[(uint8)team][(uint8)tool]->tex->bind();
int action = 1;
if (velocity.x < -.5f || velocity.x > .5f ||
@ -170,18 +170,20 @@ void Player::render(const glm::mat4 &transform) const {
TexInfos[(uint8)team][(uint8)tool]->side[
getSide(rmod(atan2(position.x-G->LP->position.x, position.z-G->LP->position.z)-angle, M_PI*2))]
.vbos[action]->bind();
glEnableVertexAttribArray(RenderProgram_attrib_texcoord);
glEnableVertexAttribArray(RenderProgram_attrib_coord);
glEnableVertexAttribArray(R.att_texcoord);
glEnableVertexAttribArray(R.att_coord);
glUniform1f(R.uni_fogStart, G->RP->fogStart);
glUniform1f(R.uni_fogEnd, G->RP->fogEnd);
glm::vec3 &lpPos = G->LP->position;
float angle = atan2(lpPos.x-m_predictPos.x, lpPos.z-m_predictPos.z);
static const glm::vec3 vecY(0.0, 1.0, 0.0);
glUniformMatrix4fv(RenderProgram_uni_mvp, 1, GL_FALSE, glm::value_ptr(
glUniformMatrix4fv(R.uni_mvp, 1, GL_FALSE, glm::value_ptr(
glm::translate(transform, m_predictPos) * glm::rotate(angle, vecY)));
glVertexAttribPointer(RenderProgram_attrib_coord, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), 0);
glVertexAttribPointer(RenderProgram_attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (GLvoid*)(3*sizeof(float)));
glVertexAttribPointer(R.att_coord, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), 0);
glVertexAttribPointer(R.att_texcoord, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (GLvoid*)(3*sizeof(float)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(RenderProgram_attrib_coord);
glDisableVertexAttribArray(RenderProgram_attrib_texcoord);
glDisableVertexAttribArray(R.att_coord);
glDisableVertexAttribArray(R.att_texcoord);
}
void Player::setDead(bool dead, DeathReason dr, bool send) {

View File

@ -13,7 +13,7 @@ class Game;
class Texture;
class Player {
private:
protected:
static struct TexInfo {
Texture *tex;
union VBOs {
@ -23,8 +23,15 @@ private:
VBO *vbos[4];
} side[4];
} ***TexInfos;
static const Program *RenderProgram;
static GLint RenderProgram_attrib_coord, RenderProgram_attrib_texcoord, RenderProgram_uni_mvp;
static struct Renderer {
const Program *prog;
GLint att_coord,
att_texcoord,
uni_mvp,
uni_unicolor,
uni_fogStart,
uni_fogEnd;
} R;
glm::vec3 m_predictPos;
Player(const Player&) = delete;
@ -82,12 +89,12 @@ public:
Player(Game *G = nullptr);
Player(Player&&);
Player& operator=(Player&&);
virtual ~Player();
~Player();
virtual void setPosVel(const glm::vec3 &pos, const glm::vec3 &vel, const glm::vec3 &acc = glm::vec3());
virtual void update(const float &delta);
virtual void render(const glm::mat4 &transform) const;
virtual void setDead(bool, DeathReason = DeathReason::None, bool send = false);
void setPosVel(const glm::vec3 &pos, const glm::vec3 &vel, const glm::vec3 &acc = glm::vec3());
void update(const float &delta);
void render(const glm::mat4 &transform) const;
void setDead(bool, DeathReason = DeathReason::None, bool send = false);
};
}

View File

@ -11,62 +11,62 @@ private:
GLint linked = GL_FALSE;
bool mustDestroy = false;
std::string fshPath, vshPath;
public:
///
/// Creates an OpenGL Program from two existent shaders
/// (shaders dtors won't be called when ~Program is called)
///
Program(Shader* vsh, Shader* fsh);
///
/// Creates an OpenGL Program shaders read from paths
/// (shaders dtors will be called when ~Program is called)
///
Program(const std::string& vshPath, const std::string& fshPath);
///
/// Set shaders' #defines
/// @see Shader::setDefines(const std::vector<std::string>);
/// @see Shader::setDefines(const std::vector<std::string>&);
///
void setDefines(const std::vector<std::string>&);
///
/// Links the shaders together
/// @returns true on success, otherwise false
/// @see getError() returns the error message
///
bool link();
///
/// @returns The error message generated during link
/// @see link()
///
std::string getError() const;
GLuint getId() const;
operator GLuint() const { return getId(); }
///
/// @param name Name of the attribute
/// @returns OpenGL attribute ID
///
GLint att(const std::string& name) const;
///
/// @param name Name of the uniform
/// @returns OpenGL uniform ID
///
GLint uni(const std::string& name) const;
///
/// Makes this Program active
///
void bind() const;
GLuint getFShId() const;
GLuint getVShId() const;
///
/// Destroys the shader, freeing OpenGL resources and the subsequent Shaders (if needed)
///

View File

@ -243,35 +243,14 @@ Server::Server(Game &G, uint16 port) : G(G) {
throw "Server init failed";
}
#if 0
G.SC->setSize(4, 4, 4);
setup();
}
//for (int i=0; i < 8192; i++) G.SC->set(FastRand(CX*G.SC->getChunksX()), FastRand(CY*G.SC->getChunksY()), FastRand(CZ*G.SC->getChunksZ()), (BlockType)(FastRand((int)BlockType::LAST)));
for(int x=0;x<CX*G.SC->getChunksX();x++) for(int z=0;z<(CZ*G.SC->getChunksZ())/2;z++) G.SC->set(x, 0, z, BlockType::Dirt);
for(int x=0;x<CX*G.SC->getChunksX();x++) for(int z=0;z<(CZ*G.SC->getChunksZ())/2;z++) G.SC->set(x, 0, z+(CZ*G.SC->getChunksZ())/2, BlockType::Road);
// for(int x=0;x<CX*G.SC->getChunksX();x++) for(int y=0;y<16;y++) for(int z=0;z<CZ*G.SC->getChunksZ();z++) G.SC->set(x,y,z,BlockType::Dirt);
for(int x=0; x < (int)BlockType::LAST; x++) G.SC->set(x, 2, 0, (BlockType)(x));
G.SC->set(4, 4, 4, BlockType::Shock);
G.SC->set(4, 0, 4, BlockType::Jump);
G.SC->set(0, 1, 1, BlockType::Metal);
G.SC->set(0, 2, 1, BlockType::Metal);
G.SC->set(0, 3, 1, BlockType::Metal);
G.SC->set(1, 3, 1, BlockType::Metal);
G.SC->set(2, 3, 1, BlockType::Metal);
G.SC->set(3, 1, 1, BlockType::Metal);
G.SC->set(3, 2, 1, BlockType::Metal);
G.SC->set(3, 3, 1, BlockType::Metal);
CaveGenerator::PaintAtPoint(*(G.SC), 8, 8, 8, 1, BlockType::Dirt);
CaveGenerator::PaintAtPoint(*(G.SC), 16, 8, 8, 2, BlockType::Dirt);
CaveGenerator::PaintAtPoint(*(G.SC), 24, 8, 8, 3, BlockType::Dirt);
for(int x=0;x<CX*G.SC->getChunksX();x++) for(int z=0;z<(CZ*G.SC->getChunksZ())/2;z++) G.SC->set(x, 64, z, BlockType::Dirt);
G.SC->set(2*CX, 68, 2*CY, BlockType::Lava);
#else
void Server::setupInternals() {
}
void Server::setup() {
G.CCH->enabled = false;
G.SC->setSize(4, 4, 4);
auto genStart = std::chrono::high_resolution_clock::now();
@ -281,7 +260,6 @@ Server::Server(Game &G, uint16 port) : G(G) {
auto genDelta = std::chrono::duration_cast<std::chrono::milliseconds>(genEnd - genStart);
getOutputStream() << "Map gen took " << genDelta.count() << "ms" << std::endl;
G.CCH->enabled = true;
#endif
//G.SC->save("/tmp/a");
//G.SC->load("/tmp/a");
@ -293,6 +271,7 @@ Server::Server(Game &G, uint16 port) : G(G) {
}*/
}
void chunk_updater(Game *G, Superchunk *sc, Host &H) {
while (true) {
for (int x=0; x < CX; x++)
@ -375,7 +354,7 @@ bool Server::isPlayerOnline(const std::string &playername) const {
return false;
}
void Server::kick(Player& p, Net::QuitReason r, const std::string& message) {
void Server::kick(Player &p, Net::QuitReason r, const std::string &message) {
OutMessage msg(MessageType::PlayerQuit, r);
msg.writeU32(p.id);
msg.writeString(message);

View File

@ -29,6 +29,8 @@ public:
Server(Game &G, uint16 port);
~Server();
void setupInternals();
void setup();
void run();
bool isPlayerOnline(const std::string &playername) const;
@ -36,7 +38,7 @@ public:
Player* getPlayerById(uint32 id);
Player* getPlayerByPeer(const Net::Peer &peer);
Player* getPlayerByName(const std::string &name);
void kick(Player &p, Net::QuitReason r, const std::string& message = "");
void kick(Player &p, Net::QuitReason r = Net::QuitReason::Kicked, const std::string& message = "");
};
}

View File

@ -23,25 +23,25 @@ public:
void stop();
bool isPlaying() const;
inline ALuint getId() const { return id; }
float getGain() const;
void setGain(float value);
bool getLooping() const;
void setLooping(bool value);
float getPitch() const;
void setPitch(float value);
bool getRelative() const;
void setRelative(bool value);
glm::vec3 getPosition() const;
void setPosition(const glm::vec3 &value);
glm::vec3 getVelocity() const;
void setVelocity(const glm::vec3 &value);
glm::vec3 getDirection() const;
void setDirection(const glm::vec3 &value);
};

View File

@ -63,23 +63,22 @@ void SoundBuffer::loadOgg(const std::string &path) {
getDebugStream() << "Could not load " << path << " : " << error << std::endl;
return;
}
// Get file info
stb_vorbis_info info = stb_vorbis_get_info(stream);
ALenum format = alGetFormat(info.channels, 16); // stb_vorbis always 16-bit samples
uint bufferSize = stb_vorbis_stream_length_in_samples(stream); //4096*8;
uint bufferSize = stb_vorbis_stream_length_in_samples(stream);
// Create buffer
ALshort *bufferData = new ALshort[bufferSize];
// Fill the buffer
stb_vorbis_get_samples_short_interleaved(stream, info.channels, bufferData, bufferSize);
// Send the buffer data
alBufferData(id, format, bufferData, stb_vorbis_stream_length_in_samples(stream)*sizeof(ALshort), info.sample_rate);
//getDebugStream() << path << ' ' << info.sample_rate << "Hz" << std::endl;
// avoid memory leaks: delete the buffer and stb_vorbis instance
delete[] bufferData;
stb_vorbis_close(stream);
}

View File

@ -1,6 +1,7 @@
#include "Superchunk.hpp"
#include "Game.hpp"
#include <cstring>
#include <glm/gtc/matrix_transform.hpp>
#include "Game.hpp"
#include "lzfx/lzfx.h"
#include "network/Network.hpp"
@ -37,6 +38,7 @@ void Superchunk::setSize(int x, int y, int z) {
c[x] = new Chunk**[chunksY];
for (int y = 0; y < chunksY; y++) {
c[x][y] = new Chunk*[chunksZ];
//memset(c[x][y], chunksZ*sizeof(Chunk*), 0);
for (int z = 0; z < chunksZ; z++) {
c[x][y][z] = nullptr;
}
@ -144,7 +146,7 @@ void Superchunk::render(const glm::mat4& transform) {
c[x][y][z]->renderBatched(chunkTransform);
}
}
glDisableVertexAttribArray(Chunk::R.att_wave);
glDisableVertexAttribArray(Chunk::R.att_color);
glDisableVertexAttribArray(Chunk::R.att_texcoord);
@ -192,19 +194,22 @@ void Superchunk::write(OutStream &msg) const {
};
msg.writeData(&mth, sizeof(MapTransferHeader));
const BlockType *chunkData = nullptr;
uint compressedSize = CX * CY * CZ;
byte *compressed = new byte[compressedSize];
uint initCompressedSize = CX*CY*CZ*sizeof(BlockType);
uint compressedSize;
byte *compressed = new byte[initCompressedSize];
for (int sx=0; sx < getChunksX(); sx++) {
for (int sy=0; sy < getChunksY(); sy++) {
for (int sz=0; sz < getChunksZ(); sz++) {
// Chunk may be uninitialized
if (c[sx][sy][sz] == nullptr) {
// Chunk is empty (not initialized), mark as missing
msg.writeI16(-1);
} else {
chunkData = c[sx][sy][sz]->blk;
compressedSize = CX * CY * CZ;
lzfx_compress(chunkData, CX*CY*CZ, compressed, &compressedSize);
compressedSize = initCompressedSize;
int rz = lzfx_compress(chunkData, CX*CY*CZ*sizeof(BlockType), compressed, &compressedSize);
if (rz < 0)
getErrorStream() << "Failed compressing Chunk[" << sx << ',' << sy <<
' ' << sz << ']' << std::endl;
msg.writeI16(compressedSize);
msg.writeData(compressed, compressedSize);
}
@ -219,15 +224,12 @@ void Superchunk::read(InStream &M) {
M.readData(&mth, sizeof(mth));
setSize(mth.Chunks.x, mth.Chunks.y, mth.Chunks.z);
int bytesRead = 0;
uint uncompressedDataSize = CX * CY * CZ; // Should not change
BlockType *uncompressedData = new BlockType[uncompressedDataSize/sizeof(BlockType)];
uint uncDataSizeMust = CX*CY*CZ*sizeof(BlockType), uncDataSize = 0;
for (int sx=0; sx < mth.Chunks.x; sx++) {
for (int sy=0; sy < mth.Chunks.y; sy++) {
for (int sz=0; sz < mth.Chunks.z; sz++) {
int16 size = M.readI16();
if (c[sx][sy][sz] != nullptr) {
delete c[sx][sy][sz]; // Bash out the old chunk
}
delete c[sx][sy][sz]; // Bash out the old chunk
if (size == -1) { // Chunk is empty
c[sx][sy][sz] = nullptr; // Keep out
} else {
@ -235,17 +237,24 @@ void Superchunk::read(InStream &M) {
byte *compressedData = new byte[size];
M.readData(compressedData, size);
bytesRead += size;
uncompressedDataSize = CX * CY * CZ;
lzfx_decompress(compressedData, size, uncompressedData, &uncompressedDataSize);
for (int i=0; i < CX*CY*CZ; ++i) {
c[sx][sy][sz]->blk[i] = uncompressedData[i];
uncDataSize = uncDataSizeMust;
int rz = lzfx_decompress(compressedData, size, c[sx][sy][sz]->blk, &uncDataSize);
if (rz < 0 || uncDataSize != uncDataSizeMust) {
if (rz < 0) {
getErrorStream() << "Chunk[" << sx << ',' << sy << ' ' << sz <<
"] LZFX decompression failed" << std::endl;
} else {
getErrorStream() << "Chunk[" << sx << ',' << sy << ' ' << sz <<
"] has bad size " << uncDataSize << '/' << uncDataSizeMust << std::endl;
}
delete c[sx][sy][sz];
c[sx][sy][sz] = nullptr;
}
delete[] compressedData;
}
}
}
}
delete[] uncompressedData;
getDebugStream() << "MapRead: read " << bytesRead << std::endl;
}

View File

@ -31,15 +31,6 @@ public:
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(T), data.data(), usage);
glBindBuffer(GL_ARRAY_BUFFER, currentBoundArray);
//getDebugStream() << "Set buffer " << typeid(T).name() << ' ' << data.size() << std::endl;
}
template <typename T> void setData(const std::initializer_list<T>& data, GLenum usage = GL_STATIC_DRAW) {
// TODO: Fix this, it's not working: data seems to always be empty
GLint currentBoundArray; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &currentBoundArray);
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(T), data.begin(), usage);
glBindBuffer(GL_ARRAY_BUFFER, currentBoundArray);
//getDebugStream() << "Set buffer " << typeid(T).name() << ' ' << data.size() << std::endl;
}
template <typename T> void setData(const T *data, uint count, GLenum usage = GL_STATIC_DRAW) {
GLint currentBoundArray; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &currentBoundArray);

View File

@ -32,6 +32,6 @@ void main(void) {
#endif
#ifdef FOG
float fogCoord = (gl_FragCoord.z/gl_FragCoord.w);
gl_FragColor = mix(gl_FragColor, vec4(0.0, 0.0, 0.0, 1.0), 1.0-clamp((fogEnd-fogCoord)/(fogEnd-fogStart), 0.0, 1.0));
gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.0, 0.0, 0.0), 1.0-clamp((fogEnd-fogCoord)/(fogEnd-fogStart), 0.0, 1.0));
#endif
}

View File

@ -26,9 +26,11 @@ void main(void) {
#endif
vec3 coord = coord.xyz;
#ifdef WAVE
float yShift = sin(time+(coord.x+coord.z)/16.0*6*PI)*(wave) - wave;
coord.y += yShift;
//v_texcoord.y -= yShift/8.0;
if (wave != 0) {
float yShift = sin(time+(coord.x+coord.z)/16.0*6*PI)*(wave) - wave;
coord.y += yShift;
//v_texcoord.y -= yShift/8.0;
}
#endif
gl_Position = mvp * vec4(coord, 1);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

View File

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 522 B

View File

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 543 B

View File

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

View File

Before

Width:  |  Height:  |  Size: 457 B

After

Width:  |  Height:  |  Size: 457 B

View File

Before

Width:  |  Height:  |  Size: 526 B

After

Width:  |  Height:  |  Size: 526 B

View File

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 430 B

View File

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 378 B

View File

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 513 B

View File

Before

Width:  |  Height:  |  Size: 373 B

After

Width:  |  Height:  |  Size: 373 B

View File

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

View File

Before

Width:  |  Height:  |  Size: 641 B

After

Width:  |  Height:  |  Size: 641 B

View File

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 522 B

View File

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 447 B

View File

Before

Width:  |  Height:  |  Size: 443 B

After

Width:  |  Height:  |  Size: 443 B

View File

@ -2,8 +2,10 @@ cmake_minimum_required(VERSION 2.6)
project(enet)
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CC_FLAGS_DEBUG "${CMAKE_CC_FLAGS_DEBUG} -g")
set(CMAKE_CC_FLAGS_RELEASE "${CMAKE_CC_FLAGS_RELEASE} -O3")
add_definitions(-DHAS_FCNTL -DHAS_POLL -DHAS_SOCKLEN_T)
set(ENET_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")

View File

@ -1,6 +1,10 @@
cmake_minimum_required(VERSION 2.6)
project(lzfx)
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CC_FLAGS_DEBUG "${CMAKE_CC_FLAGS_DEBUG} -g")
set(CMAKE_CC_FLAGS_RELEASE "${CMAKE_CC_FLAGS_RELEASE} -O3")
set(LZFX_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(LZFX_INCLUDE_DIR ${LZFX_INCLUDE_DIR} PARENT_SCOPE)
add_library(lzfx STATIC lzfx.c)

View File

@ -9,11 +9,10 @@
namespace Diggler {
namespace UI {
static const Program *RP_Rect = nullptr;
static GLint RP_Rect_att_texcoord = -1;
static GLint RP_Rect_att_coord = -1;
static GLint RP_Rect_uni_mvp = -1;
static GLint RP_Rect_uni_unicolor = -1;
struct Renderer {
const Program *prog;
GLint att_texcoord, att_coord, uni_mvp, uni_unicolor;
} R = {0}, RR = {0};
Manager::Manager() : Scale(2) {
PM = &m_projMatrix;
@ -24,12 +23,18 @@ Manager::Manager() : Scale(2) {
void Manager::setup(Game *G) {
this->G = G;
if (RP_Rect == nullptr) {
RP_Rect = G->PM->getProgram(PM_2D | PM_TEXTURED);
RP_Rect_att_coord = RP_Rect->att("coord");
RP_Rect_att_texcoord = RP_Rect->att("texcoord");
RP_Rect_uni_mvp = RP_Rect->uni("mvp");
RP_Rect_uni_unicolor = RP_Rect->uni("unicolor");
if (R.prog == nullptr) {
R.prog = G->PM->getProgram(PM_2D | PM_TEXTURED);
R.att_texcoord = R.prog->att("texcoord");
R.att_coord = R.prog->att("coord");
R.uni_mvp = R.prog->uni("mvp");
R.uni_unicolor = R.prog->uni("unicolor");
}
if (RR.prog == nullptr) {
RR.prog = G->PM->getProgram(PM_2D);
RR.att_coord = RR.prog->att("coord");
RR.uni_mvp = RR.prog->uni("mvp");
RR.uni_unicolor = RR.prog->uni("unicolor");
}
m_rectVbo = new VBO();
uint8 verts[6*4] = {
@ -69,44 +74,50 @@ void Manager::setProjMat(const glm::mat4 &mat) {
}
void Manager::drawRect(const glm::mat4 &mat, const glm::vec4 &color) const {
RP_Rect->bind();
glEnableVertexAttribArray(RP_Rect_att_coord);
RR.prog->bind();
glEnableVertexAttribArray(RR.att_coord);
Texture::unbind();
m_rectVbo->bind();
glUniform4f(RP_Rect_uni_unicolor, color.r, color.g, color.b, color.a);
glUniformMatrix4fv(RP_Rect_uni_mvp, 1, GL_FALSE, glm::value_ptr(mat));
glVertexAttribPointer(RP_Rect_att_coord, 2, GL_UNSIGNED_BYTE, GL_FALSE, 4*sizeof(uint8), 0);
Texture::unbind();
glUniform4f(RR.uni_unicolor, color.r, color.g, color.b, color.a);
glUniformMatrix4fv(RR.uni_mvp, 1, GL_FALSE, glm::value_ptr(mat));
glVertexAttribPointer(RR.att_coord, 2, GL_UNSIGNED_BYTE, GL_FALSE, 4*sizeof(uint8), 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
// OpenGL needs to be stateless. Definitely. Wait for Vulkan.
glUniform4f(RP_Rect_uni_unicolor, 1.f, 1.f, 1.f, 1.f);
glUniform4f(RR.uni_unicolor, 1.f, 1.f, 1.f, 1.f);
glDisableVertexAttribArray(RP_Rect_att_coord);
glDisableVertexAttribArray(RR.att_coord);
}
void Manager::drawFullRect(const glm::vec4 &color) const {
drawRect(m_projMat1, color);
}
void Manager::drawTex(const Element::Area &a, const Texture &t) const {
drawTex(glm::scale(glm::translate(*PM, glm::vec3(a.x, a.y, 0)), glm::vec3(a.w, a.h, 0)), t);
}
void Manager::drawTex(const glm::mat4 &mat, const Texture &t) const {
RP_Rect->bind();
glEnableVertexAttribArray(RP_Rect_att_coord);
glEnableVertexAttribArray(RP_Rect_att_texcoord);
void Manager::drawTex(const glm::mat4 &mat, const Texture &t, const glm::vec4 &color) const {
R.prog->bind();
glEnableVertexAttribArray(R.att_coord);
glEnableVertexAttribArray(R.att_texcoord);
t.bind();
m_rectVbo->bind();
glUniformMatrix4fv(RP_Rect_uni_mvp, 1, GL_FALSE, glm::value_ptr(mat));
glVertexAttribPointer(RP_Rect_att_coord, 2, GL_UNSIGNED_BYTE, GL_FALSE, 4*sizeof(uint8), 0);
glVertexAttribPointer(RP_Rect_att_texcoord, 2, GL_UNSIGNED_BYTE, GL_FALSE, 4*sizeof(uint8), (void*)(2*sizeof(uint8)));
glUniform4f(R.uni_unicolor, color.r, color.g, color.b, color.a);
glUniformMatrix4fv(R.uni_mvp, 1, GL_FALSE, glm::value_ptr(mat));
glVertexAttribPointer(R.att_coord, 2, GL_UNSIGNED_BYTE, GL_FALSE, 4*sizeof(uint8), 0);
glVertexAttribPointer(R.att_texcoord, 2, GL_UNSIGNED_BYTE, GL_FALSE, 4*sizeof(uint8), (void*)(2*sizeof(uint8)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glUniform4f(R.uni_unicolor, 1.f, 1.f, 1.f, 1.f);
glDisableVertexAttribArray(RP_Rect_att_texcoord);
glDisableVertexAttribArray(RP_Rect_att_coord);
glDisableVertexAttribArray(R.att_texcoord);
glDisableVertexAttribArray(R.att_coord);
}
void Manager::drawTex(const glm::mat4 &mat, const Texture &t) const {
drawTex(mat, t, glm::vec4(1.f));
}
void Manager::drawTex(const Element::Area &a, const Texture &t) const {
drawTex(glm::scale(glm::translate(*PM, glm::vec3(a.x, a.y, 0)), glm::vec3(a.w, a.h, 0)), t);
}
void Manager::drawFullTexV(const Texture &t) const {
@ -114,9 +125,7 @@ void Manager::drawFullTexV(const Texture &t) const {
}
void Manager::drawFullTexV(const Texture &t, const glm::vec4 &color) const {
glUniform4f(RP_Rect_uni_unicolor, color.r, color.g, color.b, color.a);
drawTex(m_projMat1V, t);
glUniform4f(RP_Rect_uni_unicolor, 1.f, 1.f, 1.f, 1.f);
drawTex(m_projMat1V, t, color);
}
}

View File

@ -55,6 +55,7 @@ public:
void drawFullRect(const glm::vec4 &color) const;
void drawTex(const Element::Area&, const Texture&) const;
void drawTex(const glm::mat4&, const Texture&) const;
void drawTex(const glm::mat4&, const Texture&, const glm::vec4 &color) const;
void drawFullTexV(const Texture&) const;
void drawFullTexV(const Texture&, const glm::vec4 &color) const;