#include "RenderSystem.h" #include "Environment.h" #include "Utils.h" #include "Inventory.h" #include namespace ZL { void RenderSystem::initialize() { /* renderer.shaderManager.AddShaderFromFiles("default", "./default.vertex", "./default.fragment"); renderer.shaderManager.AddShaderFromFiles("defaultHideCam", "./defaultHideCam.vertex", "./defaultHideCam.fragment"); renderer.shaderManager.AddShaderFromFiles("defaultColor", "./defaultColor.vertex", "./defaultColor.fragment"); renderer.InitOpenGL();*/ } void RenderSystem::drawScene(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.0f, 0.5f, 1.0f, 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::drawViola(GameObjectManager& gameObjects) { 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"; renderer.shaderManager.PushShader(colorShaderName); renderer.EnableVertexAttribArray(vPositionName); renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, static_cast(Environment::width) / static_cast(Environment::height), 50, 10000); renderer.PushMatrix(); renderer.LoadIdentity(); renderer.TranslateMatrix({ 0,0, -100 * Environment::zoom }); renderer.RotateMatrix(QuatFromRotateAroundX(Environment::cameraAlpha)); //renderer.RotateMatrix(QuatFromRotateAroundY(Environment::cameraPhi)); //Go a little bit up to make camera at the position of Viola renderer.TranslateMatrix({ 0, Environment::cameraDefaultVerticalShift, 0 }); //Viola stuff renderer.ScaleMatrix(10); renderer.RotateMatrix(QuatFromRotateAroundX(-M_PI / 2.0)); if (Environment::violaCurrentAnimation == 0) { gameObjects.violaIdleModelMutable.AssignFrom(gameObjects.violaIdleModel.mesh); gameObjects.violaIdleModelMutable.RefreshVBO(); renderer.DrawVertexRenderStruct(gameObjects.violaIdleModelMutable); } else { gameObjects.violaWalkModelMutable.AssignFrom(gameObjects.violaWalkModel.mesh); gameObjects.violaWalkModelMutable.RefreshVBO(); renderer.DrawVertexRenderStruct(gameObjects.violaWalkModelMutable); } renderer.PopMatrix(); renderer.PopProjectionMatrix(); renderer.DisableVertexAttribArray(vPositionName); renderer.shaderManager.PopShader(); } void RenderSystem::drawWorld(GameObjectManager& gameObjects) { static const std::string defaultShaderName = "default"; static const std::string colorShaderName = "defaultColor"; static const std::string hideCamShaderName = "defaultHideCam"; static const std::string vPositionName = "vPosition"; static const std::string vTexCoordName = "vTexCoord"; static const std::string vColorName = "vColor"; static const std::string textureUniformName = "Texture"; //static const std::string modelViewMatrixName = "modelView"; /* renderer.shaderManager.PushShader(defaultShaderName); renderer.RenderUniform1i(textureUniformName, 0); renderer.EnableVertexAttribArray(vPositionName); renderer.EnableVertexAttribArray(vTexCoordName); */ // Draw cone //glBindTexture(GL_TEXTURE_2D, gameObjects.coneTexturePtr->getTexID()); //renderer.DrawVertexRenderStruct(gameObjects.coneMeshMutable); drawViola(gameObjects); renderer.shaderManager.PushShader(hideCamShaderName); renderer.RenderUniform1i(textureUniformName, 0); Vector3f testVec1{ 0,0,0 }; Vector3f testVec2{ 0,400,-600 }; renderer.RenderUniform3fv("targetPos", &Environment::characterPos.v[0]); //renderer.RenderUniform3fv("targetPos", &testVec1.v[0]); Vector3f cameraPos = Vector3f{ 0,0, 100 * Environment::zoom }; cameraPos = MultVectorMatrix(cameraPos, QuatToMatrix(QuatFromRotateAroundX(Environment::cameraAlpha))); cameraPos = MultVectorMatrix(cameraPos, QuatToMatrix(QuatFromRotateAroundY(Environment::cameraPhi))); cameraPos = cameraPos + Environment::characterPos; renderer.RenderUniform3fv("eyePos", &cameraPos.v[0]); //renderer.RenderUniform3fv("eyePos", &testVec2.v[0]); renderer.EnableVertexAttribArray(vPositionName); renderer.EnableVertexAttribArray(vTexCoordName); renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, static_cast(Environment::width) / static_cast(Environment::height), 50, 10000); renderer.PushMatrix(); renderer.LoadIdentity(); renderer.TranslateMatrix({ 0,0, -100 * Environment::zoom }); renderer.RotateMatrix(QuatFromRotateAroundX(Environment::cameraAlpha)); renderer.RotateMatrix(QuatFromRotateAroundY(Environment::cameraPhi)); renderer.TranslateMatrix(Environment::cameraShift); //Go a little bit up to make camera at the position of Viola renderer.TranslateMatrix({ 0, Environment::cameraDefaultVerticalShift, 0 }); // 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(gameObjects).checkMouseIntersection( lastMouseX, lastMouseY, latestProjectionModelView); renderer.PopMatrix(); renderer.PopProjectionMatrix(); renderer.DisableVertexAttribArray(vPositionName); renderer.DisableVertexAttribArray(vTexCoordName); renderer.shaderManager.PopShader(); // Store matrix for UI rendering currentProjectionModelView = latestProjectionModelView; } void RenderSystem::drawUI(const GameObjectManager& gameObjects) { // Устанавливаем нужный шейдер для UI (например, "default") renderer.shaderManager.PushShader("default"); // Если шейдер ожидает атрибуты вершин, их нужно включить static const std::string vPositionName = "vPosition"; static const std::string vTexCoordName = "vTexCoord"; renderer.EnableVertexAttribArray(vPositionName); renderer.EnableVertexAttribArray(vTexCoordName); renderer.PushProjectionMatrix(static_cast(Environment::width), static_cast(Environment::height)); renderer.PushMatrix(); renderer.LoadIdentity(); for (const auto* ao : gameObjects.aoMgr.findByHighlighted(true)) { std::cout << ao->name << std::endl; std::cout << "Draw" << std::endl; if (ao->activeObjectScreenTexturePtr) { std::cout << "Found activeObjectScreenTexturePtr" << std::endl; int screenX, screenY; worldToScreenCoordinates(ao->objectPos, currentProjectionModelView, Environment::width, Environment::height, screenX, screenY); renderer.PushMatrix(); // Здесь можно использовать вычисленные screenX, screenY, // но для теста оставляем фиксированное значение renderer.TranslateMatrix(Vector3f{screenX + 0.f, screenY + 0.f, 0.0f}); glBindTexture(GL_TEXTURE_2D, ao->activeObjectScreenTexturePtr->getTexID()); renderer.DrawVertexRenderStruct(ao->activeObjectScreenMeshMutable); renderer.PopMatrix(); } } const auto& inventoryMap = ZL::ReturnInventory(); int i = 0; for (const auto& [name, item] : inventoryMap) { 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, item.texture->getTexID()); renderer.DrawVertexRenderStruct(gameObjects.inventoryIconMeshMutable); renderer.PopMatrix(); i++; } renderer.PopMatrix(); renderer.PopProjectionMatrix(); // Выключаем атрибуты, чтобы сохранить баланс renderer.DisableVertexAttribArray(vPositionName); renderer.DisableVertexAttribArray(vTexCoordName); // Снимаем шейдер, тем самым балансируя стек renderer.shaderManager.PopShader(); } 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