merge
This commit is contained in:
commit
68b31cb197
17
ActiveObject.h
Normal file
17
ActiveObject.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "TextureManager.h"
|
||||||
|
#include "Math.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct ActiveObject {
|
||||||
|
std::shared_ptr<ZL::Texture> activeObjectTexturePtr;
|
||||||
|
ZL::VertexDataStruct activeObjectMesh;
|
||||||
|
ZL::VertexRenderStruct activeObjectMeshMutable;
|
||||||
|
|
||||||
|
std::shared_ptr<ZL::Texture> activeObjectScreenTexturePtr;
|
||||||
|
ZL::VertexDataStruct activeObjectScreenMesh;
|
||||||
|
ZL::VertexRenderStruct activeObjectScreenMeshMutable;
|
||||||
|
|
||||||
|
ZL::Vector3f objectPos;
|
||||||
|
bool highlighted = false;
|
||||||
|
};
|
||||||
18
Environment.cpp
Normal file
18
Environment.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "Environment.h"
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
|
||||||
|
int Environment::windowHeaderHeight = 0;
|
||||||
|
int Environment::width = 0;
|
||||||
|
int Environment::height = 0;
|
||||||
|
float Environment::zoom = 10.0f;
|
||||||
|
|
||||||
|
bool Environment::leftPressed = false;
|
||||||
|
bool Environment::rightPressed = false;
|
||||||
|
bool Environment::upPressed = false;
|
||||||
|
bool Environment::downPressed = false;
|
||||||
|
|
||||||
|
Vector3f Environment::cameraShift = {0, 0, 0};
|
||||||
|
Vector3f Environment::characterPos = {0, 0, 0};
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
22
Environment.h
Normal file
22
Environment.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Math.h"
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
|
||||||
|
class Environment {
|
||||||
|
public:
|
||||||
|
static int windowHeaderHeight;
|
||||||
|
static int width;
|
||||||
|
static int height;
|
||||||
|
static float zoom;
|
||||||
|
|
||||||
|
static bool leftPressed;
|
||||||
|
static bool rightPressed;
|
||||||
|
static bool upPressed;
|
||||||
|
static bool downPressed;
|
||||||
|
|
||||||
|
static Vector3f cameraShift;
|
||||||
|
static Vector3f characterPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
99
Game.cpp
99
Game.cpp
@ -1,8 +1,105 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "AnimatedModel.h"
|
#include "AnimatedModel.h"
|
||||||
#include "BoneAnimatedModel.h"
|
#include "BoneAnimatedModel.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Inventory.h" // Add this include
|
||||||
|
#include "OpenGlExtensions.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace ZL
|
namespace ZL
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
Game::Game()
|
||||||
|
: window(nullptr)
|
||||||
|
, glContext(nullptr)
|
||||||
|
, exitGameLoop(false)
|
||||||
|
, newTickCount(0)
|
||||||
|
, lastTickCount(0)
|
||||||
|
, renderer(renderSystem.getRenderer()) // Инициализация ссылки на renderer
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::~Game() {
|
||||||
|
if (glContext) {
|
||||||
|
SDL_GL_DeleteContext(glContext);
|
||||||
|
}
|
||||||
|
if (window) {
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
}
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::setup() {
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
|
||||||
|
SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
|
|
||||||
|
window = SDL_CreateWindow("Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
Environment::width, Environment::height, SDL_WINDOW_OPENGL);
|
||||||
|
|
||||||
|
glContext = SDL_GL_CreateContext(window);
|
||||||
|
|
||||||
|
ZL::BindOpenGlFunctions();
|
||||||
|
ZL::CheckGlError();
|
||||||
|
|
||||||
|
// Initialize renderer
|
||||||
|
renderer.shaderManager.AddShaderFromFiles("default", "./default.vertex", "./default.fragment");
|
||||||
|
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./defaultColor.vertex", "./defaultColor.fragment");
|
||||||
|
renderer.InitOpenGL();
|
||||||
|
|
||||||
|
// Initialize game objects
|
||||||
|
gameObjects.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::drawScene() {
|
||||||
|
// Вместо прямого рисования используем RenderSystem
|
||||||
|
renderSystem.drawScene(gameObjects);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::processTickCount() {
|
||||||
|
if (lastTickCount == 0) {
|
||||||
|
lastTickCount = SDL_GetTicks64();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newTickCount = SDL_GetTicks64();
|
||||||
|
if (newTickCount - lastTickCount > CONST_TIMER_INTERVAL) {
|
||||||
|
size_t delta = (newTickCount - lastTickCount > CONST_MAX_TIME_INTERVAL) ?
|
||||||
|
CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount;
|
||||||
|
|
||||||
|
gameObjects.update();
|
||||||
|
|
||||||
|
lastTickCount = newTickCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::render() {
|
||||||
|
SDL_GL_MakeCurrent(window, glContext);
|
||||||
|
ZL::CheckGlError();
|
||||||
|
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
drawScene();
|
||||||
|
processTickCount();
|
||||||
|
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::update() {
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
if (event.type == SDL_QUIT) {
|
||||||
|
exitGameLoop = true;
|
||||||
|
}
|
||||||
|
gameObjects.handleEvent(event);
|
||||||
|
}
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
46
Game.h
46
Game.h
@ -1,14 +1,40 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Math.h"
|
#include "OpenGlExtensions.h"
|
||||||
#include "Physics.h"
|
#include "GameObjectManager.h"
|
||||||
#include "TextureManager.h"
|
#include "RenderSystem.h"
|
||||||
#include "Renderer.h"
|
#include "Environment.h"
|
||||||
#include "AnimatedModel.h"
|
|
||||||
#include "BoneAnimatedModel.h"
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace ZL
|
namespace ZL {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
class Game {
|
||||||
|
public:
|
||||||
|
Game();
|
||||||
|
~Game();
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
void run();
|
||||||
|
void update();
|
||||||
|
void render();
|
||||||
|
|
||||||
|
bool shouldExit() const { return exitGameLoop; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void processTickCount();
|
||||||
|
void drawScene();
|
||||||
|
|
||||||
|
SDL_Window* window;
|
||||||
|
SDL_GLContext glContext;
|
||||||
|
RenderSystem renderSystem;
|
||||||
|
GameObjectManager gameObjects;
|
||||||
|
Renderer& renderer; // Ссылка на renderer из RenderSystem
|
||||||
|
|
||||||
|
bool exitGameLoop;
|
||||||
|
size_t newTickCount;
|
||||||
|
size_t lastTickCount;
|
||||||
|
|
||||||
|
static const size_t CONST_TIMER_INTERVAL = 10;
|
||||||
|
static const size_t CONST_MAX_TIME_INTERVAL = 1000;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
228
GameObjectManager.cpp
Normal file
228
GameObjectManager.cpp
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
#include "GameObjectManager.h"
|
||||||
|
#include "Environment.h"
|
||||||
|
#include "ObjLoader.h"
|
||||||
|
#include "Inventory.h"
|
||||||
|
#include "TextModel.h" // Add this include for LoadFromTextFile
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
|
||||||
|
const float GameObjectManager::INVENTORY_ICON_SIZE = 32.0f;
|
||||||
|
const float GameObjectManager::INVENTORY_MARGIN = 10.0f;
|
||||||
|
|
||||||
|
void GameObjectManager::initialize() {
|
||||||
|
// Load textures
|
||||||
|
roomTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp"));
|
||||||
|
coneTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./conus.bmp"));
|
||||||
|
|
||||||
|
// Load models
|
||||||
|
colorCubeMesh = CreateCube3D(5.0);
|
||||||
|
colorCubeMeshMutable.data = CreateCube3D(5.0);
|
||||||
|
colorCubeMeshMutable.RefreshVBO();
|
||||||
|
|
||||||
|
testObjMesh = LoadFromObjFile("./chair_01.obj");
|
||||||
|
testObjMesh.Scale(10);
|
||||||
|
testObjMesh.SwapZandY();
|
||||||
|
testObjMeshMutable.data = testObjMesh;
|
||||||
|
testObjMeshMutable.RefreshVBO();
|
||||||
|
|
||||||
|
textMesh = ZL::LoadFromTextFile("./mesh001.txt"); // Add ZL:: namespace
|
||||||
|
coneMesh = ZL::LoadFromTextFile("./cone001.txt"); // Add ZL:: namespace
|
||||||
|
coneMesh.Scale(200);
|
||||||
|
|
||||||
|
textMeshMutable.AssignFrom(textMesh);
|
||||||
|
textMeshMutable.RefreshVBO();
|
||||||
|
coneMeshMutable.AssignFrom(coneMesh);
|
||||||
|
coneMeshMutable.RefreshVBO();
|
||||||
|
|
||||||
|
// Load bone animations
|
||||||
|
bx.LoadFromFile("mesh_armature_and_animation_data.txt");
|
||||||
|
|
||||||
|
// Create active object
|
||||||
|
ActiveObject ao1;
|
||||||
|
ao1.activeObjectMesh = ZL::LoadFromTextFile("./book001.txt"); // Add ZL:: namespace
|
||||||
|
ao1.activeObjectMesh.Scale(4);
|
||||||
|
ao1.activeObjectMeshMutable.AssignFrom(ao1.activeObjectMesh);
|
||||||
|
ao1.activeObjectMeshMutable.RefreshVBO();
|
||||||
|
ao1.objectPos = Vector3f{50, 0, -300};
|
||||||
|
ao1.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./book03.bmp"));
|
||||||
|
ao1.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
|
||||||
|
ao1.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
|
||||||
|
ao1.activeObjectScreenMeshMutable.AssignFrom(ao1.activeObjectScreenMesh);
|
||||||
|
ao1.activeObjectScreenMeshMutable.RefreshVBO();
|
||||||
|
activeObjects.push_back(ao1);
|
||||||
|
|
||||||
|
// Initialize audio
|
||||||
|
audioPlayer = std::make_unique<AudioPlayer>();
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer->playMusic("Symphony No.6 (1st movement).ogg");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize inventory
|
||||||
|
inventoryIconMesh = CreateRect2D(
|
||||||
|
{0.0f, 0.0f},
|
||||||
|
{INVENTORY_ICON_SIZE/2, INVENTORY_ICON_SIZE/2},
|
||||||
|
0.5f
|
||||||
|
);
|
||||||
|
inventoryIconMeshMutable.AssignFrom(inventoryIconMesh);
|
||||||
|
inventoryIconMeshMutable.RefreshVBO();
|
||||||
|
|
||||||
|
// Add test items to inventory
|
||||||
|
auto testRoomTexture = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp"));
|
||||||
|
auto testConeTexture = std::make_shared<Texture>(CreateTextureDataFromBmp24("./conus.bmp"));
|
||||||
|
AddItemToInventory("RoomCeramics", testRoomTexture);
|
||||||
|
AddItemToInventory("Cone", testConeTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObjectManager::update() {
|
||||||
|
updateScene(16); // Добавим фиксированный timestep для обновления сцены
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObjectManager::handleEvent(const SDL_Event& event) {
|
||||||
|
if (event.type == SDL_MOUSEBUTTONDOWN) {
|
||||||
|
bx.Interpolate(animationCounter);
|
||||||
|
animationCounter += 2;
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_MOUSEWHEEL) {
|
||||||
|
static const float zoomstep = 1.0f;
|
||||||
|
if (event.wheel.y > 0) {
|
||||||
|
Environment::zoom -= zoomstep;
|
||||||
|
}
|
||||||
|
else if (event.wheel.y < 0) {
|
||||||
|
Environment::zoom += zoomstep;
|
||||||
|
}
|
||||||
|
if (Environment::zoom < zoomstep) {
|
||||||
|
Environment::zoom = zoomstep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_KEYDOWN) {
|
||||||
|
switch (event.key.keysym.sym) {
|
||||||
|
case SDLK_LEFT:
|
||||||
|
case SDLK_a:
|
||||||
|
Environment::leftPressed = true;
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
case SDLK_d:
|
||||||
|
Environment::rightPressed = true;
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDLK_UP:
|
||||||
|
case SDLK_w:
|
||||||
|
Environment::upPressed = true;
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDLK_DOWN:
|
||||||
|
case SDLK_s:
|
||||||
|
Environment::downPressed = true;
|
||||||
|
if (audioPlayer) {
|
||||||
|
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// ...handle other keys...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_KEYUP) {
|
||||||
|
switch (event.key.keysym.sym) {
|
||||||
|
case SDLK_LEFT:
|
||||||
|
case SDLK_a:
|
||||||
|
Environment::leftPressed = false;
|
||||||
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
case SDLK_d:
|
||||||
|
Environment::rightPressed = false;
|
||||||
|
break;
|
||||||
|
case SDLK_UP:
|
||||||
|
case SDLK_w:
|
||||||
|
Environment::upPressed = false;
|
||||||
|
break;
|
||||||
|
case SDLK_DOWN:
|
||||||
|
case SDLK_s:
|
||||||
|
Environment::downPressed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event.type == SDL_MOUSEMOTION) {
|
||||||
|
// Сохраняем позицию мыши для последующей проверки
|
||||||
|
lastMouseX = event.motion.x;
|
||||||
|
lastMouseY = event.motion.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObjectManager::updateScene(size_t ms) {
|
||||||
|
const float SPEED = 0.1f;
|
||||||
|
if (Environment::leftPressed) {
|
||||||
|
Environment::cameraShift.v[0] += SPEED * ms;
|
||||||
|
}
|
||||||
|
if (Environment::rightPressed) {
|
||||||
|
Environment::cameraShift.v[0] -= SPEED * ms;
|
||||||
|
}
|
||||||
|
if (Environment::upPressed) {
|
||||||
|
Environment::cameraShift.v[2] += SPEED * ms;
|
||||||
|
}
|
||||||
|
if (Environment::downPressed) {
|
||||||
|
Environment::cameraShift.v[2] -= SPEED * ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::characterPos.v[0] = -Environment::cameraShift.v[0];
|
||||||
|
Environment::characterPos.v[1] = -Environment::cameraShift.v[1];
|
||||||
|
Environment::characterPos.v[2] = -Environment::cameraShift.v[2];
|
||||||
|
|
||||||
|
for (auto& ao : activeObjects) {
|
||||||
|
float dist = sqrtf(
|
||||||
|
pow(Environment::characterPos.v[0] - ao.objectPos.v[0], 2) +
|
||||||
|
pow(Environment::characterPos.v[1] - ao.objectPos.v[1], 2) +
|
||||||
|
pow(Environment::characterPos.v[2] - ao.objectPos.v[2], 2)
|
||||||
|
);
|
||||||
|
ao.highlighted = (dist < 50.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameObjectManager::isPointInObject(int screenX, int screenY, int objectScreenX, int objectScreenY) const {
|
||||||
|
// Простая проверка попадания точки в квадрат 64x64 вокруг центра объекта
|
||||||
|
const int objectSize = 32; // Половина размера области выделения
|
||||||
|
return (screenX >= objectScreenX - objectSize &&
|
||||||
|
screenX <= objectScreenX + objectSize &&
|
||||||
|
screenY >= objectScreenY - objectSize &&
|
||||||
|
screenY <= objectScreenY + objectSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObjectManager::checkMouseIntersection(int mouseX, int mouseY, const Matrix4f& projectionModelView) {
|
||||||
|
for (auto& ao : activeObjects) {
|
||||||
|
int screenX, screenY;
|
||||||
|
worldToScreenCoordinates(ao.objectPos, projectionModelView,
|
||||||
|
Environment::width, Environment::height, screenX, screenY);
|
||||||
|
|
||||||
|
if (isPointInObject(mouseX, mouseY, screenX, screenY)) {
|
||||||
|
std::cout << "Mouse over object at screen coordinates: "
|
||||||
|
<< screenX << ", " << screenY
|
||||||
|
<< " (world pos: "
|
||||||
|
<< ao.objectPos.v[0] << ", "
|
||||||
|
<< ao.objectPos.v[1] << ", "
|
||||||
|
<< ao.objectPos.v[2] << ")"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObjectManager::worldToScreenCoordinates(Vector3f objectPos,
|
||||||
|
Matrix4f projectionModelView,
|
||||||
|
int screenWidth, int screenHeight,
|
||||||
|
int& screenX, int& screenY) {
|
||||||
|
|
||||||
|
Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f};
|
||||||
|
Vector4f clipCoords = MultMatrixVector(projectionModelView, inx);
|
||||||
|
|
||||||
|
float ndcX = clipCoords.v[0] / clipCoords.v[3];
|
||||||
|
float ndcY = clipCoords.v[1] / clipCoords.v[3];
|
||||||
|
|
||||||
|
screenX = (int)((ndcX + 1.0f) * 0.5f * screenWidth);
|
||||||
|
screenY = (int)((1.0f + ndcY) * 0.5f * screenHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
59
GameObjectManager.h
Normal file
59
GameObjectManager.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "TextureManager.h"
|
||||||
|
#include "BoneAnimatedModel.h"
|
||||||
|
#include "cmakeaudioplayer/include/AudioPlayer.hpp"
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include "ActiveObject.h"
|
||||||
|
#include "OpenGlExtensions.h"
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
|
||||||
|
class GameObjectManager {
|
||||||
|
public:
|
||||||
|
void initialize();
|
||||||
|
void update();
|
||||||
|
void handleEvent(const SDL_Event& event);
|
||||||
|
void updateScene(size_t ms);
|
||||||
|
void checkMouseIntersection(int mouseX, int mouseY, const Matrix4f& projectionModelView); // Добавляем новый метод
|
||||||
|
|
||||||
|
std::shared_ptr<ZL::Texture> testObjTexturePtr;
|
||||||
|
std::shared_ptr<ZL::Texture> roomTexturePtr;
|
||||||
|
std::shared_ptr<ZL::Texture> coneTexturePtr;
|
||||||
|
|
||||||
|
ZL::VertexDataStruct colorCubeMesh;
|
||||||
|
ZL::VertexRenderStruct colorCubeMeshMutable;
|
||||||
|
|
||||||
|
ZL::VertexDataStruct testObjMesh;
|
||||||
|
ZL::VertexRenderStruct testObjMeshMutable;
|
||||||
|
|
||||||
|
ZL::BoneSystem bx;
|
||||||
|
ZL::VertexRenderStruct bxMutable;
|
||||||
|
|
||||||
|
ZL::VertexDataStruct textMesh;
|
||||||
|
ZL::VertexRenderStruct textMeshMutable;
|
||||||
|
|
||||||
|
ZL::VertexDataStruct coneMesh;
|
||||||
|
ZL::VertexRenderStruct coneMeshMutable;
|
||||||
|
|
||||||
|
std::vector<ActiveObject> activeObjects;
|
||||||
|
std::unique_ptr<AudioPlayer> audioPlayer;
|
||||||
|
|
||||||
|
ZL::VertexDataStruct inventoryIconMesh;
|
||||||
|
ZL::VertexRenderStruct inventoryIconMeshMutable;
|
||||||
|
|
||||||
|
static const float INVENTORY_ICON_SIZE;
|
||||||
|
static const float INVENTORY_MARGIN;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int animationCounter = 0;
|
||||||
|
int lastMouseX = 0; // Добавляем переменные для хранения позиции мыши
|
||||||
|
int lastMouseY = 0;
|
||||||
|
bool isPointInObject(int screenX, int screenY, int objectScreenX, int objectScreenY) const;
|
||||||
|
void worldToScreenCoordinates(Vector3f objectPos, // Добавляем метод
|
||||||
|
Matrix4f projectionModelView,
|
||||||
|
int screenWidth, int screenHeight,
|
||||||
|
int& screenX, int& screenY);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
23
GameWorld.cpp
Normal file
23
GameWorld.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "GameWorld.h"
|
||||||
|
#include "InputManager.h"
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
GameWorld& GameWorld::getInstance() {
|
||||||
|
static GameWorld instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameWorld::update(float deltaTime) {
|
||||||
|
auto& input = InputManager::getInstance();
|
||||||
|
|
||||||
|
// Update game state based on input
|
||||||
|
if (input.isKeyPressed(SDL_SCANCODE_W)) {
|
||||||
|
// Move forward
|
||||||
|
}
|
||||||
|
// ... handle other game logic ...
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameWorld::addObject(const Vector3f& position) {
|
||||||
|
mGameObjects.push_back(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
GameWorld.h
Normal file
18
GameWorld.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Math.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
class GameWorld {
|
||||||
|
public:
|
||||||
|
static GameWorld& getInstance();
|
||||||
|
void update(float deltaTime);
|
||||||
|
void addObject(const Vector3f& position);
|
||||||
|
// ...other game world related methods...
|
||||||
|
|
||||||
|
private:
|
||||||
|
GameWorld() = default;
|
||||||
|
std::vector<Vector3f> mGameObjects;
|
||||||
|
};
|
||||||
|
}
|
||||||
27
InputManager.cpp
Normal file
27
InputManager.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "InputManager.h"
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
InputManager& InputManager::getInstance() {
|
||||||
|
static InputManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputManager::processInput() {
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
if (event.type == SDL_QUIT) {
|
||||||
|
mShouldQuit = true;
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_KEYDOWN) {
|
||||||
|
mKeys[event.key.keysym.scancode] = true;
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_KEYUP) {
|
||||||
|
mKeys[event.key.keysym.scancode] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputManager::isKeyPressed(SDL_Scancode key) const {
|
||||||
|
return mKeys[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
17
InputManager.h
Normal file
17
InputManager.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "OpenGlExtensions.h"
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
class InputManager {
|
||||||
|
public:
|
||||||
|
static InputManager& getInstance();
|
||||||
|
void processInput();
|
||||||
|
bool isKeyPressed(SDL_Scancode key) const;
|
||||||
|
bool shouldQuit() const { return mShouldQuit; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
InputManager() = default;
|
||||||
|
bool mKeys[SDL_NUM_SCANCODES] = {false};
|
||||||
|
bool mShouldQuit = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -38,6 +38,10 @@ https://github.com/gametutorials/tutorials/blob/master/OpenGL/MD3%20Animation/Ma
|
|||||||
|
|
||||||
linux:
|
linux:
|
||||||
```
|
```
|
||||||
g++ Game.cpp main.cpp Math.cpp OpenGlExtensions.cpp Physics.cpp Renderer.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp BoneAnimatedModel.cpp ObjLoader.cpp -o sdl_app -O2 -std=c++14 $(pkg-config --cflags --libs sdl2 gl)
|
g++ Game.cpp main.cpp Math.cpp OpenGlExtensions.cpp Physics.cpp Renderer.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp BoneAnimatedModel.cpp ObjLoader.cpp cmakeaudioplayer/src/AudioPlayer.cpp TextModel.cpp Inventory.cpp -o sdl_app -O2 -std=c++17 \
|
||||||
|
-I cmakeaudioplayer/include \
|
||||||
|
$(pkg-config --cflags --libs sdl2 gl) \
|
||||||
|
$(pkg-config --cflags --libs vorbis vorbisfile ogg) \
|
||||||
|
-lopenal
|
||||||
|
|
||||||
```
|
```
|
||||||
137
RenderSystem.cpp
Normal file
137
RenderSystem.cpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#include "RenderSystem.h"
|
||||||
|
#include "Environment.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Inventory.h"
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
|
||||||
|
void RenderSystem::initialize() {
|
||||||
|
renderer.shaderManager.AddShaderFromFiles("default", "./default.vertex", "./default.fragment");
|
||||||
|
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./defaultColor.vertex", "./defaultColor.fragment");
|
||||||
|
renderer.InitOpenGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderSystem::drawScene(const GameObjectManager& gameObjects) {
|
||||||
|
static const std::string defaultShaderName = "default";
|
||||||
|
static const std::string vPositionName = "vPosition";
|
||||||
|
static const std::string vTexCoordName = "vTexCoord";
|
||||||
|
static const std::string textureUniformName = "Texture";
|
||||||
|
|
||||||
|
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glViewport(0, 0, Environment::width, Environment::height);
|
||||||
|
|
||||||
|
renderer.shaderManager.PushShader(defaultShaderName);
|
||||||
|
renderer.RenderUniform1i(textureUniformName, 0);
|
||||||
|
|
||||||
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
|
renderer.EnableVertexAttribArray(vTexCoordName);
|
||||||
|
|
||||||
|
drawWorld(gameObjects);
|
||||||
|
drawUI(gameObjects);
|
||||||
|
|
||||||
|
renderer.DisableVertexAttribArray(vPositionName);
|
||||||
|
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||||
|
renderer.shaderManager.PopShader();
|
||||||
|
|
||||||
|
CheckGlError();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderSystem::drawWorld(const GameObjectManager& gameObjects) {
|
||||||
|
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||||
|
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||||
|
50, 10000);
|
||||||
|
renderer.PushMatrix();
|
||||||
|
|
||||||
|
renderer.LoadIdentity();
|
||||||
|
renderer.TranslateMatrix({ 0,0, -100 * Environment::zoom });
|
||||||
|
|
||||||
|
float t = 0.3;
|
||||||
|
renderer.RotateMatrix(QuatFromRotateAroundX(t * M_PI / 2.0));
|
||||||
|
|
||||||
|
// Draw cone
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gameObjects.coneTexturePtr->getTexID());
|
||||||
|
renderer.DrawVertexRenderStruct(gameObjects.coneMeshMutable);
|
||||||
|
|
||||||
|
renderer.TranslateMatrix(Environment::cameraShift);
|
||||||
|
|
||||||
|
// Draw active objects
|
||||||
|
for (const auto& ao : gameObjects.activeObjects) {
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.TranslateMatrix(ao.objectPos);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, ao.activeObjectTexturePtr->getTexID());
|
||||||
|
renderer.DrawVertexRenderStruct(ao.activeObjectMeshMutable);
|
||||||
|
renderer.PopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw room
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gameObjects.roomTexturePtr->getTexID());
|
||||||
|
renderer.DrawVertexRenderStruct(gameObjects.textMeshMutable);
|
||||||
|
|
||||||
|
Matrix4f latestProjectionModelView = renderer.GetProjectionModelViewMatrix();
|
||||||
|
|
||||||
|
// Проверяем пересечение с мышью после расчета всех матриц
|
||||||
|
const_cast<GameObjectManager&>(gameObjects).checkMouseIntersection(
|
||||||
|
lastMouseX, lastMouseY, latestProjectionModelView);
|
||||||
|
|
||||||
|
renderer.PopMatrix();
|
||||||
|
renderer.PopProjectionMatrix();
|
||||||
|
|
||||||
|
// Store matrix for UI rendering
|
||||||
|
currentProjectionModelView = latestProjectionModelView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderSystem::drawUI(const GameObjectManager& gameObjects) {
|
||||||
|
renderer.PushProjectionMatrix(static_cast<float>(Environment::width),
|
||||||
|
static_cast<float>(Environment::height));
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.LoadIdentity();
|
||||||
|
|
||||||
|
// Draw highlighted objects UI
|
||||||
|
for (const auto& ao : gameObjects.activeObjects) {
|
||||||
|
if (ao.highlighted) {
|
||||||
|
int screenX, screenY;
|
||||||
|
worldToScreenCoordinates(ao.objectPos, currentProjectionModelView,
|
||||||
|
Environment::width, Environment::height, screenX, screenY);
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.TranslateMatrix(Vector3f{screenX + 0.f, screenY + 0.f, 0.0f});
|
||||||
|
glBindTexture(GL_TEXTURE_2D, ao.activeObjectScreenTexturePtr->getTexID());
|
||||||
|
renderer.DrawVertexRenderStruct(ao.activeObjectScreenMeshMutable);
|
||||||
|
renderer.PopMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw inventory
|
||||||
|
const auto& inventory = ZL::ReturnInventory();
|
||||||
|
for (size_t i = 0; i < inventory.size(); ++i) {
|
||||||
|
renderer.PushMatrix();
|
||||||
|
float xPos = Environment::width - gameObjects.INVENTORY_MARGIN - gameObjects.INVENTORY_ICON_SIZE;
|
||||||
|
float yPos = gameObjects.INVENTORY_MARGIN + i * (gameObjects.INVENTORY_ICON_SIZE + gameObjects.INVENTORY_MARGIN);
|
||||||
|
renderer.TranslateMatrix(Vector3f{xPos, yPos, 0.0f});
|
||||||
|
glBindTexture(GL_TEXTURE_2D, inventory[i].texture->getTexID());
|
||||||
|
renderer.DrawVertexRenderStruct(gameObjects.inventoryIconMeshMutable);
|
||||||
|
renderer.PopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.PopMatrix();
|
||||||
|
renderer.PopProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderSystem::worldToScreenCoordinates(Vector3f objectPos,
|
||||||
|
Matrix4f projectionModelView,
|
||||||
|
int screenWidth, int screenHeight,
|
||||||
|
int& screenX, int& screenY) {
|
||||||
|
|
||||||
|
Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f};
|
||||||
|
Vector4f clipCoords = MultMatrixVector(projectionModelView, inx);
|
||||||
|
|
||||||
|
float ndcX = clipCoords.v[0] / clipCoords.v[3];
|
||||||
|
float ndcY = clipCoords.v[1] / clipCoords.v[3];
|
||||||
|
|
||||||
|
screenX = (int)((ndcX + 1.0f) * 0.5f * screenWidth);
|
||||||
|
screenY = (int)((1.0f + ndcY) * 0.5f * screenHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
31
RenderSystem.h
Normal file
31
RenderSystem.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "GameObjectManager.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ZL {
|
||||||
|
|
||||||
|
class RenderSystem {
|
||||||
|
public:
|
||||||
|
RenderSystem() = default;
|
||||||
|
void initialize();
|
||||||
|
void drawScene(const GameObjectManager& gameObjects);
|
||||||
|
Renderer& getRenderer() { return renderer; }
|
||||||
|
|
||||||
|
void worldToScreenCoordinates(Vector3f objectPos,
|
||||||
|
Matrix4f projectionModelView,
|
||||||
|
int screenWidth, int screenHeight,
|
||||||
|
int& screenX, int& screenY);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void drawWorld(const GameObjectManager& gameObjects);
|
||||||
|
void drawUI(const GameObjectManager& gameObjects);
|
||||||
|
|
||||||
|
Renderer renderer;
|
||||||
|
ShaderManager shaderManager;
|
||||||
|
Matrix4f currentProjectionModelView; // Добавлено для хранения матрицы между drawWorld и drawUI
|
||||||
|
int lastMouseX = 0;
|
||||||
|
int lastMouseY = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ZL
|
||||||
@ -116,13 +116,13 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>C:\Work\SDL2-2.28.3\include;C:\Work\Projects\lpng1645\build\install\include</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>C:\Work\SDL2-2.28.3\include;C:\Work\Projects\lpng1645\build\install\include;C:\Work\OpenAL 1.1 SDK\include;C:\Work\Projects\libogg\include;C:\Work\Projects\vorbis\include</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>libpng16_staticd.lib;SDL2.lib;SDL2main.lib;opengl32.lib;glu32.lib;shell32.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>libogg_static.lib;audioplayer.lib;vorbisfile.lib;vorbis.lib;OpenAL32.lib;libpng16_staticd.lib;SDL2.lib;SDL2main.lib;opengl32.lib;glu32.lib;shell32.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib</AdditionalDependencies>
|
||||||
<AdditionalLibraryDirectories>C:\Work\SDL2-2.28.3\lib\x64;C:\Work\Projects\lpng1645\build\install\lib</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>C:\Work\Projects\ZeptoLabTest1\cmakeaudioplayer\build\Debug;C:\Work\SDL2-2.28.3\lib\x64;C:\Work\Projects\lpng1645\build\install\lib;C:\Work\Projects\vorbis\build\lib\Debug;C:\Work\OpenAL 1.1 SDK\libs\Win64;C:\Work\Projects\libogg\win32\VS2010\x64\Debug</AdditionalLibraryDirectories>
|
||||||
<EntryPointSymbol>
|
<EntryPointSymbol>
|
||||||
</EntryPointSymbol>
|
</EntryPointSymbol>
|
||||||
</Link>
|
</Link>
|
||||||
@ -146,7 +146,11 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="BoneAnimatedModel.cpp" />
|
<ClCompile Include="BoneAnimatedModel.cpp" />
|
||||||
|
<ClCompile Include="Environment.cpp" />
|
||||||
<ClCompile Include="Game.cpp" />
|
<ClCompile Include="Game.cpp" />
|
||||||
|
<ClCompile Include="GameObjectManager.cpp" />
|
||||||
|
<ClCompile Include="GameWorld.cpp" />
|
||||||
|
<ClCompile Include="InputManager.cpp" />
|
||||||
<ClCompile Include="Inventory.cpp" />
|
<ClCompile Include="Inventory.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="Math.cpp" />
|
<ClCompile Include="Math.cpp" />
|
||||||
@ -155,15 +159,21 @@
|
|||||||
<ClCompile Include="OpenGlExtensions.cpp" />
|
<ClCompile Include="OpenGlExtensions.cpp" />
|
||||||
<ClCompile Include="Physics.cpp" />
|
<ClCompile Include="Physics.cpp" />
|
||||||
<ClCompile Include="Renderer.cpp" />
|
<ClCompile Include="Renderer.cpp" />
|
||||||
|
<ClCompile Include="RenderSystem.cpp" />
|
||||||
<ClCompile Include="ShaderManager.cpp" />
|
<ClCompile Include="ShaderManager.cpp" />
|
||||||
<ClCompile Include="TextModel.cpp" />
|
<ClCompile Include="TextModel.cpp" />
|
||||||
<ClCompile Include="TextureManager.cpp" />
|
<ClCompile Include="TextureManager.cpp" />
|
||||||
<ClCompile Include="Utils.cpp" />
|
<ClCompile Include="Utils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="ActiveObject.h" />
|
||||||
<ClInclude Include="AnimatedModel.h" />
|
<ClInclude Include="AnimatedModel.h" />
|
||||||
<ClInclude Include="BoneAnimatedModel.h" />
|
<ClInclude Include="BoneAnimatedModel.h" />
|
||||||
|
<ClInclude Include="Environment.h" />
|
||||||
<ClInclude Include="Game.h" />
|
<ClInclude Include="Game.h" />
|
||||||
|
<ClInclude Include="GameObjectManager.h" />
|
||||||
|
<ClInclude Include="GameWorld.h" />
|
||||||
|
<ClInclude Include="InputManager.h" />
|
||||||
<ClInclude Include="Inventory.h" />
|
<ClInclude Include="Inventory.h" />
|
||||||
<ClInclude Include="Math.h" />
|
<ClInclude Include="Math.h" />
|
||||||
<ClInclude Include="md3test.h" />
|
<ClInclude Include="md3test.h" />
|
||||||
@ -171,6 +181,7 @@
|
|||||||
<ClInclude Include="OpenGlExtensions.h" />
|
<ClInclude Include="OpenGlExtensions.h" />
|
||||||
<ClInclude Include="Physics.h" />
|
<ClInclude Include="Physics.h" />
|
||||||
<ClInclude Include="Renderer.h" />
|
<ClInclude Include="Renderer.h" />
|
||||||
|
<ClInclude Include="RenderSystem.h" />
|
||||||
<ClInclude Include="ShaderManager.h" />
|
<ClInclude Include="ShaderManager.h" />
|
||||||
<ClInclude Include="TextModel.h" />
|
<ClInclude Include="TextModel.h" />
|
||||||
<ClInclude Include="TextureManager.h" />
|
<ClInclude Include="TextureManager.h" />
|
||||||
|
|||||||
@ -57,6 +57,21 @@
|
|||||||
<ClCompile Include="Inventory.cpp">
|
<ClCompile Include="Inventory.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="GameWorld.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Environment.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="GameObjectManager.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="InputManager.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="RenderSystem.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="TextureManager.h">
|
<ClInclude Include="TextureManager.h">
|
||||||
@ -101,5 +116,23 @@
|
|||||||
<ClInclude Include="Inventory.h">
|
<ClInclude Include="Inventory.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="ActiveObject.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Environment.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="GameWorld.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="InputManager.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="GameObjectManager.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="RenderSystem.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -33,3 +33,4 @@ target_link_libraries(audioplayer
|
|||||||
# Test executable
|
# Test executable
|
||||||
add_executable(test_audio examples/test_audio.cpp)
|
add_executable(test_audio examples/test_audio.cpp)
|
||||||
target_link_libraries(test_audio PRIVATE audioplayer stdc++fs)
|
target_link_libraries(test_audio PRIVATE audioplayer stdc++fs)
|
||||||
|
git add ../../sounds
|
||||||
|
|||||||
@ -12,18 +12,26 @@ public:
|
|||||||
AudioPlayer();
|
AudioPlayer();
|
||||||
~AudioPlayer();
|
~AudioPlayer();
|
||||||
|
|
||||||
bool playFromSoundsDir(const std::string& filename);
|
// Для музыки с зацикливанием (если filename пустой - продолжает играть текущую)
|
||||||
|
bool playMusic(const std::string& filename = "");
|
||||||
|
|
||||||
|
// Для одноразовых звуковых эффектов
|
||||||
|
bool playSound(const std::string& filename);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
bool isPlaying() const;
|
bool isPlaying() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ALCdevice* device;
|
ALCdevice* device;
|
||||||
ALCcontext* context;
|
ALCcontext* context;
|
||||||
ALuint source;
|
ALuint musicSource; // Источник для музыки
|
||||||
ALuint buffer;
|
ALuint soundSource; // Источник для звуков
|
||||||
|
ALuint musicBuffer; // Буфер для музыки
|
||||||
|
ALuint soundBuffer; // Буфер для звуков
|
||||||
bool playing;
|
bool playing;
|
||||||
|
std::string currentMusic; // Хранит имя текущего музыкального файла
|
||||||
|
|
||||||
std::vector<char> loadOgg(const std::string& filename);
|
std::vector<char> loadOgg(const std::string& filename, ALuint buffer);
|
||||||
std::string findFileInSounds(const std::string& filename);
|
std::string findFileInSounds(const std::string& filename);
|
||||||
bool isOggFile(const std::string& filename) const;
|
bool isOggFile(const std::string& filename) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,7 +6,8 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
AudioPlayer::AudioPlayer() : device(nullptr), context(nullptr), source(0), buffer(0), playing(false) {
|
AudioPlayer::AudioPlayer() : device(nullptr), context(nullptr),
|
||||||
|
musicSource(0), soundSource(0), musicBuffer(0), soundBuffer(0), playing(false) {
|
||||||
device = alcOpenDevice(nullptr);
|
device = alcOpenDevice(nullptr);
|
||||||
if (!device) {
|
if (!device) {
|
||||||
throw std::runtime_error("Failed to open audio device");
|
throw std::runtime_error("Failed to open audio device");
|
||||||
@ -19,15 +20,21 @@ AudioPlayer::AudioPlayer() : device(nullptr), context(nullptr), source(0), buffe
|
|||||||
}
|
}
|
||||||
|
|
||||||
alcMakeContextCurrent(context);
|
alcMakeContextCurrent(context);
|
||||||
alGenSources(1, &source);
|
alGenSources(1, &musicSource);
|
||||||
alGenBuffers(1, &buffer);
|
alGenSources(1, &soundSource);
|
||||||
|
alGenBuffers(1, &musicBuffer);
|
||||||
|
alGenBuffers(1, &soundBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioPlayer::~AudioPlayer() {
|
AudioPlayer::~AudioPlayer() {
|
||||||
if (source)
|
if (musicSource)
|
||||||
alDeleteSources(1, &source);
|
alDeleteSources(1, &musicSource);
|
||||||
if (buffer)
|
if (soundSource)
|
||||||
alDeleteBuffers(1, &buffer);
|
alDeleteSources(1, &soundSource);
|
||||||
|
if (musicBuffer)
|
||||||
|
alDeleteBuffers(1, &musicBuffer);
|
||||||
|
if (soundBuffer)
|
||||||
|
alDeleteBuffers(1, &soundBuffer);
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
alcMakeContextCurrent(nullptr);
|
alcMakeContextCurrent(nullptr);
|
||||||
@ -44,28 +51,35 @@ bool AudioPlayer::isOggFile(const std::string& filename) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string AudioPlayer::findFileInSounds(const std::string& filename) {
|
std::string AudioPlayer::findFileInSounds(const std::string& filename) {
|
||||||
// Check relative to executable location first (../../sounds)
|
// Primary search path - "sounds" directory next to executable
|
||||||
std::filesystem::path soundsDir = std::filesystem::current_path() / ".." / ".." / "sounds";
|
std::filesystem::path soundsDir = std::filesystem::current_path() / "sounds";
|
||||||
|
|
||||||
// Fallback to ../sounds if not found
|
// Alternative search paths
|
||||||
std::filesystem::path altSoundsDir = std::filesystem::current_path() / ".." / "sounds";
|
std::vector<std::filesystem::path> altPaths = {
|
||||||
|
std::filesystem::current_path() / ".." / "sounds", // One level up
|
||||||
|
std::filesystem::current_path() / ".." / ".." / "sounds", // Two levels up
|
||||||
|
"/home/albert/gay-jam/ZeptoLabTest1/sounds" // Absolute path
|
||||||
|
};
|
||||||
|
|
||||||
std::cout << "🔍 Searching for \"" << filename << "\" in:\n";
|
std::cout << "🔍 Searching for \"" << filename << "\" in:\n";
|
||||||
std::cout << " " << soundsDir << "\n";
|
std::cout << " " << soundsDir << "\n";
|
||||||
std::cout << " " << altSoundsDir << "\n";
|
|
||||||
|
|
||||||
if (std::filesystem::exists(soundsDir / filename)) {
|
if (std::filesystem::exists(soundsDir / filename)) {
|
||||||
return (soundsDir / filename).string();
|
return (soundsDir / filename).string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::filesystem::exists(altSoundsDir / filename)) {
|
// Try alternative paths
|
||||||
return (altSoundsDir / filename).string();
|
for (const auto& path : altPaths) {
|
||||||
|
std::cout << " " << path << "\n";
|
||||||
|
if (std::filesystem::exists(path / filename)) {
|
||||||
|
return (path / filename).string();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error("❌ File not found: " + filename);
|
throw std::runtime_error("❌ File not found: " + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> AudioPlayer::loadOgg(const std::string& filename) {
|
std::vector<char> AudioPlayer::loadOgg(const std::string& filename, ALuint buffer) {
|
||||||
FILE* file = fopen(filename.c_str(), "rb");
|
FILE* file = fopen(filename.c_str(), "rb");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
throw std::runtime_error("Cannot open file: " + filename);
|
throw std::runtime_error("Cannot open file: " + filename);
|
||||||
@ -101,45 +115,79 @@ std::vector<char> AudioPlayer::loadOgg(const std::string& filename) {
|
|||||||
return audioData;
|
return audioData;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioPlayer::playFromSoundsDir(const std::string& filename) {
|
bool AudioPlayer::playMusic(const std::string& filename) {
|
||||||
try {
|
try {
|
||||||
|
// Если filename пустой, просто проверяем играет ли музыка
|
||||||
|
if (filename.empty()) {
|
||||||
|
if (!isPlaying()) {
|
||||||
|
alSourcei(musicSource, AL_LOOPING, AL_TRUE); // Включаем зацикливание
|
||||||
|
alSourcePlay(musicSource);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если filename не пустой, загружаем новую музыку
|
||||||
if (!isOggFile(filename)) {
|
if (!isOggFile(filename)) {
|
||||||
std::cerr << "❌ Error: File must be an .ogg file\n";
|
std::cerr << "❌ Error: Music file must be an .ogg file\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fullPath = findFileInSounds(filename);
|
std::string fullPath = findFileInSounds(filename);
|
||||||
std::cout << "✅ Found file: " << fullPath << "\n";
|
std::cout << "✅ Found music file: " << fullPath << "\n";
|
||||||
|
|
||||||
auto audioData = loadOgg(fullPath);
|
// Останавливаем текущую музыку
|
||||||
alSourcei(source, AL_BUFFER, buffer);
|
alSourceStop(musicSource);
|
||||||
|
|
||||||
alGetError(); // Clear any previous errors
|
// Загружаем и настраиваем новую музыку
|
||||||
|
loadOgg(fullPath, musicBuffer);
|
||||||
|
alSourcei(musicSource, AL_BUFFER, musicBuffer);
|
||||||
|
alSourcei(musicSource, AL_LOOPING, AL_TRUE); // Включаем зацикливание
|
||||||
|
|
||||||
std::cout << "▶️ Starting playback...\n";
|
std::cout << "▶️ Starting music playback...\n";
|
||||||
alSourcePlay(source);
|
alSourcePlay(musicSource);
|
||||||
|
|
||||||
ALenum error = alGetError();
|
|
||||||
if (error != AL_NO_ERROR) {
|
|
||||||
std::cerr << "❌ OpenAL error: " << error << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
currentMusic = filename;
|
||||||
playing = true;
|
playing = true;
|
||||||
return true;
|
return true;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << "❌ Error: " << e.what() << std::endl;
|
std::cerr << "❌ Error playing music: " << e.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioPlayer::playSound(const std::string& filename) {
|
||||||
|
try {
|
||||||
|
if (!isOggFile(filename)) {
|
||||||
|
std::cerr << "❌ Error: Sound file must be an .ogg file\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fullPath = findFileInSounds(filename);
|
||||||
|
std::cout << "✅ Found sound file: " << fullPath << "\n";
|
||||||
|
|
||||||
|
// Загружаем и настраиваем звук
|
||||||
|
loadOgg(fullPath, soundBuffer);
|
||||||
|
alSourcei(soundSource, AL_BUFFER, soundBuffer);
|
||||||
|
alSourcei(soundSource, AL_LOOPING, AL_FALSE); // Выключаем зацикливание
|
||||||
|
|
||||||
|
std::cout << "▶️ Playing sound effect...\n";
|
||||||
|
alSourcePlay(soundSource);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "❌ Error playing sound: " << e.what() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayer::stop() {
|
void AudioPlayer::stop() {
|
||||||
alSourceStop(source);
|
alSourceStop(musicSource);
|
||||||
|
alSourceStop(soundSource);
|
||||||
playing = false;
|
playing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioPlayer::isPlaying() const {
|
bool AudioPlayer::isPlaying() const {
|
||||||
ALint state;
|
ALint state;
|
||||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
alGetSourcei(musicSource, AL_SOURCE_STATE, &state);
|
||||||
return state == AL_PLAYING;
|
return state == AL_PLAYING;
|
||||||
}
|
}
|
||||||
|
|||||||
583
main.cpp
583
main.cpp
@ -1,579 +1,24 @@
|
|||||||
#include "TextureManager.h"
|
|
||||||
#include "ShaderManager.h"
|
|
||||||
#include "Renderer.h"
|
|
||||||
#include "ObjLoader.h"
|
|
||||||
|
|
||||||
#include "Physics.h"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <ctime>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "AnimatedModel.h"
|
#include "Environment.h"
|
||||||
#include "BoneAnimatedModel.h"
|
|
||||||
#include "TextModel.h"
|
|
||||||
|
|
||||||
#include "Inventory.h"
|
int main(int argc, char* argv[]) {
|
||||||
#include <memory>
|
constexpr int CONST_WIDTH = 1280;
|
||||||
|
constexpr int CONST_HEIGHT = 720;
|
||||||
|
|
||||||
namespace ZL
|
ZL::Environment::width = CONST_WIDTH;
|
||||||
{
|
ZL::Environment::height = CONST_HEIGHT;
|
||||||
void worldToScreenCoordinates(Vector3f objectPos,
|
|
||||||
Matrix4f projectionModelView,
|
|
||||||
int screenWidth, int screenHeight,
|
|
||||||
int& screenX, int& screenY) {
|
|
||||||
|
|
||||||
|
ZL::Game game;
|
||||||
Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f};
|
game.setup();
|
||||||
|
|
||||||
Vector4f clipCoords = MultMatrixVector(projectionModelView, inx);
|
|
||||||
|
|
||||||
// Ïåðñïåêòèâíîå äåëåíèå
|
|
||||||
float ndcX = clipCoords.v[0] / clipCoords.v[3];
|
|
||||||
float ndcY = clipCoords.v[1] / clipCoords.v[3];
|
|
||||||
|
|
||||||
// Ïðåîáðàçóåì NDC â ýêðàííûå êîîðäèíàòû
|
|
||||||
screenX = (int)((ndcX + 1.0f) * 0.5f * screenWidth);
|
|
||||||
//screenY = (int)((1.0f - ndcY) * 0.5f * screenHeight);
|
|
||||||
screenY = (int)((1.0f + ndcY) * 0.5f * screenHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Env
|
|
||||||
{
|
|
||||||
int windowHeaderHeight = 0;
|
|
||||||
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
|
|
||||||
float zoom = 10.0;
|
|
||||||
|
|
||||||
bool leftPressed = false;
|
|
||||||
bool rightPressed = false;
|
|
||||||
bool upPressed = false;
|
|
||||||
bool downPressed = false;
|
|
||||||
|
|
||||||
Vector3f cameraShift = {0,0,0};
|
|
||||||
Vector3f characterPos = { 0,0,0 };
|
|
||||||
|
|
||||||
/*
|
|
||||||
Vector2f birdStartPos;
|
|
||||||
|
|
||||||
float backgroundSectionWidth;
|
|
||||||
|
|
||||||
int getActualClientHeight()
|
|
||||||
{
|
|
||||||
return height - windowHeaderHeight;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ActiveObject
|
|
||||||
{
|
|
||||||
std::shared_ptr<Texture> activeObjectTexturePtr;
|
|
||||||
VertexDataStruct activeObjectMesh;
|
|
||||||
VertexRenderStruct activeObjectMeshMutable;
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> activeObjectScreenTexturePtr;
|
|
||||||
VertexDataStruct activeObjectScreenMesh;
|
|
||||||
VertexRenderStruct activeObjectScreenMeshMutable;
|
|
||||||
|
|
||||||
|
|
||||||
Vector3f objectPos;
|
|
||||||
bool highlighted = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace GameObjects
|
|
||||||
{
|
|
||||||
std::shared_ptr<Texture> testObjTexturePtr;
|
|
||||||
std::shared_ptr<Texture> roomTexturePtr;
|
|
||||||
std::shared_ptr<Texture> coneTexturePtr;
|
|
||||||
//std::shared_ptr<Texture> activeObjectTexturePtr;
|
|
||||||
|
|
||||||
VertexDataStruct colorCubeMesh;
|
|
||||||
VertexRenderStruct colorCubeMeshMutable;
|
|
||||||
|
|
||||||
VertexDataStruct testObjMesh;
|
|
||||||
VertexRenderStruct testObjMeshMutable;
|
|
||||||
|
|
||||||
BoneSystem bx;
|
|
||||||
VertexRenderStruct bxMutable;
|
|
||||||
|
|
||||||
VertexDataStruct textMesh;
|
|
||||||
VertexRenderStruct textMeshMutable;
|
|
||||||
|
|
||||||
VertexDataStruct coneMesh;
|
|
||||||
VertexRenderStruct coneMeshMutable;
|
|
||||||
|
|
||||||
std::vector<ActiveObject> activeObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SDL_Window* window = NULL;
|
|
||||||
static SDL_GLContext gl_context;
|
|
||||||
|
|
||||||
Renderer renderer;
|
|
||||||
|
|
||||||
//GameState gs;
|
|
||||||
|
|
||||||
|
|
||||||
const size_t CONST_TIMER_INTERVAL = 10;
|
|
||||||
|
|
||||||
const size_t CONST_MAX_TIME_INTERVAL = 1000;
|
|
||||||
|
|
||||||
bool ExitGameLoop = false;
|
|
||||||
|
|
||||||
//To calculate when to call Update
|
|
||||||
size_t NewTickCount;
|
|
||||||
size_t LastTickCount;
|
|
||||||
|
|
||||||
|
|
||||||
void DrawScene()
|
|
||||||
{
|
|
||||||
static const std::string defaultShaderName = "default";
|
|
||||||
static const std::string colorShaderName = "defaultColor";
|
|
||||||
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
static const std::string vColorName = "vColor";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
|
|
||||||
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
glViewport(0, 0, Env::width, Env::height);
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(colorShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, static_cast<float>(Env::width) / static_cast<float>(Env::height), 50, 10000);
|
|
||||||
renderer.PushMatrix();
|
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
|
|
||||||
renderer.TranslateMatrix({ 0,0, -100 * Env::zoom });
|
|
||||||
|
|
||||||
float t = 0.3;
|
|
||||||
|
|
||||||
renderer.RotateMatrix(QuatFromRotateAroundX(t * M_PI / 2.0));
|
|
||||||
|
|
||||||
GameObjects::bxMutable.AssignFrom(GameObjects::bx.mesh);
|
|
||||||
GameObjects::bxMutable.RefreshVBO();
|
|
||||||
renderer.DrawVertexRenderStruct(GameObjects::bxMutable);
|
|
||||||
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, static_cast<float>(Env::width) / static_cast<float>(Env::height), 50, 10000);
|
|
||||||
renderer.PushMatrix();
|
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
|
|
||||||
renderer.TranslateMatrix({ 0,0, -100* Env::zoom });
|
|
||||||
|
|
||||||
float t = 0.3;
|
|
||||||
|
|
||||||
renderer.RotateMatrix(QuatFromRotateAroundX(t * M_PI / 2.0));
|
|
||||||
|
|
||||||
//GameObjects::textMeshMutable.AssignFrom(GameObjects::textMesh);
|
|
||||||
//GameObjects::textMeshMutable.RefreshVBO();
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, GameObjects::coneTexturePtr->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(GameObjects::coneMeshMutable);
|
|
||||||
|
|
||||||
renderer.TranslateMatrix(Env::cameraShift);
|
|
||||||
|
|
||||||
|
|
||||||
//ActiveObject ao1;
|
|
||||||
|
|
||||||
for (auto& ao : GameObjects::activeObjects)
|
|
||||||
{
|
|
||||||
renderer.PushMatrix();
|
|
||||||
renderer.TranslateMatrix(ao.objectPos);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, ao.activeObjectTexturePtr->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(ao.activeObjectMeshMutable);
|
|
||||||
renderer.PopMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, GameObjects::roomTexturePtr->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(GameObjects::textMeshMutable);
|
|
||||||
|
|
||||||
auto latestProjectionModelView = renderer.GetProjectionModelViewMatrix();
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
renderer.PushProjectionMatrix(static_cast<float>(Env::width), static_cast<float>(Env::height));
|
|
||||||
renderer.PushMatrix();
|
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
|
|
||||||
for (auto& ao : GameObjects::activeObjects)
|
|
||||||
{
|
|
||||||
if (ao.highlighted)
|
|
||||||
{
|
|
||||||
int screenX, screenY;
|
|
||||||
worldToScreenCoordinates(ao.objectPos, latestProjectionModelView, Env::width, Env::height, screenX, screenY);
|
|
||||||
renderer.PushMatrix();
|
|
||||||
renderer.TranslateMatrix(Vector3f{screenX + 0.f, screenY + 0.f, 0.0f});
|
|
||||||
glBindTexture(GL_TEXTURE_2D, ao.activeObjectScreenTexturePtr->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(ao.activeObjectScreenMeshMutable);
|
|
||||||
renderer.PopMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UpdateScene(size_t ms)
|
|
||||||
{
|
|
||||||
const float SPEED = 0.1f;
|
|
||||||
if (Env::leftPressed)
|
|
||||||
{
|
|
||||||
Env::cameraShift.v[0] += SPEED * ms;
|
|
||||||
}
|
|
||||||
if (Env::rightPressed)
|
|
||||||
{
|
|
||||||
Env::cameraShift.v[0] -= SPEED * ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Env::upPressed)
|
|
||||||
{
|
|
||||||
Env::cameraShift.v[2] += SPEED * ms;
|
|
||||||
}
|
|
||||||
if (Env::downPressed)
|
|
||||||
{
|
|
||||||
Env::cameraShift.v[2] -= SPEED * ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
Env::characterPos.v[0] = -Env::cameraShift.v[0];
|
|
||||||
Env::characterPos.v[1] = -Env::cameraShift.v[1];
|
|
||||||
Env::characterPos.v[2] = -Env::cameraShift.v[2];
|
|
||||||
|
|
||||||
for (auto& ao : GameObjects::activeObjects)
|
|
||||||
{
|
|
||||||
if (sqrtf(
|
|
||||||
(Env::characterPos.v[0] - ao.objectPos.v[0]) * (Env::characterPos.v[0] - ao.objectPos.v[0])
|
|
||||||
+
|
|
||||||
(Env::characterPos.v[1] - ao.objectPos.v[1]) * (Env::characterPos.v[1] - ao.objectPos.v[1])
|
|
||||||
+
|
|
||||||
(Env::characterPos.v[2] - ao.objectPos.v[2]) * (Env::characterPos.v[2] - ao.objectPos.v[2])
|
|
||||||
) < 50.f)
|
|
||||||
{
|
|
||||||
ao.highlighted = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ao.highlighted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessTickCount()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (LastTickCount == 0)
|
|
||||||
{
|
|
||||||
LastTickCount = SDL_GetTicks64();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NewTickCount = SDL_GetTicks64();
|
|
||||||
if (NewTickCount - LastTickCount > CONST_TIMER_INTERVAL)
|
|
||||||
{
|
|
||||||
if (NewTickCount - LastTickCount > CONST_MAX_TIME_INTERVAL)
|
|
||||||
{
|
|
||||||
UpdateScene(CONST_MAX_TIME_INTERVAL); //Limit game update speed to FPS
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateScene(NewTickCount - LastTickCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
LastTickCount = NewTickCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
static const int BIRD_WIDTH = 512;
|
|
||||||
static const int BIRD_HEIGHT = 512;
|
|
||||||
|
|
||||||
static const int BACKGROUND_WIDTH = 900;
|
|
||||||
static const int BACKGROUND_HEIGHT = 504;
|
|
||||||
|
|
||||||
static const int PIPE_WIDTH = 244;
|
|
||||||
static const int PIPE_HEIGHT = 1500;
|
|
||||||
|
|
||||||
static const int GAMEOVER_WIDTH = 1400;
|
|
||||||
static const int GAMEOVER_HEIGHT = 720;
|
|
||||||
|
|
||||||
ZL::BindOpenGlFunctions();
|
|
||||||
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
//Load shaders:
|
|
||||||
std::cout << "Hello test 1" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("default", "./default.vertex", "./default.fragment");
|
|
||||||
|
|
||||||
std::cout << "Hello test 2" << std::endl;
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./defaultColor.vertex", "./defaultColor.fragment");
|
|
||||||
std::cout << "Hello test 2x" << std::endl;
|
|
||||||
|
|
||||||
//GameObjects::bx.LoadFromFile("mesh_armature_and_animation_data.txt");
|
|
||||||
GameObjects::bx.LoadFromFile("via004.txt");
|
|
||||||
|
|
||||||
std::cout << "Hello test 3" << std::endl;
|
|
||||||
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
GameObjects::roomTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp"));
|
|
||||||
GameObjects::coneTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./conus.bmp"));
|
|
||||||
|
|
||||||
GameObjects::colorCubeMesh = CreateCube3D(5.0);
|
|
||||||
GameObjects::colorCubeMeshMutable.data = CreateCube3D(5.0);
|
|
||||||
GameObjects::colorCubeMeshMutable.RefreshVBO();
|
|
||||||
|
|
||||||
GameObjects::testObjMesh = LoadFromObjFile("./chair_01.obj");
|
|
||||||
GameObjects::testObjMesh.Scale(10);
|
|
||||||
GameObjects::testObjMesh.SwapZandY();
|
|
||||||
GameObjects::testObjMeshMutable.data = GameObjects::testObjMesh;
|
|
||||||
GameObjects::testObjMeshMutable.RefreshVBO();
|
|
||||||
|
|
||||||
/*
|
|
||||||
GameObjects::textMesh = LoadFromTextFile("./mesh001.txt");
|
|
||||||
|
|
||||||
GameObjects::coneMesh = LoadFromTextFile("./cone001.txt");
|
|
||||||
|
|
||||||
GameObjects::coneMesh.Scale(200);
|
|
||||||
|
|
||||||
GameObjects::textMeshMutable.AssignFrom(GameObjects::textMesh);
|
|
||||||
GameObjects::textMeshMutable.RefreshVBO();
|
|
||||||
GameObjects::coneMeshMutable.AssignFrom(GameObjects::coneMesh);
|
|
||||||
GameObjects::coneMeshMutable.RefreshVBO();
|
|
||||||
*/
|
|
||||||
|
|
||||||
ActiveObject ao1;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ao1.activeObjectMesh = LoadFromTextFile("./book001.txt");
|
|
||||||
ao1.activeObjectMesh.Scale(4);
|
|
||||||
|
|
||||||
ao1.activeObjectMeshMutable.AssignFrom(ao1.activeObjectMesh);
|
|
||||||
ao1.activeObjectMeshMutable.RefreshVBO();
|
|
||||||
|
|
||||||
ao1.objectPos = Vector3f{50, 0, -300};
|
|
||||||
ao1.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./book03.bmp"));
|
|
||||||
|
|
||||||
ao1.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
|
|
||||||
|
|
||||||
ao1.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
|
|
||||||
ao1.activeObjectScreenMeshMutable.AssignFrom(ao1.activeObjectScreenMesh);
|
|
||||||
ao1.activeObjectScreenMeshMutable.RefreshVBO();
|
|
||||||
|
|
||||||
GameObjects::activeObjects.push_back(ao1);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::cout << "Hello test 4x" << std::endl;
|
|
||||||
|
|
||||||
renderer.InitOpenGL();
|
|
||||||
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
|
|
||||||
std::cout << "Hello test 5x" << std::endl;
|
|
||||||
|
|
||||||
// ТЕСТИРУЕМ ВЗÐ<E28094>ИМОДЕЙСТВИЕ С ИÐ<CB9C>ВЕÐ<E280A2>ТÐ<C2A2>РЕМ
|
|
||||||
auto roomTexturePtr = std::make_shared<ZL::Texture>(ZL::CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp"));
|
|
||||||
auto coneTexturePtr = std::make_shared<ZL::Texture>(ZL::CreateTextureDataFromBmp24("./conus.bmp"));
|
|
||||||
|
|
||||||
// ДобавлÑ<C2BB>ем предметы в инвентарь
|
|
||||||
ZL::AddItemToInventory("RoomCeramics", roomTexturePtr);
|
|
||||||
ZL::AddItemToInventory("Cone", coneTexturePtr);
|
|
||||||
|
|
||||||
std::cout << "Before removal:\n";
|
|
||||||
ZL::PrintInventory();
|
|
||||||
|
|
||||||
// УдалÑ<C2BB>ем "Cone" из инвентарÑ<E282AC>
|
|
||||||
ZL::RemoveItemFromInventory("Cone");
|
|
||||||
|
|
||||||
std::cout << "\nAfter removal:\n";
|
|
||||||
ZL::PrintInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
void render() {
|
|
||||||
|
|
||||||
SDL_GL_MakeCurrent(window, gl_context);
|
|
||||||
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
DrawScene();
|
|
||||||
ProcessTickCount();
|
|
||||||
|
|
||||||
SDL_GL_SwapWindow(window);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void update() {
|
|
||||||
SDL_Event event;
|
|
||||||
while (SDL_PollEvent(&event)) {
|
|
||||||
if (event.type == SDL_QUIT) {
|
|
||||||
ExitGameLoop = true;
|
|
||||||
}
|
|
||||||
if (event.type == SDL_MOUSEBUTTONDOWN) {
|
|
||||||
static int x = 0;
|
|
||||||
|
|
||||||
GameObjects::bx.Interpolate(x);
|
|
||||||
x = x + 3;
|
|
||||||
}
|
|
||||||
if (event.type == SDL_MOUSEWHEEL) {
|
|
||||||
|
|
||||||
static const float zoomstep = 1.0f;
|
|
||||||
if (event.wheel.y > 0) {
|
|
||||||
// ��������� ����� - ����������� zoom
|
|
||||||
Env::zoom -= zoomstep;
|
|
||||||
}
|
|
||||||
else if (event.wheel.y < 0) {
|
|
||||||
// ��������� ���� - ��������� zoom
|
|
||||||
Env::zoom += zoomstep;
|
|
||||||
}
|
|
||||||
// ������������ zoom, ����� �� �� ���� �������������
|
|
||||||
if (Env::zoom < zoomstep) {
|
|
||||||
Env::zoom = zoomstep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (event.type == SDL_KEYDOWN) {
|
|
||||||
switch (event.key.keysym.sym) {
|
|
||||||
case SDLK_LEFT:
|
|
||||||
case SDLK_a:
|
|
||||||
Env::leftPressed = true;
|
|
||||||
break;
|
|
||||||
case SDLK_RIGHT:
|
|
||||||
case SDLK_d:
|
|
||||||
Env::rightPressed = true;
|
|
||||||
break;
|
|
||||||
case SDLK_UP:
|
|
||||||
case SDLK_w:
|
|
||||||
Env::upPressed = true;
|
|
||||||
break;
|
|
||||||
case SDLK_DOWN:
|
|
||||||
case SDLK_s:
|
|
||||||
Env::downPressed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == SDL_KEYUP) {
|
|
||||||
switch (event.key.keysym.sym) {
|
|
||||||
case SDLK_LEFT:
|
|
||||||
case SDLK_a:
|
|
||||||
Env::leftPressed = false;
|
|
||||||
break;
|
|
||||||
case SDLK_RIGHT:
|
|
||||||
case SDLK_d:
|
|
||||||
Env::rightPressed = false;
|
|
||||||
break;
|
|
||||||
case SDLK_UP:
|
|
||||||
case SDLK_w:
|
|
||||||
Env::upPressed = false;
|
|
||||||
break;
|
|
||||||
case SDLK_DOWN:
|
|
||||||
case SDLK_s:
|
|
||||||
Env::downPressed = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
|
|
||||||
constexpr int CONST_WIDTH = 1280;
|
|
||||||
constexpr int CONST_HEIGHT = 720;
|
|
||||||
|
|
||||||
ZL::Env::width = CONST_WIDTH;
|
|
||||||
ZL::Env::height = CONST_HEIGHT;
|
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
emscripten_set_main_loop([](){ game.update(); }, 0, 1);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
|
||||||
SDL_Renderer* renderer = NULL;
|
|
||||||
SDL_CreateWindowAndRenderer(CONST_WIDTH, CONST_HEIGHT, SDL_WINDOW_OPENGL, &ZL::window, &renderer);
|
|
||||||
#else
|
#else
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
|
while (!game.shouldExit()) {
|
||||||
SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
|
game.update();
|
||||||
return 1;
|
SDL_Delay(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Use a core profile setup.
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
|
||||||
ZL::window = SDL_CreateWindow("Jumping Bird", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CONST_WIDTH, CONST_HEIGHT, SDL_WINDOW_OPENGL);
|
|
||||||
#endif
|
|
||||||
//todo
|
|
||||||
ZL::Env::windowHeaderHeight = 0;
|
|
||||||
|
|
||||||
ZL::gl_context = SDL_GL_CreateContext(ZL::window);
|
|
||||||
|
|
||||||
ZL::CheckGlError();
|
|
||||||
|
|
||||||
ZL::setup();
|
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
// register update as callback
|
|
||||||
emscripten_set_main_loop(ZL::update, 0, 1);
|
|
||||||
#else
|
|
||||||
while (!ZL::ExitGameLoop) {
|
|
||||||
|
|
||||||
ZL::update();
|
|
||||||
SDL_Delay(2);
|
|
||||||
|
|
||||||
}
|
|
||||||
SDL_GL_DeleteContext(ZL::gl_context);
|
|
||||||
SDL_DestroyWindow(ZL::window);
|
|
||||||
SDL_Quit();
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
sounds/Звук-Идут-по-земле.ogg
Normal file
BIN
sounds/Звук-Идут-по-земле.ogg
Normal file
Binary file not shown.
11
start.sh
Executable file
11
start.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
g++ Game.cpp main.cpp Math.cpp OpenGlExtensions.cpp Physics.cpp Renderer.cpp \
|
||||||
|
ShaderManager.cpp TextureManager.cpp Utils.cpp BoneAnimatedModel.cpp \
|
||||||
|
ObjLoader.cpp cmakeaudioplayer/src/AudioPlayer.cpp TextModel.cpp \
|
||||||
|
Inventory.cpp Environment.cpp GameObjectManager.cpp RenderSystem.cpp \
|
||||||
|
-o sdl_app -O2 -std=c++17 \
|
||||||
|
-I cmakeaudioplayer/include \
|
||||||
|
$(pkg-config --cflags --libs sdl2 gl) \
|
||||||
|
$(pkg-config --cflags --libs vorbis vorbisfile ogg) \
|
||||||
|
-lopenal
|
||||||
|
|
||||||
|
./sdl_app
|
||||||
Loading…
Reference in New Issue
Block a user