| @@ -15,23 +15,7 @@ static int getStoneLevel(const siv::PerlinNoise &perlin, int x) { | |||
| void DefaultWorldGen::drawBackground( | |||
| const Swan::Context &ctx, Cygnet::Renderer &rnd, Swan::Vec2 pos) { | |||
| int texmin = 10; | |||
| //int texmax = 20; | |||
| if (pos.y > texmin) { | |||
| /* | |||
| SDL_Texture *tex = bgCave_.texture_.get(); | |||
| Uint8 alpha = std::clamp( | |||
| (pos.y - texmin) / (texmax - texmin), 0.0f, 1.0f) * 255; | |||
| Swan::TexAlphaMod amod(tex, alpha); | |||
| Swan::Draw::parallaxBackground( | |||
| win, tex, std::nullopt, std::nullopt, | |||
| pos.x * Swan::TILE_SIZE, pos.y * Swan::TILE_SIZE, 0.7); | |||
| TODO */ | |||
| } | |||
| // TODO: Do something interesting? | |||
| } | |||
| Cygnet::Color DefaultWorldGen::backgroundColor(Swan::Vec2 pos) { | |||
| @@ -40,24 +40,24 @@ void PlayerEntity::update(const Swan::Context &ctx, float dt) { | |||
| placeTimer_.tick(dt); | |||
| // Break block | |||
| if (ctx.game.isMousePressed(SDL_BUTTON_LEFT)) | |||
| if (ctx.game.isMousePressed(GLFW_MOUSE_BUTTON_LEFT)) | |||
| ctx.plane.breakTile(mouseTile_); | |||
| // Place block | |||
| if (ctx.game.isMousePressed(SDL_BUTTON_RIGHT) && placeTimer_.periodic(0.50)) { | |||
| if (ctx.game.isMousePressed(GLFW_MOUSE_BUTTON_RIGHT) && placeTimer_.periodic(0.50)) { | |||
| if (ctx.plane.getTileID(mouseTile_) == ctx.world.getTileID("@::air")) { | |||
| ctx.plane.setTile(mouseTile_, "core::torch"); | |||
| } | |||
| } | |||
| // Move left | |||
| if (ctx.game.isKeyPressed(SDL_SCANCODE_A) || ctx.game.isKeyPressed(SDL_SCANCODE_LEFT)) { | |||
| if (ctx.game.isKeyPressed(GLFW_KEY_A) || ctx.game.isKeyPressed(GLFW_KEY_LEFT)) { | |||
| physics_.force += Swan::Vec2(-MOVE_FORCE, 0); | |||
| state_ = State::RUNNING_L; | |||
| } | |||
| // Move right | |||
| if (ctx.game.isKeyPressed(SDL_SCANCODE_D) || ctx.game.isKeyPressed(SDL_SCANCODE_RIGHT)) { | |||
| if (ctx.game.isKeyPressed(GLFW_KEY_D) || ctx.game.isKeyPressed(GLFW_KEY_RIGHT)) { | |||
| physics_.force += Swan::Vec2(MOVE_FORCE, 0); | |||
| if (state_ == State::RUNNING_L) | |||
| state_ = State::IDLE; | |||
| @@ -65,7 +65,7 @@ void PlayerEntity::update(const Swan::Context &ctx, float dt) { | |||
| state_ = State::RUNNING_R; | |||
| } | |||
| bool jumpPressed = ctx.game.isKeyPressed(SDL_SCANCODE_SPACE); | |||
| bool jumpPressed = ctx.game.isKeyPressed(GLFW_KEY_SPACE); | |||
| // Jump | |||
| if (physics_.onGround && jumpPressed && jumpTimer_.periodic(0.5)) { | |||
| @@ -1,34 +0,0 @@ | |||
| #pragma once | |||
| #include <swan-common/Vector2.h> | |||
| #include <memory> | |||
| #include "util.h" | |||
| struct SDL_Window; | |||
| namespace Cygnet { | |||
| struct WindowState; | |||
| class Window { | |||
| public: | |||
| Window(const char *name, int w, int h); | |||
| ~Window(); | |||
| void makeCurrent(); | |||
| void clear(Color color = {}); | |||
| void flip(); | |||
| void onResize(int w, int h); | |||
| SwanCommon::Vec2i size() { return size_; } | |||
| double pixelRatio() { return ratio_; } | |||
| SDL_Window *sdlWindow(); | |||
| private: | |||
| std::unique_ptr<WindowState> state_; | |||
| SwanCommon::Vec2i size_; | |||
| double ratio_; | |||
| }; | |||
| } | |||
| @@ -1,2 +1,6 @@ | |||
| #include <GL/glew.h> | |||
| #include <SDL_opengl.h> | |||
| #ifdef __APPLE__ | |||
| #define GL_SILENCE_DEPRECATION | |||
| #include <OpenGL/gl3.h> | |||
| #else | |||
| #include <GL/gl.h> | |||
| #endif | |||
| @@ -26,19 +26,12 @@ struct ByteColor { | |||
| operator Color() { return { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f }; } | |||
| }; | |||
| struct SDLError: public std::exception { | |||
| SDLError(std::string msg): message(std::move(msg)) {} | |||
| const char *what() const noexcept override { return message.c_str(); } | |||
| std::string message; | |||
| }; | |||
| struct GlError: public std::exception { | |||
| GlError(std::string msg): message(std::move(msg)) {} | |||
| const char *what() const noexcept override { return message.c_str(); } | |||
| std::string message; | |||
| }; | |||
| void sdlCheck(bool ok); | |||
| void glCheck(); | |||
| } | |||
| @@ -7,7 +7,6 @@ libcygnet = declare_dependency( | |||
| 'src/shaders.cc', | |||
| 'src/TileAtlas.cc', | |||
| 'src/util.cc', | |||
| 'src/Window.cc', | |||
| dependencies: [common, libtracy, libthreads, libsdl2, libgl, libglew], | |||
| dependencies: [common, libtracy, libthreads, libgl, libglfw3], | |||
| install: true, | |||
| include_directories: 'include/cygnet')) | |||
| @@ -35,7 +35,7 @@ struct ChunkProg: public GlProgram { | |||
| static constexpr float cw = (float)SwanCommon::CHUNK_WIDTH; | |||
| static constexpr GLfloat vertexes[] = { | |||
| 0.0f, 0.0f, // pos 0: top left | |||
| 0.0f, ch , // pos 1: bottom left | |||
| 0.0f, ch, // pos 1: bottom left | |||
| cw, ch, // pos 2: bottom right | |||
| cw, ch, // pos 2: bottom right | |||
| cw, 0.0f, // pos 3: top right | |||
| @@ -44,8 +44,11 @@ struct ChunkProg: public GlProgram { | |||
| void enable() { | |||
| glUseProgram(id()); | |||
| glCheck(); | |||
| glBindBuffer(GL_ARRAY_BUFFER, vbo); | |||
| glCheck(); | |||
| glVertexAttribPointer(vertex, 2, GL_FLOAT, GL_FALSE, 0, (void *)0); | |||
| glCheck(); | |||
| glEnableVertexAttribArray(vertex); | |||
| glCheck(); | |||
| @@ -586,9 +589,9 @@ RenderChunk Renderer::createChunk( | |||
| if constexpr (std::endian::native == std::endian::little) { | |||
| glTexImage2D( | |||
| GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, | |||
| GL_TEXTURE_2D, 0, GL_RG, | |||
| SwanCommon::CHUNK_WIDTH, SwanCommon::CHUNK_HEIGHT, | |||
| 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tiles); | |||
| 0, GL_RG, GL_UNSIGNED_BYTE, tiles); | |||
| glCheck(); | |||
| } else if constexpr (std::endian::native == std::endian::big) { | |||
| uint8_t buf[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT * 2]; | |||
| @@ -602,9 +605,9 @@ RenderChunk Renderer::createChunk( | |||
| } | |||
| glTexImage2D( | |||
| GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, | |||
| GL_TEXTURE_2D, 0, GL_RG, | |||
| SwanCommon::CHUNK_WIDTH, SwanCommon::CHUNK_HEIGHT, | |||
| 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buf); | |||
| 0, GL_RG, GL_UNSIGNED_BYTE, buf); | |||
| glCheck(); | |||
| } | |||
| @@ -624,12 +627,12 @@ void Renderer::modifyChunk(RenderChunk chunk, SwanCommon::Vec2i pos, TileID id) | |||
| if constexpr (std::endian::native == std::endian::little) { | |||
| glTexSubImage2D( | |||
| GL_TEXTURE_2D, 0, pos.x, pos.y, 1, 1, | |||
| GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, &id); | |||
| GL_RG, GL_UNSIGNED_BYTE, &id); | |||
| } else if constexpr (std::endian::native == std::endian::big) { | |||
| uint8_t buf[] = { (uint8_t)(id & 0xff), (uint8_t)((id & 0xff00) >> 8) }; | |||
| glTexSubImage2D( | |||
| GL_TEXTURE_2D, 0, pos.x, pos.y, 1, 1, | |||
| GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buf); | |||
| GL_RG, GL_UNSIGNED_BYTE, buf); | |||
| } | |||
| glCheck(); | |||
| @@ -655,9 +658,9 @@ RenderChunkShadow Renderer::createChunkShadow( | |||
| glCheck(); | |||
| glTexImage2D( | |||
| GL_TEXTURE_2D, 0, GL_LUMINANCE, | |||
| GL_TEXTURE_2D, 0, GL_RED, | |||
| SwanCommon::CHUNK_WIDTH, SwanCommon::CHUNK_HEIGHT, | |||
| 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); | |||
| 0, GL_RED, GL_UNSIGNED_BYTE, data); | |||
| glCheck(); | |||
| return shadow; | |||
| @@ -670,9 +673,9 @@ void Renderer::modifyChunkShadow( | |||
| glBindTexture(GL_TEXTURE_2D, shadow.tex); | |||
| glTexImage2D( | |||
| GL_TEXTURE_2D, 0, GL_LUMINANCE, | |||
| GL_TEXTURE_2D, 0, GL_RED, | |||
| SwanCommon::CHUNK_WIDTH, SwanCommon::CHUNK_HEIGHT, | |||
| 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); | |||
| 0, GL_RED, GL_UNSIGNED_BYTE, data); | |||
| glCheck(); | |||
| } | |||
| @@ -1,83 +0,0 @@ | |||
| #include "Window.h" | |||
| #include <SDL.h> | |||
| #include <iostream> | |||
| #include "gl.h" | |||
| #include "util.h" | |||
| namespace Cygnet { | |||
| struct WindowState { | |||
| SDL_Window *window; | |||
| SDL_GLContext glctx; | |||
| }; | |||
| Window::Window(const char *name, int w, int h): | |||
| state_(std::make_unique<WindowState>()) { | |||
| SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); | |||
| SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); | |||
| SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); | |||
| SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | |||
| SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); | |||
| SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); | |||
| SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8); | |||
| SDL_GL_SetSwapInterval(1); | |||
| state_->window = SDL_CreateWindow(name, | |||
| SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, | |||
| SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | | |||
| SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL); | |||
| sdlCheck(state_->window != NULL); | |||
| state_->glctx = SDL_GL_CreateContext(state_->window); | |||
| glCheck(); | |||
| makeCurrent(); | |||
| glewInit(); | |||
| std::cerr << "OpenGL Version: " << glGetString(GL_VERSION) << '\n'; | |||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
| glEnable(GL_BLEND); | |||
| glCheck(); | |||
| SDL_GetWindowSize(state_->window, &w, &h); | |||
| onResize(w, h); | |||
| } | |||
| Window::~Window() { | |||
| SDL_DestroyWindow(state_->window); | |||
| } | |||
| void Window::makeCurrent() { | |||
| SDL_GL_MakeCurrent(state_->window, state_->glctx); | |||
| glCheck(); | |||
| } | |||
| void Window::clear(Color color) { | |||
| glClearColor(color.r, color.g, color.b, color.a); | |||
| glClear(GL_COLOR_BUFFER_BIT); | |||
| glCheck(); | |||
| } | |||
| void Window::flip() { | |||
| SDL_GL_SwapWindow(state_->window); | |||
| glCheck(); | |||
| } | |||
| void Window::onResize(int w, int h) { | |||
| int dw, dh; | |||
| SDL_GL_GetDrawableSize(state_->window, &dw, &dh); | |||
| glViewport(0, 0, dw, dh); | |||
| glCheck(); | |||
| size_ = {dw, dh}; | |||
| ratio_ = (double)dw / (double)w; | |||
| } | |||
| SDL_Window *Window::sdlWindow() { | |||
| return state_->window; | |||
| } | |||
| } | |||
| @@ -3,32 +3,35 @@ | |||
| namespace Cygnet::Shaders { | |||
| const char *chunkVx = R"glsl( | |||
| #version 410 | |||
| in vec2 vertex; | |||
| uniform mat3 camera; | |||
| uniform vec2 pos; | |||
| attribute vec2 vertex; | |||
| varying vec2 v_tileCoord; | |||
| out vec2 v_tileCoord; | |||
| void main() { | |||
| vec3 pos = camera * vec3(pos + vertex, 1); | |||
| gl_Position = vec4(pos.xy, 0, 1); | |||
| vec3 p = camera * vec3(pos + vertex, 1); | |||
| gl_Position = vec4(p.xy, 0, 1); | |||
| v_tileCoord = vertex; | |||
| } | |||
| )glsl"; | |||
| const char *chunkFr = R"glsl( | |||
| #version 410 | |||
| #define TILE_SIZE 32.0 | |||
| #define CHUNK_WIDTH 64 | |||
| #define CHUNK_HEIGHT 64 | |||
| varying vec2 v_tileCoord; | |||
| in vec2 v_tileCoord; | |||
| uniform sampler2D tileAtlas; | |||
| uniform vec2 tileAtlasSize; | |||
| uniform sampler2D tiles; | |||
| out vec4 fragColor; | |||
| void main() { | |||
| vec2 tilePos = floor(vec2(v_tileCoord.x, v_tileCoord.y)); | |||
| vec4 tileColor = texture2D(tiles, tilePos / vec2(CHUNK_WIDTH, CHUNK_HEIGHT)); | |||
| float tileID = floor((tileColor.r * 256.0 + tileColor.a) * 256.0); | |||
| vec4 tileColor = texture(tiles, tilePos / vec2(CHUNK_WIDTH, CHUNK_HEIGHT)); | |||
| float tileID = floor((tileColor.r * 256.0 + tileColor.g) * 256.0); | |||
| // 1/(TILE_SIZE*16) plays the same role here as in the sprite vertex shader. | |||
| vec2 offset = v_tileCoord - tilePos; | |||
| @@ -37,18 +40,19 @@ const char *chunkFr = R"glsl( | |||
| pixoffset.x + tileID + offset.x, | |||
| pixoffset.y + floor(tileID / tileAtlasSize.x) + offset.y); | |||
| gl_FragColor = texture2D(tileAtlas, atlasPos / tileAtlasSize); | |||
| fragColor = texture(tileAtlas, atlasPos / tileAtlasSize); | |||
| } | |||
| )glsl"; | |||
| const char *chunkShadowVx = R"glsl( | |||
| #version 410 | |||
| #define CHUNK_WIDTH 64 | |||
| #define CHUNK_HEIGHT 64 | |||
| in vec2 vertex; | |||
| uniform mat3 camera; | |||
| uniform vec2 pos; | |||
| attribute vec2 vertex; | |||
| varying vec2 v_texCoord; | |||
| out vec2 v_texCoord; | |||
| void main() { | |||
| vec3 pos = camera * vec3(pos + vertex, 1); | |||
| @@ -58,20 +62,23 @@ const char *chunkShadowVx = R"glsl( | |||
| )glsl"; | |||
| const char *chunkShadowFr = R"glsl( | |||
| varying vec2 v_texCoord; | |||
| #version 410 | |||
| in vec2 v_texCoord; | |||
| uniform sampler2D tex; | |||
| out vec4 fragColor; | |||
| void main() { | |||
| vec4 color = texture2D(tex, v_texCoord); | |||
| gl_FragColor = vec4(0, 0, 0, 1.0 - color.r); | |||
| vec4 color = texture(tex, v_texCoord); | |||
| fragColor = vec4(0, 0, 0, 1.0 - color.r); | |||
| } | |||
| )glsl"; | |||
| const char *tileVx = R"glsl( | |||
| #version 410 | |||
| in vec2 vertex; | |||
| uniform mat3 camera; | |||
| uniform mat3 transform; | |||
| attribute vec2 vertex; | |||
| varying vec2 v_tileCoord; | |||
| out vec2 v_tileCoord; | |||
| void main() { | |||
| vec3 pos = camera * transform * vec3(vertex, 1); | |||
| @@ -81,12 +88,14 @@ const char *tileVx = R"glsl( | |||
| )glsl"; | |||
| const char *tileFr = R"glsl( | |||
| #version 410 | |||
| #define TILE_SIZE 32.0 | |||
| varying vec2 v_tileCoord; | |||
| in vec2 v_tileCoord; | |||
| uniform sampler2D tileAtlas; | |||
| uniform vec2 tileAtlasSize; | |||
| uniform float tileID; | |||
| out vec4 fragColor; | |||
| void main() { | |||
| @@ -97,19 +106,20 @@ const char *tileFr = R"glsl( | |||
| pixoffset.x + tileID + offset.x, | |||
| pixoffset.y + floor(tileID / tileAtlasSize.x) + offset.y); | |||
| gl_FragColor = texture2D(tileAtlas, atlasPos / tileAtlasSize); | |||
| fragColor = texture(tileAtlas, atlasPos / tileAtlasSize); | |||
| } | |||
| )glsl"; | |||
| const char *spriteVx = R"glsl( | |||
| #version 410 | |||
| #define TILE_SIZE 32.0 | |||
| in vec2 vertex; | |||
| uniform mat3 camera; | |||
| uniform mat3 transform; | |||
| uniform vec2 frameSize; | |||
| uniform vec2 frameInfo; // frame count, frame index | |||
| attribute vec2 vertex; | |||
| varying vec2 v_texCoord; | |||
| out vec2 v_texCoord; | |||
| void main() { | |||
| // Here, I'm basically treating 1/(TILE_SIZE*16) as half the size of a "pixel". | |||
| @@ -128,20 +138,23 @@ const char *spriteVx = R"glsl( | |||
| )glsl"; | |||
| const char *spriteFr = R"glsl( | |||
| varying vec2 v_texCoord; | |||
| #version 410 | |||
| in vec2 v_texCoord; | |||
| uniform sampler2D tex; | |||
| out vec4 fragColor; | |||
| void main() { | |||
| gl_FragColor = texture2D(tex, v_texCoord); | |||
| fragColor = texture(tex, v_texCoord); | |||
| } | |||
| )glsl"; | |||
| const char *rectVx = R"glsl( | |||
| #version 410 | |||
| in vec2 vertex; | |||
| uniform mat3 camera; | |||
| uniform vec2 pos; | |||
| uniform vec2 size; | |||
| attribute vec2 vertex; | |||
| varying vec2 v_coord; | |||
| out vec2 v_coord; | |||
| void main() { | |||
| vec3 pos = camera * vec3(pos + vertex * size, 1); | |||
| @@ -151,22 +164,25 @@ const char *rectVx = R"glsl( | |||
| )glsl"; | |||
| const char *rectFr = R"glsl( | |||
| #version 410 | |||
| #define THICKNESS 0.02 | |||
| varying vec2 v_coord; | |||
| in vec2 v_coord; | |||
| uniform vec2 size; | |||
| out vec4 fragColor; | |||
| void main() { | |||
| vec2 invCoord = size - v_coord; | |||
| float minDist = min(v_coord.x, min(v_coord.y, min(invCoord.x, invCoord.y))); | |||
| gl_FragColor = vec4(0.6, 0.6, 0.6, 0.8) * float(minDist < THICKNESS); | |||
| fragColor = vec4(0.6, 0.6, 0.6, 0.8) * float(minDist < THICKNESS); | |||
| } | |||
| )glsl"; | |||
| const char *blendVx = R"glsl( | |||
| attribute vec2 vertex; | |||
| attribute vec2 texCoord; | |||
| varying vec2 v_texCoord; | |||
| #version 410 | |||
| in vec2 vertex; | |||
| in vec2 texCoord; | |||
| out vec2 v_texCoord; | |||
| void main() { | |||
| gl_Position = vec4(vertex.xy, 0, 1); | |||
| @@ -175,12 +191,14 @@ const char *blendVx = R"glsl( | |||
| )glsl"; | |||
| const char *blendFr = R"glsl( | |||
| varying vec2 v_texCoord; | |||
| #version 410 | |||
| in vec2 v_texCoord; | |||
| uniform sampler2D tex; | |||
| out vec4 fragColor; | |||
| void main() { | |||
| //gl_FragColor = vec4(v_texCoord.x, v_texCoord.y, 0, 1); | |||
| gl_FragColor = texture2D(tex, v_texCoord); | |||
| fragColor = texture(tex, v_texCoord); | |||
| } | |||
| )glsl"; | |||
| @@ -1,7 +1,5 @@ | |||
| #include "util.h" | |||
| #include <SDL.h> | |||
| #include "gl.h" | |||
| namespace Cygnet { | |||
| @@ -20,12 +18,6 @@ inline const char *glErrorString(int err) { | |||
| #undef errcase | |||
| } | |||
| void sdlCheck(bool ok) { | |||
| if (!ok) { | |||
| throw SDLError(SDL_GetError()); | |||
| } | |||
| } | |||
| void glCheck() { | |||
| GLenum err = glGetError(); | |||
| if (err != GL_NO_ERROR) { | |||
| @@ -1,6 +1,5 @@ | |||
| #pragma once | |||
| #include <SDL.h> | |||
| #include <cygnet/Renderer.h> | |||
| #include "common.h" | |||
| @@ -4,7 +4,7 @@ | |||
| #include <map> | |||
| #include <string> | |||
| #include <optional> | |||
| #include <SDL.h> | |||
| #include <GLFW/glfw3.h> | |||
| #include <cygnet/Renderer.h> | |||
| #include <cygnet/util.h> | |||
| @@ -18,44 +18,42 @@ class Game { | |||
| public: | |||
| void createWorld(const std::string &worldgen, const std::vector<std::string> &modPaths); | |||
| void onKeyDown(SDL_Keysym sym) { | |||
| pressedKeys_[sym.scancode] = true; | |||
| didPressKeys_[sym.scancode] = true; | |||
| void onKeyDown(int scancode) { | |||
| pressedKeys_[scancode] = true; | |||
| didPressKeys_[scancode] = true; | |||
| } | |||
| void onKeyUp(SDL_Keysym sym) { | |||
| pressedKeys_[sym.scancode] = false; | |||
| didReleaseKeys_[sym.scancode] = true; | |||
| void onKeyUp(int scancode) { | |||
| pressedKeys_[scancode] = false; | |||
| didReleaseKeys_[scancode] = true; | |||
| } | |||
| void onMouseMove(Sint32 x, Sint32 y) { | |||
| mousePos_ = (Vec2{(float)x, (float)y} / (Vec2)cam_.size) * renderer_.winScale(); | |||
| void onMouseMove(float x, float y) { | |||
| mousePos_ = (Vec2{x, y} / (Vec2)cam_.size) * renderer_.winScale(); | |||
| } | |||
| void onMouseDown(Sint32 x, Sint32 y, Uint8 button) { | |||
| onMouseMove(x, y); | |||
| void onMouseDown(int button) { | |||
| pressedButtons_[button] = true; | |||
| didPressButtons_[button] = true; | |||
| } | |||
| void onMouseUp(Sint32 x, Sint32 y, Uint8 button) { | |||
| onMouseMove(x, y); | |||
| void onMouseUp(int button) { | |||
| pressedButtons_[button] = false; | |||
| didReleaseButtons_[button] = true; | |||
| } | |||
| void onScrollWheel(Sint32 y) { | |||
| didScroll_ = (y > 0 ? 1 : -1 ); | |||
| void onScrollWheel(double dy) { | |||
| didScroll_ += dy; | |||
| } | |||
| bool isKeyPressed(SDL_Scancode code) { return pressedKeys_[code]; } | |||
| bool wasKeyPressed(SDL_Scancode code) { return didPressKeys_[code]; } | |||
| bool wasKeyReleased(SDL_Scancode code) { return didReleaseKeys_[code]; } | |||
| bool isKeyPressed(int key) { return pressedKeys_[glfwGetKeyScancode(key)]; } | |||
| bool wasKeyPressed(int key) { return didPressKeys_[glfwGetKeyScancode(key)]; } | |||
| bool wasKeyReleased(int key) { return didReleaseKeys_[glfwGetKeyScancode(key)]; } | |||
| Vec2 getMousePos() { return mousePos_; } | |||
| bool isMousePressed(Uint8 button) { return pressedButtons_[button]; } | |||
| bool wasMousePressed(Uint8 button) { return didPressButtons_[button]; } | |||
| bool wasMouseReleased(Uint8 button) { return didReleaseButtons_[button]; } | |||
| int wasWheelScrolled() { return didScroll_; } | |||
| bool isMousePressed(int button) { return pressedButtons_[button]; } | |||
| bool wasMousePressed(int button) { return didPressButtons_[button]; } | |||
| bool wasMouseReleased(int button) { return didReleaseButtons_[button]; } | |||
| double wasWheelScrolled() { return didScroll_; } | |||
| TilePos getMouseTile(); | |||
| @@ -69,16 +67,16 @@ public: | |||
| Cygnet::RenderCamera cam_{.zoom = 0.125}; | |||
| private: | |||
| std::bitset<SDL_NUM_SCANCODES> pressedKeys_; | |||
| std::bitset<SDL_NUM_SCANCODES> didPressKeys_; | |||
| std::bitset<SDL_NUM_SCANCODES> didReleaseKeys_; | |||
| std::bitset<512> pressedKeys_; | |||
| std::bitset<512> didPressKeys_; | |||
| std::bitset<512> didReleaseKeys_; | |||
| Vec2 mousePos_; | |||
| std::bitset<SDL_BUTTON_X2> pressedButtons_; | |||
| std::bitset<SDL_BUTTON_X2> didPressButtons_; | |||
| std::bitset<SDL_BUTTON_X2> didReleaseButtons_; | |||
| std::bitset<8> pressedButtons_; | |||
| std::bitset<8> didPressButtons_; | |||
| std::bitset<8> didReleaseButtons_; | |||
| int didScroll_ = 0; | |||
| double didScroll_ = 0; | |||
| }; | |||
| } | |||
| @@ -5,7 +5,6 @@ | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <type_traits> | |||
| #include <SDL.h> | |||
| #include "Tile.h" | |||
| #include "Item.h" | |||
| @@ -4,7 +4,6 @@ | |||
| #include <vector> | |||
| #include <string> | |||
| #include <random> | |||
| #include <SDL.h> | |||
| #include <cygnet/Renderer.h> | |||
| #include <cygnet/ResourceManager.h> | |||
| #include <cygnet/util.h> | |||
| @@ -1,7 +1,6 @@ | |||
| #pragma once | |||
| #include <memory> | |||
| #include <SDL.h> | |||
| #include <cygnet/util.h> | |||
| #include "common.h" | |||
| @@ -1,6 +1,5 @@ | |||
| #pragma once | |||
| #include <SDL.h> | |||
| #include <optional> | |||
| #include <initializer_list> | |||
| #include <utility> | |||
| @@ -12,12 +11,5 @@ namespace Draw { | |||
| Cygnet::Color linearGradient( | |||
| float val, std::initializer_list<std::pair<float, Cygnet::Color>> colors); | |||
| /* | |||
| void parallaxBackground( | |||
| Win &win, SDL_Texture *tex, | |||
| std::optional<SDL_Rect> srcrect, std::optional<SDL_Rect> destrect, | |||
| float x, float y, float factor); | |||
| TODO */ | |||
| } | |||
| } | |||
| @@ -1,136 +0,0 @@ | |||
| #include <SDL.h> | |||
| #include <ostream> | |||
| #include "util.h" | |||
| #include "log.h" | |||
| namespace Swan { | |||
| inline std::ostream &operator<<(std::ostream &os, const SDL_Rect &rect) { | |||
| os | |||
| << "SDL_Rect(" << rect.x << ", " << rect.y << ", " | |||
| << rect.w << ", " << rect.h << ")"; | |||
| return os; | |||
| } | |||
| class RenderBlendMode: NonCopyable { | |||
| public: | |||
| RenderBlendMode(SDL_Renderer *rnd, SDL_BlendMode mode): rnd_(rnd) { | |||
| SDL_GetRenderDrawBlendMode(rnd_, &mode_); | |||
| SDL_SetRenderDrawBlendMode(rnd_, mode); | |||
| } | |||
| ~RenderBlendMode() { | |||
| SDL_SetRenderDrawBlendMode(rnd_, mode_); | |||
| } | |||
| private: | |||
| SDL_Renderer *rnd_; | |||
| SDL_BlendMode mode_; | |||
| }; | |||
| class RenderDrawColor: NonCopyable { | |||
| public: | |||
| RenderDrawColor(SDL_Renderer *rnd, Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255): rnd_(rnd) { | |||
| SDL_GetRenderDrawColor(rnd_, &r_, &g_, &b_, &a_); | |||
| SDL_SetRenderDrawColor(rnd_, r, g, b, a); | |||
| } | |||
| void change(Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255) { | |||
| SDL_SetRenderDrawColor(rnd_, r, g, b, a); | |||
| } | |||
| ~RenderDrawColor() { | |||
| SDL_SetRenderDrawColor(rnd_, r_, g_, b_, a_); | |||
| } | |||
| private: | |||
| SDL_Renderer *rnd_; | |||
| Uint8 r_, g_, b_, a_; | |||
| }; | |||
| class RenderClipRect: NonCopyable { | |||
| public: | |||
| RenderClipRect(SDL_Renderer *rnd, SDL_Rect *rect): rnd_(rnd) { | |||
| enabled_ = SDL_RenderIsClipEnabled(rnd_); | |||
| SDL_RenderGetClipRect(rnd_, &rect_); | |||
| SDL_RenderSetClipRect(rnd_, rect); | |||
| } | |||
| ~RenderClipRect() { | |||
| if (enabled_) | |||
| SDL_RenderSetClipRect(rnd_, &rect_); | |||
| else | |||
| SDL_RenderSetClipRect(rnd_, nullptr); | |||
| } | |||
| private: | |||
| SDL_Renderer *rnd_; | |||
| bool enabled_; | |||
| SDL_Rect rect_; | |||
| }; | |||
| class RenderTarget: NonCopyable { | |||
| public: | |||
| RenderTarget(SDL_Renderer *rnd, SDL_Texture *tex): rnd_(rnd) { | |||
| prevTarget_ = SDL_GetRenderTarget(rnd_); | |||
| SDL_SetRenderTarget(rnd_, tex); | |||
| } | |||
| ~RenderTarget() { | |||
| SDL_SetRenderTarget(rnd_, prevTarget_); | |||
| } | |||
| private: | |||
| SDL_Renderer *rnd_; | |||
| SDL_Texture *prevTarget_; | |||
| }; | |||
| class TexLock: NonCopyable { | |||
| public: | |||
| TexLock(SDL_Texture *tex, SDL_Rect *rect = nullptr); | |||
| ~TexLock() { SDL_UnlockTexture(tex_); } | |||
| int blit(SDL_Rect *destrect, SDL_Surface *srcsurf, SDL_Rect *srcrect = nullptr) { | |||
| return SDL_BlitSurface(srcsurf, srcrect, surf_.get(), destrect); | |||
| } | |||
| private: | |||
| SDL_Texture *tex_; | |||
| CPtr<SDL_Surface, SDL_FreeSurface> surf_; | |||
| }; | |||
| class TexColorMod: NonCopyable { | |||
| public: | |||
| TexColorMod(SDL_Texture *tex, Uint8 r, Uint8 g, Uint8 b): tex_(tex) { | |||
| SDL_GetTextureColorMod(tex_, &r_, &g_, &b_); | |||
| SDL_SetTextureColorMod(tex_, r, g, b); | |||
| } | |||
| ~TexColorMod() { | |||
| SDL_SetTextureColorMod(tex_, r_, g_, b_); | |||
| } | |||
| private: | |||
| SDL_Texture *tex_; | |||
| Uint8 r_, g_, b_; | |||
| }; | |||
| class TexAlphaMod: NonCopyable { | |||
| public: | |||
| TexAlphaMod(SDL_Texture *tex, Uint8 alpha): tex_(tex) { | |||
| SDL_GetTextureAlphaMod(tex_, &alpha_); | |||
| SDL_SetTextureAlphaMod(tex_, alpha); | |||
| } | |||
| ~TexAlphaMod() { | |||
| SDL_SetTextureAlphaMod(tex_, alpha_); | |||
| } | |||
| private: | |||
| SDL_Texture *tex_; | |||
| Uint8 alpha_; | |||
| }; | |||
| } | |||
| @@ -20,5 +20,4 @@ | |||
| #include <swan/common.h> | |||
| #include <swan/log.h> | |||
| #include <swan/drawutil.h> | |||
| #include <swan/gfxutil.h> | |||
| #include <swan/util.h> | |||
| @@ -1,6 +1,6 @@ | |||
| libswan_deps = [ | |||
| common, libcygnet, libtracy, libthreads, libsdl2, libsdl2_image, | |||
| libcpptoml, libdl, libz] | |||
| common, libcygnet, libtracy, libthreads, libsdl2_image, | |||
| libcpptoml, libdl, libz, libglfw3] | |||
| libswan = declare_dependency( | |||
| include_directories: 'include', | |||
| @@ -15,7 +15,6 @@ libswan = declare_dependency( | |||
| 'src/drawutil.cc', | |||
| 'src/Entity.cc', | |||
| 'src/Game.cc', | |||
| 'src/gfxutil.cc', | |||
| 'src/ItemStack.cc', | |||
| 'src/LightServer.cc', | |||
| 'src/OS.cc', | |||
| @@ -7,7 +7,6 @@ | |||
| #include "log.h" | |||
| #include "Clock.h" | |||
| #include "gfxutil.h" | |||
| #include "World.h" | |||
| #include "Game.h" | |||
| @@ -34,7 +34,7 @@ void Game::draw() { | |||
| void Game::update(float dt) { | |||
| // Zoom the window using the scroll wheel | |||
| cam_.zoom += (float)wasWheelScrolled() * 0.1f * cam_.zoom; | |||
| cam_.zoom += (float)wasWheelScrolled() * 0.05f * cam_.zoom; | |||
| if (cam_.zoom > 1) | |||
| cam_.zoom = 1; | |||
| else if (cam_.zoom < 0.025) | |||
| @@ -1,6 +1,5 @@ | |||
| #include "assets.h" | |||
| #include <SDL.h> | |||
| #include <SDL_image.h> | |||
| #include <cpptoml.h> | |||
| #include <string.h> | |||
| @@ -3,8 +3,6 @@ | |||
| #include <algorithm> | |||
| #include <cmath> | |||
| #include "gfxutil.h" | |||
| namespace Swan { | |||
| namespace Draw { | |||
| @@ -44,56 +42,5 @@ Cygnet::Color linearGradient( | |||
| return arr[size - 1].second; | |||
| } | |||
| /* | |||
| void parallaxBackground( | |||
| Win &win, SDL_Texture *tex, | |||
| std::optional<SDL_Rect> srcrect, std::optional<SDL_Rect> destrect, | |||
| float x, float y, float factor) { | |||
| SDL_Renderer *rnd = win.renderer_; | |||
| // We only need to set a clip rect if we have a destrect | |||
| std::optional<RenderClipRect> clip; | |||
| if (!srcrect) { | |||
| Uint32 fmt; | |||
| int access, w, h; | |||
| SDL_QueryTexture(tex, &fmt, &access, &w, &h); | |||
| srcrect = SDL_Rect{ 0, 0, w, h }; | |||
| } | |||
| if (destrect) { | |||
| clip.emplace(rnd, &*destrect); | |||
| } else { | |||
| int w, h; | |||
| SDL_RenderGetLogicalSize(rnd, &w, &h); | |||
| destrect = SDL_Rect{ 0, 0, w, h }; | |||
| } | |||
| x = (x * win.zoom_) * -factor; | |||
| y = (y * win.zoom_) * -factor; | |||
| SDL_Rect rect{ | |||
| 0, 0, | |||
| (int)((float)srcrect->w * win.zoom_), | |||
| (int)((float)srcrect->h * win.zoom_), | |||
| }; | |||
| rect.x = (int)std::floor((int)x % rect.w); | |||
| if (rect.x > 0) rect.x -= rect.w; | |||
| rect.y = (int)std::floor((int)y % rect.h); | |||
| if (rect.y > 0) rect.y -= rect.h; | |||
| int numx = destrect->w / rect.w + 2; | |||
| int numy = destrect->h / rect.h + 2; | |||
| for (int x = 0; x < numx; ++x) { | |||
| for (int y = 0; y < numy; ++y) { | |||
| SDL_Rect r{ rect.x + x * rect.w, rect.y + y * rect.h, rect.w, rect.h }; | |||
| SDL_RenderCopy(rnd, tex, &*srcrect, &r); | |||
| } | |||
| } | |||
| } | |||
| TODO */ | |||
| } | |||
| } | |||
| @@ -1,45 +0,0 @@ | |||
| #include "gfxutil.h" | |||
| #include <stdint.h> | |||
| #include "log.h" | |||
| namespace Swan { | |||
| TexLock::TexLock(SDL_Texture *tex, SDL_Rect *rect): tex_(tex) { | |||
| // We must query the texture to get a format... | |||
| uint32_t format; | |||
| int access, texw, texh; | |||
| if (SDL_QueryTexture(tex_, &format, &access, &texw, &texh) < 0) { | |||
| panic << "Failed to query texture: " << SDL_GetError(); | |||
| abort(); | |||
| } | |||
| SDL_Rect lockrect = rect == NULL | |||
| ? SDL_Rect{ 0, 0, texw, texh } | |||
| : *rect; | |||
| // ...and convert that format into masks... | |||
| int bpp = 32; | |||
| uint32_t rmask, gmask, bmask, amask; | |||
| if (SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask) != SDL_TRUE) { | |||
| panic << "Failed to get pixel mask: " << SDL_GetError(); | |||
| abort(); | |||
| } | |||
| // ...and lock the texture... | |||
| uint8_t *pixels; | |||
| int pitch; | |||
| if (SDL_LockTexture(tex_, &lockrect, (void **)&pixels, &pitch) < 0) { | |||
| panic << "Failed to lock texture: " << SDL_GetError(); | |||
| abort(); | |||
| } | |||
| // ...in order to create a surface. | |||
| surf_.reset(SDL_CreateRGBSurfaceFrom( | |||
| pixels, lockrect.w, lockrect.h, | |||
| 32, pitch, rmask, gmask, bmask, amask)); | |||
| } | |||
| } | |||
| @@ -4,11 +4,10 @@ project('swan', 'cpp', | |||
| libdl = meson.get_compiler('cpp').find_library('dl') | |||
| libz = meson.get_compiler('cpp').find_library('z') | |||
| libglew = dependency('glew') | |||
| libglfw3 = dependency('glfw3') | |||
| libgl = dependency('OpenGL') | |||
| #libgl = meson.get_compiler('cpp').find_library('GLESv2') | |||
| libsdl2 = dependency('sdl2') | |||
| libsdl2_image = dependency('SDL2_image') | |||
| libthreads = dependency('threads') | |||
| @@ -24,6 +23,6 @@ subdir('core.mod') | |||
| executable('swan', 'src/main.cc', | |||
| install: true, | |||
| install_rpath: get_option('libdir'), | |||
| dependencies: [libswan, libcygnet, common, libimgui, libsdl2, libsdl2_image]) | |||
| dependencies: [libswan, libcygnet, common, libimgui, libsdl2_image, libgl, libglfw3]) | |||
| install_subdir('assets', install_dir: '') | |||
| @@ -5,13 +5,14 @@ | |||
| #include <chrono> | |||
| #include <ratio> | |||
| #include <SDL.h> | |||
| #define GLFW_INCLUDE_NONE | |||
| #include <GLFW/glfw3.h> | |||
| #include <SDL_image.h> | |||
| #include <string.h> | |||
| #include <imgui.h> | |||
| #include <imgui_sdl.h> | |||
| #include <cygnet/gl.h> | |||
| #include <cygnet/Renderer.h> | |||
| #include <cygnet/Window.h> | |||
| #include <swan/swan.h> | |||
| @@ -27,65 +28,80 @@ using namespace Swan; | |||
| #define sdlassert(expr, str) errassert(expr, str, SDL_GetError); | |||
| #define imgassert(expr, str) errassert(expr, str, IMG_GetError); | |||
| // ImGUI and SDL have different numbers for mouse buttons | |||
| int sdlButtonToImGuiButton(uint8_t button) { | |||
| switch (button) { | |||
| case SDL_BUTTON_LEFT: | |||
| return 0; | |||
| case SDL_BUTTON_RIGHT: | |||
| return 1; | |||
| case SDL_BUTTON_MIDDLE: | |||
| return 2; | |||
| case SDL_BUTTON_X1: | |||
| return 3; | |||
| case SDL_BUTTON_X2: | |||
| return 4; | |||
| default: | |||
| warn << "Unknown mouse button: " << button; | |||
| return 4; // Let's call that X2? | |||
| static Game *gameptr; | |||
| static double pixelRatio = 1; | |||
| static void keyCallback(GLFWwindow *, int key, int scancode, int action, int) { | |||
| if (action == GLFW_PRESS) { | |||
| gameptr->onKeyDown(scancode); | |||
| } else if (action == GLFW_RELEASE) { | |||
| gameptr->onKeyUp(scancode); | |||
| } | |||
| } | |||
| int main(int argc, char **argv) { | |||
| uint32_t winFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; | |||
| uint32_t renderFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; | |||
| float guiScale = 1; | |||
| for (int i = 1; i < argc; ++i) { | |||
| if (strcmp(argv[i], "--lodpi") == 0) { | |||
| winFlags &= ~SDL_WINDOW_ALLOW_HIGHDPI; | |||
| } else if (strcmp(argv[i], "--fullscreen") == 0) { | |||
| winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; | |||
| } else if (strcmp(argv[i], "--no-vsync") == 0) { | |||
| renderFlags &= ~SDL_RENDERER_PRESENTVSYNC; | |||
| } else if (strcmp(argv[i], "--vulkan") == 0) { | |||
| winFlags |= SDL_WINDOW_VULKAN; | |||
| } else if (strcmp(argv[i], "--sw-render") == 0) { | |||
| renderFlags &= ~SDL_RENDERER_ACCELERATED; | |||
| renderFlags |= SDL_RENDERER_SOFTWARE; | |||
| } else if (strcmp(argv[i], "--2x") == 0) { | |||
| guiScale = 2; | |||
| } else if (strcmp(argv[i], "--gles") == 0) { | |||
| SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2"); | |||
| } else { | |||
| warn << "Unknown argument: " << argv[i]; | |||
| } | |||
| static void mouseButtonCallback(GLFWwindow *, int button, int action, int) { | |||
| if (action == GLFW_PRESS) { | |||
| gameptr->onMouseDown(button); | |||
| } else if (action == GLFW_RELEASE) { | |||
| gameptr->onMouseUp(button); | |||
| } | |||
| } | |||
| sdlassert(SDL_Init(SDL_INIT_VIDEO) >= 0, "Could not initialize SDL"); | |||
| Deferred<SDL_Quit> sdl; | |||
| static void cursorPositionCallback(GLFWwindow *, double xpos, double ypos) { | |||
| gameptr->onMouseMove(xpos * pixelRatio, ypos * pixelRatio); | |||
| } | |||
| static void scrollCallback(GLFWwindow *, double dx, double dy) { | |||
| gameptr->onScrollWheel(dy); | |||
| } | |||
| static void windowSizeCallback(GLFWwindow *window, int width, int height) { | |||
| int dw, dh; | |||
| glfwGetFramebufferSize(window, &dw, &dh); | |||
| glViewport(0, 0, dw, dh); | |||
| Cygnet::glCheck(); | |||
| gameptr->cam_.size = {dw, dh}; | |||
| pixelRatio = (double)dw / (double)width; | |||
| } | |||
| int main(int argc, char **argv) { | |||
| glfwInit(); | |||
| Deferred<glfwTerminate> glfw; | |||
| glfwSetErrorCallback(+[](int error, const char* description) { | |||
| warn << "GLFW Error: " << error << ": " << description; | |||
| }); | |||
| int imgFlags = IMG_INIT_PNG; | |||
| imgassert(IMG_Init(imgFlags) == imgFlags, "Could not initialize SDL_Image"); | |||
| Deferred<IMG_Quit> sdlImage; | |||
| Cygnet::Window window("Project: SWAN", 640 * guiScale, 480 * guiScale); | |||
| glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |||
| glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | |||
| glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |||
| glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |||
| GLFWwindow *window = glfwCreateWindow(640, 480, "Project: SWAN", nullptr, nullptr); | |||
| if (!window) { | |||
| panic << "Failed to create window"; | |||
| return 1; | |||
| } | |||
| glfwMakeContextCurrent(window); | |||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
| glEnable(GL_BLEND); | |||
| // Create one global VAO, so we can pretend VAOs don't exist | |||
| GLuint globalVao; | |||
| glGenVertexArrays(1, &globalVao); | |||
| glBindVertexArray(globalVao); | |||
| // Load and display application icon | |||
| /* | |||
| CPtr<SDL_Surface, SDL_FreeSurface> icon( | |||
| IMG_Load("assets/icon.png")); | |||
| sdlassert(icon, "Could not load icon"); | |||
| SDL_SetWindowIcon(window.sdlWindow(), icon.get()); | |||
| SDL_SetWindowIcon(window.sdlWindow(), icon.get());*/ | |||
| // Init ImGUI and ImGUI_SDL | |||
| /* | |||
| @@ -104,10 +120,23 @@ int main(int argc, char **argv) { | |||
| // Create a world | |||
| Game game; | |||
| game.cam_.size = window.size(); | |||
| std::vector<std::string> mods{ "core.mod" }; | |||
| game.createWorld("core::default", mods); | |||
| gameptr = &game; | |||
| glfwSetKeyCallback(window, keyCallback); | |||
| glfwSetMouseButtonCallback(window, mouseButtonCallback); | |||
| glfwSetCursorPosCallback(window, cursorPositionCallback); | |||
| glfwSetScrollCallback(window, scrollCallback); | |||
| glfwSetWindowSizeCallback(window, windowSizeCallback); | |||
| // Initialize window size stuff | |||
| { | |||
| int width, height; | |||
| glfwGetWindowSize(window, &width, &height); | |||
| windowSizeCallback(window, width, height); | |||
| } | |||
| auto prevTime = std::chrono::steady_clock::now(); | |||
| float fpsAcc = 0; | |||
| @@ -115,77 +144,9 @@ int main(int argc, char **argv) { | |||
| int fCount = 0; | |||
| int slowFrames = 0; | |||
| while (1) { | |||
| while (!glfwWindowShouldClose(window)) { | |||
| ZoneScopedN("game loop"); | |||
| SDL_Event evt; | |||
| while (SDL_PollEvent(&evt)) { | |||
| switch (evt.type) { | |||
| case SDL_QUIT: | |||
| goto exit; | |||
| break; | |||
| case SDL_WINDOWEVENT: | |||
| if (evt.window.event == SDL_WINDOWEVENT_RESIZED) { | |||
| window.onResize(evt.window.data1, evt.window.data2); | |||
| //imguiIO.DisplaySize.x = (float)evt.window.data1; | |||
| //imguiIO.DisplaySize.y = (float)evt.window.data2; | |||
| } | |||
| break; | |||
| case SDL_KEYDOWN: | |||
| game.onKeyDown(evt.key.keysym); | |||
| break; | |||
| case SDL_KEYUP: | |||
| game.onKeyUp(evt.key.keysym); | |||
| break; | |||
| case SDL_MOUSEMOTION: | |||
| /* | |||
| imguiIO.MousePos.x = (float)evt.motion.x; | |||
| imguiIO.MousePos.y = (float)evt.motion.y; | |||
| if (!imguiIO.WantCaptureMouse) */ | |||
| game.onMouseMove( | |||
| evt.motion.x * window.pixelRatio(), | |||
| evt.motion.y * window.pixelRatio()); | |||
| break; | |||
| case SDL_MOUSEBUTTONDOWN: | |||
| /* | |||
| imguiIO.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = true; | |||
| if (!imguiIO.WantCaptureMouse) */ | |||
| game.onMouseDown( | |||
| evt.button.x * window.pixelRatio(), | |||
| evt.button.y * window.pixelRatio(), | |||
| evt.button.button); | |||
| break; | |||
| case SDL_MOUSEBUTTONUP: | |||
| /* | |||
| imguiIO.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = false; | |||
| if (!imguiIO.WantCaptureMouse) */ | |||
| game.onMouseUp( | |||
| evt.button.x * window.pixelRatio(), | |||
| evt.button.y * window.pixelRatio(), | |||
| evt.button.button); | |||
| break; | |||
| case SDL_MOUSEWHEEL: | |||
| if (evt.wheel.y == 0) { | |||
| break; | |||
| } | |||
| /* | |||
| imguiIO.MouseWheel += (float)evt.wheel.y; | |||
| if (!imguiIO.WantCaptureMouse) */ | |||
| game.onScrollWheel(evt.wheel.y); | |||
| break; | |||
| } | |||
| } | |||
| game.cam_.size = window.size(); | |||
| auto now = std::chrono::steady_clock::now(); | |||
| std::chrono::duration<float> dur(now - prevTime); | |||
| prevTime = now; | |||
| @@ -247,7 +208,9 @@ int main(int argc, char **argv) { | |||
| } | |||
| { | |||
| window.clear(game.backgroundColor()); | |||
| Cygnet::Color color = game.backgroundColor(); | |||
| glClearColor(color.r, color.g, color.b, color.a); | |||
| glClear(GL_COLOR_BUFFER_BIT); | |||
| } | |||
| // ImGUI | |||
| @@ -268,11 +231,10 @@ int main(int argc, char **argv) { | |||
| { | |||
| ZoneScopedN("render present"); | |||
| window.flip(); | |||
| glfwSwapBuffers(window); | |||
| } | |||
| glfwPollEvents(); | |||
| FrameMark | |||
| } | |||
| exit: | |||
| return EXIT_SUCCESS; | |||
| } | |||
| @@ -1 +0,0 @@ | |||
| Subproject commit 6cb719dc505a9328c6b1fdb801acb64d8d703dda | |||
| @@ -9,16 +9,14 @@ libfmt = declare_dependency( | |||
| include_directories: 'fmt/include')) | |||
| libimgui = declare_dependency( | |||
| include_directories: ['imgui', 'imgui-plot/include', 'imgui_sdl'], | |||
| include_directories: ['imgui', 'imgui-plot/include'], | |||
| link_with: library('imgui', | |||
| 'imgui/imgui_demo.cpp', | |||
| 'imgui/imgui_draw.cpp', | |||
| 'imgui/imgui_widgets.cpp', | |||
| 'imgui/imgui.cpp', | |||
| 'imgui_sdl/imgui_sdl.cpp', | |||
| 'imgui-plot/src/imgui_plot.cpp', | |||
| include_directories: ['imgui', 'imgui-plot/include', 'imgui_sdl'], | |||
| dependencies: libsdl2, | |||
| include_directories: ['imgui', 'imgui-plot/include'], | |||
| cpp_args: ['-Wno-sign-compare', '-Wno-deprecated-enum-enum-conversion'])) | |||
| libmsgpack = declare_dependency( | |||