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, -O3master
|
@ -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;
|
||||
|
|
235
Blocks.cpp
|
@ -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;
|
||||
}
|
||||
|
|
20
Blocks.hpp
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
55
Chunk.cpp
|
@ -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};
|
||||
|
|
|
@ -44,7 +44,6 @@ public:
|
|||
uni_time;
|
||||
} R;
|
||||
static Texture *TextureAtlas;
|
||||
static Blocks *BlkInf;
|
||||
BlockType *blk;
|
||||
int scx, scy, scz;
|
||||
Game *G;
|
||||
|
|
51
Font.cpp
|
@ -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 {
|
||||
|
|
11
Font.hpp
|
@ -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;
|
||||
|
|
2
Game.cpp
|
@ -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;
|
||||
|
|
1
Game.hpp
|
@ -27,6 +27,7 @@ public:
|
|||
class ChunkChangeHelper *CCH;
|
||||
|
||||
// Client
|
||||
Blocks *B;
|
||||
class Config *C;
|
||||
class GameWindow *GW;
|
||||
UI::Manager *UIM;
|
||||
|
|
104
GameState.cpp
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -111,6 +111,10 @@ GameWindow::~GameWindow() {
|
|||
}
|
||||
}
|
||||
|
||||
bool GameWindow::shouldClose() const {
|
||||
return glfwWindowShouldClose(m_window);
|
||||
}
|
||||
|
||||
void GameWindow::cbChar(char32 unichar) {
|
||||
m_currentState->onChar(unichar);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -13,8 +13,6 @@ namespace GlobalProperties {
|
|||
extern const unsigned int PlayerNameMaxLen;
|
||||
extern char *PlayerName;
|
||||
|
||||
extern bool UseProceduralTextures;
|
||||
|
||||
extern bool IsSoundEnabled;
|
||||
|
||||
extern int UIScale;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -214,7 +214,7 @@ std::ostream& Diggler::getDebugStreamRaw() {
|
|||
return std::cout;
|
||||
}
|
||||
|
||||
std::ostream &Diggler::getOutputStreamRaw() {
|
||||
std::ostream& Diggler::getOutputStreamRaw() {
|
||||
return std::cout;
|
||||
}
|
||||
|
||||
|
|
34
Player.cpp
|
@ -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) {
|
||||
|
|
23
Player.hpp
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
24
Program.hpp
|
@ -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)
|
||||
///
|
||||
|
|
39
Server.cpp
|
@ -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);
|
||||
|
|
|
@ -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 = "");
|
||||
};
|
||||
|
||||
}
|
||||
|
|
14
Sound.hpp
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
9
VBO.hpp
|
@ -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, ¤tBoundArray);
|
||||
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, ¤tBoundArray);
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
}
|
Before Width: | Height: | Size: 202 B After Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 202 B After Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 385 B |
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 384 B |
Before Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 523 B |
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 522 B |
Before Width: | Height: | Size: 543 B After Width: | Height: | Size: 543 B |
Before Width: | Height: | Size: 277 B After Width: | Height: | Size: 277 B |
Before Width: | Height: | Size: 457 B After Width: | Height: | Size: 457 B |
Before Width: | Height: | Size: 526 B After Width: | Height: | Size: 526 B |
Before Width: | Height: | Size: 430 B After Width: | Height: | Size: 430 B |
Before Width: | Height: | Size: 378 B After Width: | Height: | Size: 378 B |
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 373 B After Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 369 B After Width: | Height: | Size: 369 B |
Before Width: | Height: | Size: 641 B After Width: | Height: | Size: 641 B |
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 522 B |
Before Width: | Height: | Size: 447 B After Width: | Height: | Size: 447 B |
Before Width: | Height: | Size: 443 B After Width: | Height: | Size: 443 B |
|
@ -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")
|
||||
|
|
|
@ -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)
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|