|
@@ -1,11 +1,13 @@
|
|
-#include "GLFW/glfw3.h"
|
|
+#include "client/Main.h"
|
|
-
|
|
+#include "client/Controls.h"
|
|
-#include "common/Box.h"
|
|
+#include "client/Network.h"
|
|
-#include "common/Packets.h"
|
|
+#include "client/Player.h"
|
|
|
|
+#include "client/World.h"
|
|
|
|
+#include "common/NetworkPackets.h"
|
|
#include "data/Array.h"
|
|
#include "data/Array.h"
|
|
-#include "data/HashMap.h"
|
|
|
|
#include "data/RingBuffer.h"
|
|
#include "data/RingBuffer.h"
|
|
-#include "math/Frustum.h"
|
|
+#include "math/Box.h"
|
|
|
|
+#include "math/View.h"
|
|
#include "network/Client.h"
|
|
#include "network/Client.h"
|
|
#include "rendering/Shader.h"
|
|
#include "rendering/Shader.h"
|
|
#include "rendering/Texture.h"
|
|
#include "rendering/Texture.h"
|
|
@@ -13,147 +15,24 @@
|
|
#include "rendering/Window.h"
|
|
#include "rendering/Window.h"
|
|
#include "utils/Buffer.h"
|
|
#include "utils/Buffer.h"
|
|
|
|
|
|
-static constexpr int WORLD_SIZE = 16;
|
|
|
|
-
|
|
|
|
-static Array<bool, WORLD_SIZE * WORLD_SIZE * WORLD_SIZE> world(true);
|
|
|
|
-static Shader shader;
|
|
|
|
static Shader fontShader;
|
|
static Shader fontShader;
|
|
-static VertexBuffer vertexBuffer;
|
|
|
|
static VertexBuffer markVertexBuffer;
|
|
static VertexBuffer markVertexBuffer;
|
|
static VertexBuffer fontBuffer;
|
|
static VertexBuffer fontBuffer;
|
|
static Texture fontTexture;
|
|
static Texture fontTexture;
|
|
-static bool dirtyVertexBuffer = true;
|
|
|
|
-static int vertices = 0;
|
|
|
|
-static Frustum frustum(80.0f, 0.1f, 1000.0f);
|
|
|
|
-
|
|
|
|
-static Vector3 lastPosition(8.0f, 30.0f, 8.0f);
|
|
|
|
-static Vector3 position(lastPosition);
|
|
|
|
-static float lastWidthAngle = 0.0f;
|
|
|
|
-static float widthAngle = lastWidthAngle;
|
|
|
|
-static float lastLengthAngle = 0.0f;
|
|
|
|
-static float lengthAngle = lastLengthAngle;
|
|
|
|
-static Vector3 velocity;
|
|
|
|
-static Vector3 acceleration;
|
|
|
|
-static bool onGround = false;
|
|
|
|
-
|
|
|
|
-static Window::Controls::ButtonId leftKey;
|
|
|
|
-static Window::Controls::ButtonId rightKey;
|
|
|
|
-static Window::Controls::ButtonId upKey;
|
|
|
|
-static Window::Controls::ButtonId downKey;
|
|
|
|
-static Window::Controls::ButtonId jumpKey;
|
|
|
|
-static Window::Controls::ButtonId sneakKey;
|
|
|
|
-static Window::Controls::ButtonId escapeKey;
|
|
|
|
-static Window::Controls::ButtonId chatKey;
|
|
|
|
-static Window::Controls::ButtonId sendChatKey;
|
|
|
|
-static Window::Controls::ButtonId primaryClick;
|
|
|
|
-
|
|
|
|
-static bool trappedMoused = false;
|
|
|
|
-
|
|
|
|
-static Vector3 up;
|
|
|
|
-static Vector3 down;
|
|
|
|
-static Vector3 left;
|
|
|
|
-static Vector3 right;
|
|
|
|
-static Vector3 front;
|
|
|
|
-static Vector3 back;
|
|
|
|
-
|
|
|
|
-static Vector3 focus;
|
|
|
|
-static bool hasFocus = false;
|
|
|
|
-
|
|
|
|
-struct Player {
|
|
|
|
- Vector3 lastPosition;
|
|
|
|
- Vector3 position;
|
|
|
|
-};
|
|
|
|
|
|
|
|
-static HashMap<int, Player> players;
|
|
+HashMap<int, OtherPlayer> players;
|
|
|
|
|
|
-typedef StringBuffer<50> ChatMessage;
|
|
|
|
static Array<ChatMessage, 20> chat;
|
|
static Array<ChatMessage, 20> chat;
|
|
static int chatIndex = 0;
|
|
static int chatIndex = 0;
|
|
-static bool renderInput = false;
|
|
+bool renderInput = false;
|
|
|
|
|
|
-static void addToChat(const ChatMessage& msg) {
|
|
+void addToChat(const ChatMessage& msg) {
|
|
chat[chatIndex] = msg;
|
|
chat[chatIndex] = msg;
|
|
chatIndex = (chatIndex + 1) % chat.getLength();
|
|
chatIndex = (chatIndex + 1) % chat.getLength();
|
|
}
|
|
}
|
|
|
|
|
|
static bool isRunning() {
|
|
static bool isRunning() {
|
|
return !Window::shouldClose();
|
|
return !Window::shouldClose();
|
|
-
|
|
|
|
-
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void set(int x, int y, int z, bool b) {
|
|
|
|
- if(x < 0 || x >= WORLD_SIZE || y < 0 || y >= WORLD_SIZE || z < 0 ||
|
|
|
|
- z >= WORLD_SIZE) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- world[x * WORLD_SIZE * WORLD_SIZE + y * WORLD_SIZE + z] = b;
|
|
|
|
- dirtyVertexBuffer = true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void onPacket(InPacket& in) {
|
|
|
|
- uint8 type = 0;
|
|
|
|
- if(in.readU8(type)) {
|
|
|
|
- puts("no data");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- switch(static_cast<Packet::Type>(type)) {
|
|
|
|
- case Packet::Type::WORLD: {
|
|
|
|
- for(bool& b : world) {
|
|
|
|
- uint8 data = 0;
|
|
|
|
- if(in.readU8(data)) {
|
|
|
|
- puts("too less data in world packet");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- b = data;
|
|
|
|
- }
|
|
|
|
- dirtyVertexBuffer = true;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case Packet::Type::SET_BLOCK: {
|
|
|
|
- Vector3 pos;
|
|
|
|
- in.readFloat(pos[0]);
|
|
|
|
- in.readFloat(pos[1]);
|
|
|
|
- in.readFloat(pos[2]);
|
|
|
|
- uint8 type;
|
|
|
|
- in.readU8(type);
|
|
|
|
- set(pos[0], pos[1], pos[2], type);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case Packet::Type::PLAYER: {
|
|
|
|
- Vector3 pos;
|
|
|
|
- in.readFloat(pos[0]);
|
|
|
|
- in.readFloat(pos[1]);
|
|
|
|
- in.readFloat(pos[2]);
|
|
|
|
- int client = -1;
|
|
|
|
- in.readS32(client);
|
|
|
|
-
|
|
|
|
- Player* p = players.search(client);
|
|
|
|
- if(p != nullptr) {
|
|
|
|
- p->position = pos;
|
|
|
|
- } else {
|
|
|
|
- players.add(client, {pos, pos});
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case Packet::Type::CHAT: {
|
|
|
|
- ChatMessage msg;
|
|
|
|
- uint32 u;
|
|
|
|
- int i = 0;
|
|
|
|
- while(!in.readU32(u)) {
|
|
|
|
- i++;
|
|
|
|
- msg.appendUnicode(u);
|
|
|
|
- }
|
|
|
|
- printf("%d\n", i);
|
|
|
|
- addToChat(msg);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- default: printf("invalid package type %d\n", static_cast<int>(type));
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void onDisconnect() {
|
|
|
|
- puts("Disconnect");
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void addTriangle(Buffer& buffer, const Vector3& a, const Vector3& b,
|
|
static void addTriangle(Buffer& buffer, const Vector3& a, const Vector3& b,
|
|
@@ -163,14 +42,11 @@ static void addTriangle(Buffer& buffer, const Vector3& a, const Vector3& b,
|
|
}
|
|
}
|
|
|
|
|
|
static bool init() {
|
|
static bool init() {
|
|
- Error e =
|
|
+ if(World::init()) {
|
|
- shader.compile("resources/shader/test.vs", "resources/shader/test.fs");
|
|
|
|
- if(e.has()) {
|
|
|
|
- e.message.printLine();
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- e = fontShader.compile("resources/shader/fontTest.vs",
|
|
+ Error e = fontShader.compile("resources/shader/fontTest.vs",
|
|
- "resources/shader/fontTest.fs");
|
|
+ "resources/shader/fontTest.fs");
|
|
if(e.has()) {
|
|
if(e.has()) {
|
|
e.message.printLine();
|
|
e.message.printLine();
|
|
return true;
|
|
return true;
|
|
@@ -180,7 +56,6 @@ static bool init() {
|
|
e.message.printLine();
|
|
e.message.printLine();
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- vertexBuffer.init(VertexBuffer::Attributes().addFloat(3).addFloat(3));
|
|
|
|
markVertexBuffer.init(VertexBuffer::Attributes().addFloat(3).addFloat(3));
|
|
markVertexBuffer.init(VertexBuffer::Attributes().addFloat(3).addFloat(3));
|
|
fontBuffer.init(VertexBuffer::Attributes().addFloat(3).addFloat(2));
|
|
fontBuffer.init(VertexBuffer::Attributes().addFloat(3).addFloat(2));
|
|
|
|
|
|
@@ -206,299 +81,68 @@ static bool init() {
|
|
addTriangle(buffer, v111, v011, v101);
|
|
addTriangle(buffer, v111, v011, v101);
|
|
addTriangle(buffer, v000, v010, v100);
|
|
addTriangle(buffer, v000, v010, v100);
|
|
addTriangle(buffer, v110, v100, v010);
|
|
addTriangle(buffer, v110, v100, v010);
|
|
- markVertexBuffer.setStaticData(buffer.getLength(), buffer);
|
|
+ markVertexBuffer.setData(buffer, GL::STATIC_DRAW);
|
|
|
|
|
|
- Client::setPacketHandler(onPacket);
|
|
+ Controls::init();
|
|
- Client::setDisconnectHandler(onDisconnect);
|
|
|
|
-
|
|
|
|
- leftKey = Window::Controls::add("Left");
|
|
|
|
- Window::Controls::bindKey(leftKey, GLFW_KEY_A);
|
|
|
|
- rightKey = Window::Controls::add("Right");
|
|
|
|
- Window::Controls::bindKey(rightKey, GLFW_KEY_D);
|
|
|
|
- upKey = Window::Controls::add("Up");
|
|
|
|
- Window::Controls::bindKey(upKey, GLFW_KEY_W);
|
|
|
|
- downKey = Window::Controls::add("Right");
|
|
|
|
- Window::Controls::bindKey(downKey, GLFW_KEY_S);
|
|
|
|
- jumpKey = Window::Controls::add("Jump");
|
|
|
|
- Window::Controls::bindKey(jumpKey, GLFW_KEY_SPACE);
|
|
|
|
- sneakKey = Window::Controls::add("Sneak");
|
|
|
|
- Window::Controls::bindKey(sneakKey, GLFW_KEY_LEFT_SHIFT);
|
|
|
|
- escapeKey = Window::Controls::add("Escape");
|
|
|
|
- Window::Controls::bindKey(escapeKey, GLFW_KEY_ESCAPE);
|
|
|
|
- chatKey = Window::Controls::add("Chat");
|
|
|
|
- Window::Controls::bindKey(chatKey, GLFW_KEY_T);
|
|
|
|
- sendChatKey = Window::Controls::add("Send Chat");
|
|
|
|
- Window::Controls::bindKey(sendChatKey, GLFW_KEY_ENTER);
|
|
|
|
- primaryClick = Window::Controls::add("Primary Click");
|
|
|
|
- Window::Controls::bindMouse(primaryClick, GLFW_MOUSE_BUTTON_LEFT);
|
|
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
-static void updateDirections(float lag) {
|
|
|
|
- front.setAngles(Math::interpolate(lastLengthAngle, lengthAngle, lag),
|
|
|
|
- Math::interpolate(lastWidthAngle, widthAngle, lag));
|
|
|
|
- back = -front;
|
|
|
|
- right = front.cross(Vector3(0.0f, 1.0f, 0.0f));
|
|
|
|
- right.normalize();
|
|
|
|
- left = -right;
|
|
|
|
- up = front.cross(left);
|
|
|
|
- down = -up;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static bool isAir(int x, int y, int z) {
|
|
|
|
- if(x < 0 || x >= WORLD_SIZE || y < 0 || y >= WORLD_SIZE || z < 0 ||
|
|
|
|
- z >= WORLD_SIZE) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return !world[x * WORLD_SIZE * WORLD_SIZE + y * WORLD_SIZE + z];
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static List<Box> getBoxes(const Box& box) {
|
|
|
|
- int minX = floorf(box.getMin()[0]);
|
|
|
|
- int minY = floorf(box.getMin()[1]);
|
|
|
|
- int minZ = floorf(box.getMin()[2]);
|
|
|
|
- int maxX = floorf(box.getMax()[0]);
|
|
|
|
- int maxY = floorf(box.getMax()[1]);
|
|
|
|
- int maxZ = floorf(box.getMax()[2]);
|
|
|
|
-
|
|
|
|
- Box base(Vector3(1.0f, 1.0f, 1.0f));
|
|
|
|
- List<Box> boxes;
|
|
|
|
- for(int x = minX; x <= maxX; x++) {
|
|
|
|
- for(int y = minY; y <= maxY; y++) {
|
|
|
|
- for(int z = minZ; z <= maxZ; z++) {
|
|
|
|
- if(!isAir(x, y, z)) {
|
|
|
|
- boxes.add(base.offset(Vector3(x, y, z)));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return boxes;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static Vector3 limitMove() {
|
|
|
|
- Vector3 move = velocity;
|
|
|
|
- Box box(Vector3(0.8f, 0.8f, 0.8f));
|
|
|
|
- box = box.offset(position - Vector3(0.4f, 0.0f, 0.4f));
|
|
|
|
-
|
|
|
|
- List<Box> boxes = getBoxes(box.expand(move));
|
|
|
|
- if(boxes.getLength() == 0) {
|
|
|
|
- return move;
|
|
|
|
- }
|
|
|
|
- Vector3 realMove;
|
|
|
|
-
|
|
|
|
- constexpr float step = 0.05f;
|
|
|
|
- while(move[0] != 0.0f || move[1] != 0.0f || move[2] != 0.0f) {
|
|
|
|
- for(int i = 0; i < 3; i++) {
|
|
|
|
- Vector3 old = realMove;
|
|
|
|
- if(move[i] > step) {
|
|
|
|
- realMove[i] += step;
|
|
|
|
- move[i] -= step;
|
|
|
|
- } else if(move[i] < -step) {
|
|
|
|
- realMove[i] -= step;
|
|
|
|
- move[i] += step;
|
|
|
|
- } else if(move[i] != 0.0f) {
|
|
|
|
- realMove[i] += move[i];
|
|
|
|
- move[i] = 0.0f;
|
|
|
|
- }
|
|
|
|
- Box moved = box.offset(realMove);
|
|
|
|
- for(const Box& box : boxes) {
|
|
|
|
- if(box.collidesWith(moved)) {
|
|
|
|
- move[i] = 0.0f;
|
|
|
|
- realMove = old;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return realMove;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void tick() {
|
|
static void tick() {
|
|
if(renderInput) {
|
|
if(renderInput) {
|
|
- if(Window::Controls::wasReleased(sendChatKey)) {
|
|
+ if(Controls::wasReleased(Controls::enter)) {
|
|
- OutPacket out = Packet::build(Packet::Type::CHAT);
|
|
+ OutPacket out(100);
|
|
|
|
+ out.writeU8(static_cast<uint8>(ToServerPacket::CHAT));
|
|
for(uint32 u : Window::Input::getUnicode()) {
|
|
for(uint32 u : Window::Input::getUnicode()) {
|
|
out.writeU32(u);
|
|
out.writeU32(u);
|
|
}
|
|
}
|
|
- Client::send(out, PacketType::RELIABLE);
|
|
+ Client::send(out, PacketSendMode::RELIABLE);
|
|
Window::Input::reset();
|
|
Window::Input::reset();
|
|
}
|
|
}
|
|
- if(Window::Controls::wasReleased(escapeKey)) {
|
|
+ if(Controls::wasReleased(Controls::escape)) {
|
|
Window::Input::disable();
|
|
Window::Input::disable();
|
|
Window::trapCursor();
|
|
Window::trapCursor();
|
|
- trappedMoused = true;
|
|
|
|
renderInput = false;
|
|
renderInput = false;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- if(Window::Controls::isDown(chatKey)) {
|
|
+ if(Controls::isDown(Controls::chat)) {
|
|
Window::Input::enable();
|
|
Window::Input::enable();
|
|
Window::freeCursor();
|
|
Window::freeCursor();
|
|
- trappedMoused = false;
|
|
|
|
renderInput = true;
|
|
renderInput = true;
|
|
}
|
|
}
|
|
- if(Window::Controls::wasReleased(primaryClick)) {
|
|
+ if(Controls::wasReleased(Controls::primaryClick)) {
|
|
Window::trapCursor();
|
|
Window::trapCursor();
|
|
- trappedMoused = true;
|
|
|
|
}
|
|
}
|
|
- if(Window::Controls::wasReleased(escapeKey)) {
|
|
+ if(Controls::wasReleased(Controls::escape)) {
|
|
Window::freeCursor();
|
|
Window::freeCursor();
|
|
- trappedMoused = false;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- lastPosition = position;
|
|
+ Player::tick();
|
|
- lastWidthAngle = widthAngle;
|
|
+ for(OtherPlayer& p : players.values()) {
|
|
- lastLengthAngle = lengthAngle;
|
|
+ p.position.update();
|
|
-
|
|
|
|
- for(Player& p : players.values()) {
|
|
|
|
- p.lastPosition = p.position;
|
|
|
|
}
|
|
}
|
|
- Client::tick();
|
|
+ Network::tick();
|
|
-
|
|
|
|
- updateDirections(0.0f);
|
|
|
|
|
|
|
|
- Vector3 b = back;
|
|
+ if(Controls::wasReleased(Controls::primaryClick) && !renderInput) {
|
|
- b[1] = 0.0f;
|
|
+ RayTrace rt =
|
|
- b.normalize();
|
|
+ World::rayTrace(Player::getPosition() + Vector3(0.0f, 0.8f, 0.0f),
|
|
|
|
+ Player::getLook(), 10.0f);
|
|
|
|
+ if(rt.type == RayTrace::Type::BLOCK) {
|
|
|
|
+ World::set(rt.block[0], rt.block[1], rt.block[2], false);
|
|
|
|
|
|
- Vector3 r = right;
|
|
+ OutPacket out(100);
|
|
- r[1] = 0.0f;
|
|
+ out.writeU8(static_cast<uint8>(ToServerPacket::SET_BLOCK));
|
|
- r.normalize();
|
|
+ out.writeVector(rt.block);
|
|
-
|
|
+ out.writeU8(0);
|
|
- if(!renderInput) {
|
|
+ Client::send(out, PacketSendMode::RELIABLE);
|
|
- Vector3 force;
|
|
|
|
- if(Window::Controls::isDown(downKey)) {
|
|
|
|
- force += b;
|
|
|
|
- }
|
|
|
|
- if(Window::Controls::isDown(upKey)) {
|
|
|
|
- force -= b;
|
|
|
|
- }
|
|
|
|
- if(Window::Controls::isDown(leftKey)) {
|
|
|
|
- force -= r;
|
|
|
|
- }
|
|
|
|
- if(Window::Controls::isDown(rightKey)) {
|
|
|
|
- force += r;
|
|
|
|
- }
|
|
|
|
- if(force.squareLength() > 0.0f) {
|
|
|
|
- force.normalize();
|
|
|
|
- }
|
|
|
|
- acceleration += force * 0.1f;
|
|
|
|
-
|
|
|
|
- if(Window::Controls::isDown(jumpKey) && onGround) {
|
|
|
|
- acceleration[1] += (0.42f / 0.98f + 0.08f);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(trappedMoused) {
|
|
|
|
- Vector2 diff = (Window::Controls::getLastMousePosition() -
|
|
|
|
- Window::Controls::getMousePosition()) *
|
|
|
|
- 0.1f;
|
|
|
|
- widthAngle += diff[1];
|
|
|
|
- lengthAngle += diff[0];
|
|
|
|
- if(widthAngle > 89.0f) {
|
|
|
|
- widthAngle = 89.0f;
|
|
|
|
- }
|
|
|
|
- if(widthAngle < -89.0f) {
|
|
|
|
- widthAngle = -89.0f;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- hasFocus = false;
|
|
+ OutPacket out(100);
|
|
- Vector3 p = position + Vector3(0.0f, 0.8f, 0.0f);
|
|
+ out.writeU8(static_cast<uint8>(ToServerPacket::PLAYER));
|
|
- Vector3 step = front * 0.125f;
|
|
+ out.writeVector(Player::getPosition());
|
|
- for(int i = 0; i < 80; i++) {
|
|
|
|
- if(!isAir(p[0], p[1], p[2])) {
|
|
|
|
- hasFocus = true;
|
|
|
|
- focus = Vector3(static_cast<int>(p[0]), static_cast<int>(p[1]),
|
|
|
|
- static_cast<int>(p[2]));
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- p += step;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(hasFocus && Window::Controls::wasReleased(primaryClick) &&
|
|
|
|
- !renderInput) {
|
|
|
|
- set(focus[0], focus[1], focus[2], false);
|
|
|
|
- dirtyVertexBuffer = true;
|
|
|
|
-
|
|
|
|
- OutPacket out = Packet::build(Packet::Type::SET_BLOCK);
|
|
|
|
- out.writeFloat(focus[0]);
|
|
|
|
- out.writeFloat(focus[1]);
|
|
|
|
- out.writeFloat(focus[2]);
|
|
|
|
- out.writeU8(0);
|
|
|
|
- Client::send(out, PacketType::RELIABLE);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- OutPacket out = Packet::build(Packet::Type::PLAYER);
|
|
|
|
- out.writeFloat(position[0]);
|
|
|
|
- out.writeFloat(position[1]);
|
|
|
|
- out.writeFloat(position[2]);
|
|
|
|
out.writeS32(-1);
|
|
out.writeS32(-1);
|
|
- Client::send(out, PacketType::RELIABLE);
|
|
+ Client::send(out, PacketSendMode::RELIABLE);
|
|
-
|
|
|
|
- velocity += acceleration;
|
|
|
|
- velocity *= Vector3(0.686f, 0.98f, 0.686f);
|
|
|
|
- acceleration = Vector3(0.0f, -0.08f, 0.0f);
|
|
|
|
-
|
|
|
|
- Vector3 move = limitMove();
|
|
|
|
- if(move[1] + position[1] < 0.0f) {
|
|
|
|
- move[1] = -position[1];
|
|
|
|
- }
|
|
|
|
- position += move;
|
|
|
|
- onGround = move[1] == 0.0f && velocity[1] < 0.0f;
|
|
|
|
- velocity = move;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void addCube(Buffer& buffer, int x, int y, int z) {
|
|
|
|
- if(isAir(x, y, z)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- Vector3 v000(x, y, z);
|
|
|
|
- Vector3 v001(x, y, z + 1);
|
|
|
|
- Vector3 v010(x, y + 1, z);
|
|
|
|
- Vector3 v011(x, y + 1, z + 1);
|
|
|
|
- Vector3 v100(x + 1, y, z);
|
|
|
|
- Vector3 v101(x + 1, y, z + 1);
|
|
|
|
- Vector3 v110(x + 1, y + 1, z);
|
|
|
|
- Vector3 v111(x + 1, y + 1, z + 1);
|
|
|
|
-
|
|
|
|
- if(isAir(x, y - 1, z)) {
|
|
|
|
- addTriangle(buffer, v000, v100, v001);
|
|
|
|
- addTriangle(buffer, v100, v101, v001);
|
|
|
|
- }
|
|
|
|
- if(isAir(x, y + 1, z)) {
|
|
|
|
- addTriangle(buffer, v010, v011, v110);
|
|
|
|
- addTriangle(buffer, v110, v011, v111);
|
|
|
|
- }
|
|
|
|
- if(isAir(x - 1, y, z)) {
|
|
|
|
- addTriangle(buffer, v000, v001, v010);
|
|
|
|
- addTriangle(buffer, v001, v011, v010);
|
|
|
|
- }
|
|
|
|
- if(isAir(x + 1, y, z)) {
|
|
|
|
- addTriangle(buffer, v100, v110, v101);
|
|
|
|
- addTriangle(buffer, v101, v110, v111);
|
|
|
|
- }
|
|
|
|
- if(isAir(x, y, z + 1)) {
|
|
|
|
- addTriangle(buffer, v001, v101, v011);
|
|
|
|
- addTriangle(buffer, v111, v011, v101);
|
|
|
|
- }
|
|
|
|
- if(isAir(x, y, z - 1)) {
|
|
|
|
- addTriangle(buffer, v000, v010, v100);
|
|
|
|
- addTriangle(buffer, v110, v100, v010);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void buildRenderingBuffer() {
|
|
|
|
- Buffer buffer(100);
|
|
|
|
- for(int x = 0; x < WORLD_SIZE; x++) {
|
|
|
|
- for(int y = 0; y < WORLD_SIZE; y++) {
|
|
|
|
- for(int z = 0; z < WORLD_SIZE; z++) {
|
|
|
|
- addCube(buffer, x, y, z);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- vertices = buffer.getLength() / (2 * sizeof(Vector3));
|
|
|
|
- vertexBuffer.setStaticData(buffer.getLength(), buffer);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void renderString(const char* text) {
|
|
static void renderString(const char* text) {
|
|
@@ -531,86 +175,70 @@ static void renderString(const char* text) {
|
|
vertices += 6;
|
|
vertices += 6;
|
|
index++;
|
|
index++;
|
|
}
|
|
}
|
|
- fontBuffer.setDynamicData(buffer.getLength(), buffer);
|
|
+ fontBuffer.setData(buffer, GL::DYNAMIC_DRAW);
|
|
fontBuffer.draw(vertices);
|
|
fontBuffer.draw(vertices);
|
|
}
|
|
}
|
|
|
|
|
|
static void render(float lag) {
|
|
static void render(float lag) {
|
|
GL::clear();
|
|
GL::clear();
|
|
GL::enableDepthTesting();
|
|
GL::enableDepthTesting();
|
|
- if(dirtyVertexBuffer) {
|
|
+ World::render(lag);
|
|
- dirtyVertexBuffer = false;
|
|
|
|
- buildRenderingBuffer();
|
|
|
|
- puts("rebuilt buffer");
|
|
|
|
- }
|
|
|
|
|
|
|
|
- shader.use();
|
|
+ RayTrace rt =
|
|
- GL::setViewport(Window::getSize()[0], Window::getSize()[1]);
|
|
+ World::rayTrace(Player::getPosition(lag) + Vector3(0.0f, 0.8f, 0.0f),
|
|
- const Matrix& proj = frustum.updateProjection(Window::getSize());
|
|
+ Player::getLook(lag), 10.0f);
|
|
- shader.setMatrix("proj", proj.getValues());
|
|
|
|
- updateDirections(lag);
|
|
|
|
- Matrix view;
|
|
|
|
- Vector3 center = Math::interpolate(lastPosition, position, lag) +
|
|
|
|
- Vector3(0.0f, 0.8f, 0.0f);
|
|
|
|
- view.set(0, Vector4(right[0], right[1], right[2], right.dot(-center)));
|
|
|
|
- view.set(1, Vector4(up[0], up[1], up[2], up.dot(-center)));
|
|
|
|
- view.set(2, Vector4(back[0], back[1], back[2], back.dot(-center)));
|
|
|
|
- view.set(3, Vector4(0.0f, 0.0f, 0.0f, 1.0f));
|
|
|
|
- shader.setMatrix("view", view.getValues());
|
|
|
|
- shader.setVector("color", Vector3(1.0f, 1.0f, 1.0f));
|
|
|
|
- Matrix model;
|
|
|
|
- shader.setMatrix("model", model.getValues());
|
|
|
|
- vertexBuffer.draw(vertices);
|
|
|
|
|
|
|
|
- if(hasFocus) {
|
|
+ if(rt.type == RayTrace::Type::BLOCK) {
|
|
- shader.setVector("color", Vector3(0.8f, 0.6f, 0.6f));
|
|
+ World::shader.setVector("color", Vector3(0.8f, 0.6f, 0.6f));
|
|
|
|
+ Matrix model;
|
|
model.translate(Vector3(-0.5f, -0.5f, -0.5f));
|
|
model.translate(Vector3(-0.5f, -0.5f, -0.5f));
|
|
model.scale(1.01f);
|
|
model.scale(1.01f);
|
|
model.translate(Vector3(0.5f, 0.5f, 0.5f));
|
|
model.translate(Vector3(0.5f, 0.5f, 0.5f));
|
|
- model.translate(focus);
|
|
+ model.translate(rt.block.toFloat());
|
|
- shader.setMatrix("model", model.getValues());
|
|
+ World::shader.setMatrix("model", model);
|
|
markVertexBuffer.draw(36);
|
|
markVertexBuffer.draw(36);
|
|
}
|
|
}
|
|
|
|
|
|
- shader.setVector("color", Vector3(1.0f, 0.0f, 0.0f));
|
|
+ World::shader.setVector("color", Vector3(1.0f, 0.0f, 0.0f));
|
|
- for(const Player& p : players.values()) {
|
|
+ for(const OtherPlayer& p : players.values()) {
|
|
|
|
+ Matrix model;
|
|
model.translateTo(Vector3(-0.5f, -0.5f, -0.5f));
|
|
model.translateTo(Vector3(-0.5f, -0.5f, -0.5f));
|
|
model.scale(0.8f);
|
|
model.scale(0.8f);
|
|
- model.translate(Math::interpolate(p.lastPosition, p.position, lag) +
|
|
+ model.translate(p.position.get(lag) + Vector3(0.0f, 0.4f, 0.0f));
|
|
- Vector3(0.0f, 0.4f, 0.0f));
|
|
+ World::shader.setMatrix("model", model);
|
|
- shader.setMatrix("model", model.getValues());
|
|
|
|
markVertexBuffer.draw(36);
|
|
markVertexBuffer.draw(36);
|
|
}
|
|
}
|
|
|
|
|
|
- shader.setMatrix("proj", Matrix().getValues());
|
|
+ World::shader.setMatrix("proj", Matrix());
|
|
- shader.setMatrix("view", Matrix().getValues());
|
|
+ World::shader.setMatrix("view", Matrix());
|
|
- shader.setVector("color", Vector3(1.0f, 0.0f, 1.0f));
|
|
+ World::shader.setVector("color", Vector3(1.0f, 0.0f, 1.0f));
|
|
|
|
+ Matrix model;
|
|
model.translateTo(Vector3(-0.5f, -0.5f, -0.5f));
|
|
model.translateTo(Vector3(-0.5f, -0.5f, -0.5f));
|
|
model.scale(0.05f);
|
|
model.scale(0.05f);
|
|
- shader.setMatrix("model", model.getValues());
|
|
+ World::shader.setMatrix("model", model);
|
|
markVertexBuffer.draw(36);
|
|
markVertexBuffer.draw(36);
|
|
|
|
|
|
GL::disableDepthTesting();
|
|
GL::disableDepthTesting();
|
|
GL::enableBlending();
|
|
GL::enableBlending();
|
|
fontShader.use();
|
|
fontShader.use();
|
|
- fontShader.setMatrix("proj", Matrix().getValues());
|
|
+ fontShader.setMatrix("proj", Matrix());
|
|
- view.translateTo(Vector3(0.0f, 0.0f, 0.0f));
|
|
+ Matrix v;
|
|
IntVector2 size = Window::getSize();
|
|
IntVector2 size = Window::getSize();
|
|
- view.scale(Vector3(2.0f / size[0], -2.0f / size[1], 1.0f));
|
|
+ v.scale(Vector3(2.0f / size[0], -2.0f / size[1], 1.0f));
|
|
- view.translate(Vector3(-1.0f, 1.0f, 0.0f));
|
|
+ v.translate(Vector3(-1.0f, 1.0f, 0.0f));
|
|
- fontShader.setMatrix("view", view.getValues());
|
|
+ fontShader.setMatrix("view", v);
|
|
fontTexture.bindTo(0);
|
|
fontTexture.bindTo(0);
|
|
|
|
|
|
for(int i = 0; i < chat.getLength(); i++) {
|
|
for(int i = 0; i < chat.getLength(); i++) {
|
|
model.translateTo(Vector3(0.0f, i * 8.0f, 0.0f)).scale(3.0f);
|
|
model.translateTo(Vector3(0.0f, i * 8.0f, 0.0f)).scale(3.0f);
|
|
- fontShader.setMatrix("model", model.getValues());
|
|
+ fontShader.setMatrix("model", model);
|
|
renderString(chat[(i + chatIndex) % chat.getLength()]);
|
|
renderString(chat[(i + chatIndex) % chat.getLength()]);
|
|
}
|
|
}
|
|
|
|
|
|
if(renderInput) {
|
|
if(renderInput) {
|
|
model.translateTo(Vector3(0.0f, chat.getLength() * 8.0f, 0.0f))
|
|
model.translateTo(Vector3(0.0f, chat.getLength() * 8.0f, 0.0f))
|
|
.scale(3.0f);
|
|
.scale(3.0f);
|
|
- fontShader.setMatrix("model", model.getValues());
|
|
+ fontShader.setMatrix("model", model);
|
|
StringBuffer<256> s;
|
|
StringBuffer<256> s;
|
|
Window::Input::toString(s);
|
|
Window::Input::toString(s);
|
|
renderString(s);
|
|
renderString(s);
|
|
@@ -619,42 +247,35 @@ static void render(float lag) {
|
|
.translateTo(Vector3(Window::Input::getCursor() * 8.0f,
|
|
.translateTo(Vector3(Window::Input::getCursor() * 8.0f,
|
|
chat.getLength() * 8.0f + 2.0f, 0.0f))
|
|
chat.getLength() * 8.0f + 2.0f, 0.0f))
|
|
.scale(3.0f);
|
|
.scale(3.0f);
|
|
- fontShader.setMatrix("model", model.getValues());
|
|
+ fontShader.setMatrix("model", model);
|
|
renderString("_");
|
|
renderString("_");
|
|
}
|
|
}
|
|
|
|
|
|
GL::disableBlending();
|
|
GL::disableBlending();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void startWindow() {
|
|
|
|
+ Window::Options options(4, 3, IntVector2(1024, 600), false, "test");
|
|
|
|
+ Error e = Window::open(options);
|
|
|
|
+ if(e.has()) {
|
|
|
|
+ e.message.printLine();
|
|
|
|
+ return;
|
|
|
|
+ } else if(!init()) {
|
|
|
|
+ Window::show();
|
|
|
|
+ Window::run<isRunning, tick, render>(50'000'000);
|
|
|
|
+ }
|
|
|
|
+ Window::close();
|
|
|
|
+}
|
|
|
|
+
|
|
int main(int argAmount, const char* const* args) {
|
|
int main(int argAmount, const char* const* args) {
|
|
const char* server = "127.0.0.1";
|
|
const char* server = "127.0.0.1";
|
|
if(argAmount >= 2) {
|
|
if(argAmount >= 2) {
|
|
server = args[1];
|
|
server = args[1];
|
|
}
|
|
}
|
|
- Error e = Client::start();
|
|
+ if(Network::start(server)) {
|
|
- if(e.has()) {
|
|
|
|
- e.message.printLine();
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- e = Client::connect(server, 11196, 40);
|
|
|
|
- if(e.has()) {
|
|
|
|
- e.message.printLine();
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- Window::Options options(4, 3, IntVector2(1024, 600), false, "test");
|
|
|
|
- e = Window::open(options);
|
|
|
|
- if(e.has()) {
|
|
|
|
- e.message.printLine();
|
|
|
|
- Client::stop();
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
- if(init()) {
|
|
+ startWindow();
|
|
- Client::stop();
|
|
+ Network::stop();
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- Window::show();
|
|
|
|
- Window::run<isRunning, tick, render>(50'000'000);
|
|
|
|
- Window::close();
|
|
|
|
- Client::stop();
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|