Main.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #include "client/Main.h"
  2. #include "client/Controls.h"
  3. #include "client/Network.h"
  4. #include "client/Player.h"
  5. #include "client/World.h"
  6. #include "common/NetworkPackets.h"
  7. #include "data/Array.h"
  8. #include "data/RingBuffer.h"
  9. #include "math/Box.h"
  10. #include "math/View.h"
  11. #include "network/Client.h"
  12. #include "rendering/Shader.h"
  13. #include "rendering/Texture.h"
  14. #include "rendering/VertexBuffer.h"
  15. #include "rendering/Window.h"
  16. #include "utils/Buffer.h"
  17. static Shader fontShader;
  18. static VertexBuffer markVertexBuffer;
  19. static VertexBuffer fontBuffer;
  20. static Texture fontTexture;
  21. HashMap<int, OtherPlayer> players;
  22. static Array<ChatMessage, 20> chat;
  23. static int chatIndex = 0;
  24. bool renderInput = false;
  25. void addToChat(const ChatMessage& msg) {
  26. chat[chatIndex] = msg;
  27. chatIndex = (chatIndex + 1) % chat.getLength();
  28. }
  29. static bool isRunning() {
  30. return !Window::shouldClose();
  31. }
  32. static void addTriangle(Buffer& buffer, const Vector3& a, const Vector3& b,
  33. const Vector3& c) {
  34. Vector3 normal = (b - a).cross(c - a);
  35. buffer.add(a).add(normal).add(b).add(normal).add(c).add(normal);
  36. }
  37. static bool init() {
  38. if(World::init()) {
  39. return true;
  40. }
  41. Error e = fontShader.compile("resources/shader/fontTest.vs",
  42. "resources/shader/fontTest.fs");
  43. if(e.has()) {
  44. e.message.printLine();
  45. return true;
  46. }
  47. e = fontTexture.load("resources/font8x8.png", 0);
  48. if(e.has()) {
  49. e.message.printLine();
  50. return true;
  51. }
  52. markVertexBuffer.init(VertexBuffer::Attributes().addFloat(3).addFloat(3));
  53. fontBuffer.init(VertexBuffer::Attributes().addFloat(3).addFloat(2));
  54. Vector3 v000(0, 0, 0);
  55. Vector3 v001(0, 0, 1);
  56. Vector3 v010(0, 1, 0);
  57. Vector3 v011(0, 1, 1);
  58. Vector3 v100(1, 0, 0);
  59. Vector3 v101(1, 0, 1);
  60. Vector3 v110(1, 1, 0);
  61. Vector3 v111(1, 1, 1);
  62. Buffer buffer(100);
  63. addTriangle(buffer, v000, v100, v001);
  64. addTriangle(buffer, v100, v101, v001);
  65. addTriangle(buffer, v010, v011, v110);
  66. addTriangle(buffer, v110, v011, v111);
  67. addTriangle(buffer, v000, v001, v010);
  68. addTriangle(buffer, v001, v011, v010);
  69. addTriangle(buffer, v100, v110, v101);
  70. addTriangle(buffer, v101, v110, v111);
  71. addTriangle(buffer, v001, v101, v011);
  72. addTriangle(buffer, v111, v011, v101);
  73. addTriangle(buffer, v000, v010, v100);
  74. addTriangle(buffer, v110, v100, v010);
  75. markVertexBuffer.setData(buffer, GL::STATIC_DRAW);
  76. Controls::init();
  77. return false;
  78. }
  79. static void tick() {
  80. if(renderInput) {
  81. if(Controls::wasReleased(Controls::enter)) {
  82. OutPacket out(100);
  83. out.writeU8(static_cast<uint8>(ToServerPacket::CHAT));
  84. for(uint32 u : Window::Input::getUnicode()) {
  85. out.writeU32(u);
  86. }
  87. Client::send(out, PacketSendMode::RELIABLE);
  88. Window::Input::reset();
  89. }
  90. if(Controls::wasReleased(Controls::escape)) {
  91. Window::Input::disable();
  92. Window::trapCursor();
  93. renderInput = false;
  94. }
  95. } else {
  96. if(Controls::isDown(Controls::chat)) {
  97. Window::Input::enable();
  98. Window::freeCursor();
  99. renderInput = true;
  100. }
  101. if(Controls::wasReleased(Controls::primaryClick)) {
  102. Window::trapCursor();
  103. }
  104. if(Controls::wasReleased(Controls::escape)) {
  105. Window::freeCursor();
  106. }
  107. }
  108. Player::tick();
  109. for(OtherPlayer& p : players.values()) {
  110. p.position.update();
  111. }
  112. Network::tick();
  113. if(Controls::wasReleased(Controls::primaryClick) && !renderInput) {
  114. RayTrace rt =
  115. World::rayTrace(Player::getPosition() + Vector3(0.0f, 0.8f, 0.0f),
  116. Player::getLook(), 10.0f);
  117. if(rt.type == RayTrace::Type::BLOCK) {
  118. World::set(rt.block[0], rt.block[1], rt.block[2], false);
  119. OutPacket out(100);
  120. out.writeU8(static_cast<uint8>(ToServerPacket::SET_BLOCK));
  121. out.writeVector(rt.block);
  122. out.writeU8(0);
  123. Client::send(out, PacketSendMode::RELIABLE);
  124. }
  125. }
  126. OutPacket out(100);
  127. out.writeU8(static_cast<uint8>(ToServerPacket::PLAYER));
  128. out.writeVector(Player::getPosition());
  129. out.writeS32(-1);
  130. Client::send(out, PacketSendMode::RELIABLE);
  131. }
  132. static void renderString(const char* text) {
  133. static Buffer buffer(50);
  134. buffer.clear();
  135. constexpr float fontSize = 8.0f;
  136. constexpr float fontStep = 8.0f / 128.0f;
  137. int index = 0;
  138. Vector3 pos;
  139. int vertices = 0;
  140. while(text[index] != '\0') {
  141. Vector3 right = pos + Vector3(fontSize, 0.0f, 0.0f);
  142. Vector3 down = pos + Vector3(0.0f, fontSize, 0.0f);
  143. Vector3 downRight = pos + Vector3(fontSize, fontSize, 0.0f);
  144. int i = text[index];
  145. if(i < 0 && text[index + 1] != '\0') {
  146. index++;
  147. i = ((i & 0x1F) << 6) | (text[index] & 0x3F);
  148. }
  149. Vector2 tPos(fontStep * (i % 16), fontStep * (i / 16));
  150. Vector2 tRight = tPos + Vector2(fontStep, 0.0f);
  151. Vector2 tDown = tPos + Vector2(0.0f, fontStep);
  152. Vector2 tDownRight = tPos + Vector2(fontStep, fontStep);
  153. buffer.add(pos).add(tPos).add(down).add(tDown).add(right).add(tRight);
  154. buffer.add(down).add(tDown).add(right).add(tRight).add(downRight).add(
  155. tDownRight);
  156. pos += Vector3(fontSize, 0.0f, 0.0f);
  157. vertices += 6;
  158. index++;
  159. }
  160. fontBuffer.setData(buffer, GL::DYNAMIC_DRAW);
  161. fontBuffer.draw(vertices);
  162. }
  163. static void render(float lag) {
  164. GL::clear();
  165. GL::enableDepthTesting();
  166. World::render(lag);
  167. RayTrace rt =
  168. World::rayTrace(Player::getPosition(lag) + Vector3(0.0f, 0.8f, 0.0f),
  169. Player::getLook(lag), 10.0f);
  170. if(rt.type == RayTrace::Type::BLOCK) {
  171. World::shader.setVector("color", Vector3(0.8f, 0.6f, 0.6f));
  172. Matrix model;
  173. model.translate(Vector3(-0.5f, -0.5f, -0.5f));
  174. model.scale(1.01f);
  175. model.translate(Vector3(0.5f, 0.5f, 0.5f));
  176. model.translate(rt.block.toFloat());
  177. World::shader.setMatrix("model", model);
  178. markVertexBuffer.draw(36);
  179. }
  180. World::shader.setVector("color", Vector3(1.0f, 0.0f, 0.0f));
  181. for(const OtherPlayer& p : players.values()) {
  182. Matrix model;
  183. model.translateTo(Vector3(-0.5f, -0.5f, -0.5f));
  184. model.scale(0.8f);
  185. model.translate(p.position.get(lag) + Vector3(0.0f, 0.4f, 0.0f));
  186. World::shader.setMatrix("model", model);
  187. markVertexBuffer.draw(36);
  188. }
  189. World::shader.setMatrix("proj", Matrix());
  190. World::shader.setMatrix("view", Matrix());
  191. World::shader.setVector("color", Vector3(1.0f, 0.0f, 1.0f));
  192. Matrix model;
  193. model.translateTo(Vector3(-0.5f, -0.5f, -0.5f));
  194. model.scale(0.05f);
  195. World::shader.setMatrix("model", model);
  196. markVertexBuffer.draw(36);
  197. GL::disableDepthTesting();
  198. GL::enableBlending();
  199. fontShader.use();
  200. fontShader.setMatrix("proj", Matrix());
  201. Matrix v;
  202. IntVector2 size = Window::getSize();
  203. v.scale(Vector3(2.0f / size[0], -2.0f / size[1], 1.0f));
  204. v.translate(Vector3(-1.0f, 1.0f, 0.0f));
  205. fontShader.setMatrix("view", v);
  206. fontTexture.bindTo(0);
  207. for(int i = 0; i < chat.getLength(); i++) {
  208. model.translateTo(Vector3(0.0f, i * 8.0f, 0.0f)).scale(3.0f);
  209. fontShader.setMatrix("model", model);
  210. renderString(chat[(i + chatIndex) % chat.getLength()]);
  211. }
  212. if(renderInput) {
  213. model.translateTo(Vector3(0.0f, chat.getLength() * 8.0f, 0.0f))
  214. .scale(3.0f);
  215. fontShader.setMatrix("model", model);
  216. StringBuffer<256> s;
  217. Window::Input::toString(s);
  218. renderString(s);
  219. model
  220. .translateTo(Vector3(Window::Input::getCursor() * 8.0f,
  221. chat.getLength() * 8.0f + 2.0f, 0.0f))
  222. .scale(3.0f);
  223. fontShader.setMatrix("model", model);
  224. renderString("_");
  225. }
  226. GL::disableBlending();
  227. }
  228. static void startWindow() {
  229. Window::Options options(4, 3, IntVector2(1024, 600), false, "test");
  230. Error e = Window::open(options);
  231. if(e.has()) {
  232. e.message.printLine();
  233. return;
  234. } else if(!init()) {
  235. Window::show();
  236. Window::run<isRunning, tick, render>(50'000'000);
  237. }
  238. Window::close();
  239. }
  240. int main(int argAmount, const char* const* args) {
  241. const char* server = "127.0.0.1";
  242. if(argAmount >= 2) {
  243. server = args[1];
  244. }
  245. if(Network::start(server)) {
  246. return 0;
  247. }
  248. startWindow();
  249. Network::stop();
  250. return 0;
  251. }