#include #include #include "Game.h" #include "MarchingCubes.h" #include "gaming-core/utils/Array.h" #include "gaming-core/utils/List.h" #include "gaming-core/utils/Random.h" #include "gaming-core/utils/Utils.h" #include "gaming-core/wrapper/GL.h" Game::Game(Shader& shader, Shader& noiceShader, Shader& particleShader, LayeredFramebuffer& buffer, Buttons& buttons, const Size& size) : shader(shader), noiceShader(noiceShader), particleShader(particleShader), noiceBuffer(buffer), bricks("resources/bricks.png"), bricksBump("resources/bricks_bump.png"), bricksNormal("resources/bricks_normal.png"), buttons(buttons), size(size), frustum(60.0f, 0.1f, 1000.0f, size), up(GLFW_KEY_SPACE, "Up"), down(GLFW_KEY_LEFT_SHIFT, "Down"), left(GLFW_KEY_A, "left"), right(GLFW_KEY_D, "right"), front(GLFW_KEY_W, "front"), back(GLFW_KEY_S, "back"), toggle(GLFW_KEY_T, "toggle"), scaleUp(GLFW_KEY_G, "scale up"), scaleDown(GLFW_KEY_H, "scale down"), stepsUp(GLFW_KEY_Y, "steps up"), stepsDown(GLFW_KEY_U, "steps down"), fineStepsUp(GLFW_KEY_I, "fine steps up"), fineStepsDown(GLFW_KEY_O, "fine steps down"), modeToggle(GLFW_KEY_C, "mode toggle"), primaryMouse(GLFW_MOUSE_BUTTON_1, "primary click"), timeUp(GLFW_KEY_N, "time up"), timeDown(GLFW_KEY_M, "time down"), oldHeight(0.0f), height(0.0f), heightScale(0.01f), steps(1), fineSteps(1), mode(false), time(0.0f), emitterAge(999999.0f), timeFactor(1.0f) { buttons.add(up); buttons.add(down); buttons.add(left); buttons.add(right); buttons.add(front); buttons.add(back); buttons.add(toggle); buttons.add(scaleUp); buttons.add(scaleDown); buttons.add(stepsUp); buttons.add(stepsDown); buttons.add(fineStepsUp); buttons.add(fineStepsDown); buttons.add(modeToggle); buttons.add(timeUp); buttons.add(timeDown); buttons.addMouse(primaryMouse); bricks.setLinearFilter(); bricksBump.setLinearFilter(); bricksNormal.setLinearFilter(); position = Vector3(-32.0f, 0.0f, -120.0f); rectangleBuffer.setAttributes(Attributes().addFloat(2)); float recData[6][2] = {{-1.0f, -1.0f}, {-1.0, 1.0}, {1.0, -1.0}, {1.0f, 1.0f}, {-1.0, 1.0}, {1.0, -1.0}}; rectangleBuffer.setStaticData(sizeof(recData), recData); noiceBuffer.bindTextureTo(0); } void Game::render(float lag) { GL::setViewport(64, 64); noiceShader.use(); noiceBuffer.bindAndClear(); float step = 1.0f / 31.5f; noiceShader.setFloat("height", oldHeight * step); for(int i = 0; i < 64; i++) { noiceShader.setFloat("layer", i * step - 1.0f); noiceBuffer.bindLayer(i); rectangleBuffer.draw(6); } GL::setViewport(size.width, size.height); shader.use(); GL::bindMainFramebuffer(); GL::clear(); Matrix& proj = frustum.updateProjection(); shader.setMatrix("proj", proj.getValues()); Matrix m; m.translate(Utils::interpolate(oldPosition, position, lag)); m.translateY(-32.0f + (oldHeight - height) * lag); shader.setMatrix("view", m.getValues()); shader.setFloat("height", oldHeight * step * 0.5f); shader.setVector("viewPos", -position + Vector3(0.0f, 32.0f, 0.0f)); shader.setVector("lightPos", Vector3()); shader.setFloat("heightScale", heightScale); shader.setInt("steps", steps); shader.setInt("fineSteps", fineSteps); shader.setInt("kajetan", mode); if(toggle.isDown()) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } noiceBuffer.bindTextureTo(0); bricks.bindTo(1); bricksBump.bindTo(2); bricksNormal.bindTo(3); emptyBuffer.drawPoints(64 * 64 * 64); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPointSize(5.0f); particleShader.use(); particleShader.setMatrix("proj", proj.getValues()); m.translateTo(Utils::interpolate(oldPosition, position, lag)); m.translateY(-32.0f - (oldHeight + (height - oldHeight) * lag)); particleShader.setMatrix("view", m.getValues()); particleShader.setFloat("time", time + lag); GL::enableBlending(); glDepthMask(false); if(primaryMouse.wasReleased()) { noiceBuffer.bindTextureTo(0); static float buffer[64][64][64]; glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_FLOAT, buffer); float hWidth = size.width * 0.5f; float hHeight = size.height * 0.5f; float x = (buttons.getMouseX() - hWidth) / hWidth; float y = -(buttons.getMouseY() - hHeight) / hHeight; float aspect = hWidth / hHeight; float tan = tanf((0.5f * frustum.fieldOfView) * M_PI / 180.0f); float q = 1.0f / tan; Vector3 direction(x / (q / aspect), y / q, 1.0f); direction[2] = -direction[2]; direction.normalize(); Vector3 pos = -position; pos[1] = 32.0f; pos[1] = 32.0f; for(int i = 0; i < 150; i++) { int x = pos[0] + 0.5f; int y = pos[1] + 0.5f; int z = pos[2] + 0.5f; if(x >= 0 && x < 64 && y >= 0 && y < 64 && z >= 0 && z < 64 && buffer[x][y][z] > 0.5f) { emitterPos = pos + Vector3(0.0f, height, 0.0f); emitterAge = time; break; } pos += direction; } } particleShader.setFloat("timeFactor", timeFactor); particleShader.setVector("position", emitterPos); particleShader.setFloat("age", emitterAge); particleShader.setVector("color", Vector4(1.0f, 0.0f, 0.0f, 1.0f)); particleShader.setInt("seedBase", 0); emptyBuffer.drawPoints(2000000); particleShader.setVector("position", emitterPos); particleShader.setFloat("age", emitterAge + 5); particleShader.setVector("color", Vector4(0.0f, 1.0f, 0.0f, 1.0f)); particleShader.setInt("seedBase", 1); emptyBuffer.drawPoints(10000); particleShader.setVector("position", emitterPos); particleShader.setFloat("age", emitterAge + 10); particleShader.setVector("color", Vector4(0.0f, 0.0f, 1.0f, 1.0f)); particleShader.setInt("seedBase", 2); emptyBuffer.drawPoints(5000); particleShader.setVector("position", emitterPos); particleShader.setFloat("age", emitterAge + 20); particleShader.setVector("color", Vector4(0.0f, 1.0f, 1.0f, 1.0f)); particleShader.setInt("seedBase", 2); emptyBuffer.drawPoints(5000); glDepthMask(true); GL::disableBlending(); } void Game::tick() { if(timeUp.isDown()) { timeFactor *= 1.05f; std::cout << timeFactor << "\n"; } if(timeDown.isDown()) { timeFactor /= 1.05f; std::cout << timeFactor << "\n"; } time++; oldHeight = height; oldPosition = position; if(up.isDown()) { height += 1.0f; } if(down.isDown()) { height -= 1.0f; } const float speed = 1.15f; if(left.isDown()) { position += Vector3(speed, 0.0f, 0.0f); } if(right.isDown()) { position -= Vector3(speed, 0.0f, 0.0f); } if(front.isDown()) { position += Vector3(0.0f, 0.0f, speed); } if(back.isDown()) { position -= Vector3(0.0f, 0.0f, speed); } if(scaleUp.isDown()) { heightScale += 0.005f; } if(scaleDown.isDown()) { heightScale -= 0.005f; if(heightScale < 0.0f) { heightScale = 0.0f; } } if(stepsUp.wasReleased()) { steps++; } if(stepsDown.wasReleased() && steps > 1) { steps--; } if(fineStepsUp.wasReleased()) { fineSteps++; } if(fineStepsDown.wasReleased() && fineSteps > 1) { fineSteps--; } if(modeToggle.wasReleased()) { mode = !mode; } } bool Game::isRunning() const { return true; }