diff --git a/draw.cpp b/draw.cpp index d2b2916..cdf8b8f 100644 --- a/draw.cpp +++ b/draw.cpp @@ -77,24 +77,18 @@ Renderer::Renderer() Renderer::~Renderer() { LOGF((stdout, "Running Renderer destructor.\n")); - if (pgmText) - glDeleteObject(pgmText); - if (pgmMap) - glDeleteObject(pgmMap); - if (pgmButton) - glDeleteObject(pgmButton); - if (pgmColoredSprite) - glDeleteObject(pgmColoredSprite); - if (pgmCrosslinkProp) - glDeleteObject(pgmCrosslinkProp); - if (text_vbo) - glDeleteBuffers(1, &text_vbo); - if (entRectVBO) - glDeleteBuffers(1, &entRectVBO); - if (pointVBO) - glDeleteBuffers(1, &pointVBO); - if (_screenVBO) - glDeleteBuffers(1, &_screenVBO); + + safeDeleteProgram(pgmText); + safeDeleteProgram(pgmMap); + safeDeleteProgram(pgmButton); + safeDeleteProgram(pgmColoredSprite); + safeDeleteProgram(pgmCrosslinkProp); + + safeDeleteBuffer(text_vbo); + safeDeleteBuffer(entRectVBO); + safeDeleteBuffer(pointVBO); + safeDeleteBuffer(_screenVBO); + safeDeleteBuffer(_screenTexVBO); delete font1; delete font2; @@ -114,14 +108,29 @@ Renderer::~Renderer() deleteSpriteSheet(resInterface); deleteSpriteSheet(resGlass); - if (bgClose > 0) - glDeleteTextures(1, &bgClose); - if (bgMiddle > 0) - glDeleteTextures(1, &bgMiddle); - if (bgFar > 0) - glDeleteTextures(1, &bgFar); - if (bgVeryFar > 0) - glDeleteTextures(1, &bgVeryFar); + safeDeleteTexture(bgClose); + safeDeleteTexture(bgMiddle); + safeDeleteTexture(bgFar); + safeDeleteTexture(bgVeryFar); + safeDeleteTexture(bgMainMenu); +} + +void Renderer::safeDeleteBuffer(GLuint buf) +{ + if (buf > 0) + glDeleteBuffers(1, &buf); +} + +void Renderer::safeDeleteProgram(GLuint pgm) +{ + if (pgm > 0) + glDeleteObject(pgm); +} + +void Renderer::safeDeleteTexture(GLuint tex) +{ + if (tex > 0) + glDeleteTextures(1, &tex); } void Renderer::deleteSpriteSheet(SpriteSheet* sheet) @@ -156,6 +165,7 @@ void Renderer::toggleWireframe() bool Renderer::init(int x, int y) { _screenVBO = 0; + _screenTexVBO = 0; glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); @@ -225,6 +235,14 @@ bool Renderer::init(int x, int y) bgFar = loadTexture("./data/backgrounds/bgFar.png"); bgVeryFar = loadTexture("./data/backgrounds/bgVeryFar.png"); + bgMainMenu = loadTexture("./data/backgrounds/menus/main.png"); + bgCredits = loadTexture("./data/backgrounds/menus/credits.png"); + bgOptions = loadTexture("./data/backgrounds/menus/options.png"); + bgLoadMap = loadTexture("./data/backgrounds/menus/loadmap.png"); + bgPaused = loadTexture("./data/backgrounds/menus/paused.png"); + bgUpgrades = loadTexture("./data/backgrounds/menus/upgrades.png"); + bgActive = bgMainMenu; + if (resPlayer->getTexId() == 0 || resPlayerLeft->getTexId() == 0 || resGuardRight->getTexId() == 0 || @@ -436,6 +454,7 @@ void Renderer::drawState(BaseState* state) bool is_game = dynamic_cast(state); if (is_menu) { + drawMenuBackground(bgActive); for (i = 0; i < static_cast(state)->getButtonCount(); i++) { drawButton(static_cast(state)->getButtonAt(i)); @@ -631,17 +650,33 @@ void Renderer::bufferScreenVBO(float x, float y) if (_screenVBO) glDeleteBuffers(1, &_screenVBO); - float verts[] = { 0.0, 0.0, - 0.0, y, + if (_screenTexVBO) + glDeleteBuffers(1, &_screenTexVBO); + + float verts[] = { 0.0f, 0.0f, + 0.0f, y, x, 0.0f, - 0.0, y, + 0.0f, y, x, 0.0f, x, y }; + float vertsAndTexes[] = { 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, y, 0.0f, 1.0f, + x, 0.0f, 1.0f, 0.0f, + 0.0f, y, 0.0f, 1.0f, + x, 0.0f, 1.0f, 0.0f, + x, y, 1.0f, 1.0f + }; + glGenBuffers(1, &_screenVBO); + glGenBuffers(1, &_screenTexVBO); + glBindBuffer(GL_ARRAY_BUFFER, _screenVBO); glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), &verts[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, _screenTexVBO); + glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), &vertsAndTexes[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -1387,7 +1422,7 @@ void Renderer::drawTileLayer(Scene* scene, int z) glUseProgramObject(0); } -void Renderer::drawBackgrounds(Scene* scene) +void Renderer::drawSceneBackgrounds(Scene* scene) { unsigned int mapWidth = scene->getMap()->getMapWidth(); unsigned int bgCounter = 0; @@ -1457,6 +1492,33 @@ void Renderer::drawBackground(Scene* scene, GLuint tex, int x, int z, float offs glDrawArrays(GL_TRIANGLES, 0, 6); } +void Renderer::drawMenuBackground(GLuint tex) +{ + glUseProgramObject(pgmButton); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glBindBuffer(GL_ARRAY_BUFFER, _screenTexVBO); + glUniform1i(glGetUniformLocation(pgmButton, "use_grayscale"), 1); + + SpriteVertex* vert = NULL; + glEnableVertexAttribArray(glGetAttribLocation(pgmButton, "Position")); + glEnableVertexAttribArray(glGetAttribLocation(pgmButton, "TexCoord")); + glVertexAttribPointer(glGetAttribLocation(pgmButton, "Position"), 2, + GL_FLOAT, GL_FALSE, sizeof(SpriteVertex), vert->position); + glVertexAttribPointer(glGetAttribLocation(pgmButton, "TexCoord"), 2, + GL_FLOAT, GL_FALSE, sizeof(SpriteVertex), vert->texcoord); + + quadTransform = mat4f_mult(orthographic, mat4f_translate(0, 0, 0)); + glUniformMatrix4fv(glGetUniformLocation(pgmButton, "proj_mat"), + 1, GL_TRUE, &quadTransform.m[0][0]); + glDrawArrays(GL_TRIANGLES, 0, 6); + + glUniform1i(glGetUniformLocation(pgmButton, "use_grayscale"), 0); + glUseProgramObject(0); + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + void Renderer::getBoxCoordsAroundText(const char* text, float x, float y, Font* font, Rect* rect) { int longestWidth = 0; @@ -1531,7 +1593,7 @@ void Renderer::drawScene(Scene* scene) Player* player = scene->getPlayer(); Rect playerRect = player->getCollisionRect(); drawTileLayer(scene, 0); - drawBackgrounds(scene); + drawSceneBackgrounds(scene); if (!scene->inCrosslinkMode()) { @@ -1745,6 +1807,34 @@ void Renderer::drawLoadMenu(/*Scene* scene*/) drawText(winX / 2, winY / 2 + incr, (char*)"ESC: Abort", RGB_WHITE, 1.0f, font2); } +void Renderer::changeMenuBackground(eState state) +{ + switch(state) + { + case MAINMENU_SCREEN: + bgActive = bgMainMenu; + break; + case CREDITS_SCREEN: + bgActive = bgCredits; + break; + case PAUSE_SCREEN: + bgActive = bgPaused; + break; + case LOADMAP_SCREEN: + bgActive = bgLoadMap; + break; + case OPTIONS_SCREEN: + bgActive = bgOptions; + break; + case UPGRADES_SCREEN: + bgActive = bgUpgrades; + break; + default: + bgActive = 0; + break; + } +} + unsigned int Renderer::getScreenshotIndex() { return screenshotIndex; diff --git a/draw.h b/draw.h index 7fc594b..a246873 100644 --- a/draw.h +++ b/draw.h @@ -24,6 +24,7 @@ along with Clonepoint. If not, see . #include "file.h" #include "sprite.h" #include "scene.h" +#include "statemanager.h" #include "gamestate.h" #include "menustate.h" #include "font.h" @@ -77,6 +78,11 @@ class Renderer public: Renderer(); ~Renderer(); + + void safeDeleteBuffer(GLuint buf); + void safeDeleteProgram(GLuint pgm); + void safeDeleteTexture(GLuint tex); + bool init(int x, int y); void setResolution(int x, int y); bool initShaders(); @@ -102,8 +108,9 @@ class Renderer void drawSpriteBind(float x, float y, float z, float rotation, SpriteSheet* resource, unsigned int index, SpriteDrawMode mode, float red, float green, float blue); void drawFieldOfView(Scene* scene, FieldOfView* fov, GLuint program); void drawTileLayer(Scene* scene, int z); - void drawBackgrounds(Scene* scene); + void drawSceneBackgrounds(Scene* scene); void drawBackground(Scene* scene, GLuint tex, int x, int z, float offset); + void drawMenuBackground(GLuint tex); void updateLinkProgress(unsigned int dT); void deleteSpriteSheet(SpriteSheet* sheet); @@ -121,6 +128,7 @@ class Renderer void drawLine(Scene* scene, float r, float g, float b, float a, vec2f pA, vec2f pB, float z); void drawInterface(Scene* scene); void drawLoadMenu(/*Scene* scene*/); + void changeMenuBackground(eState state); //test functions. void drawEnemyFOV(Scene* scene, Enemy* enemy); @@ -140,6 +148,7 @@ class Renderer GLuint entRectVBO; //vbo for storing tile-sized quads. GLuint pointVBO; //vbo for storing quad for jump trajectory. GLuint _screenVBO; //vbo for quad with dimensions of window. + GLuint _screenTexVBO; bool wireframe; GLuint attribute_coord; @@ -153,6 +162,14 @@ class Renderer GLuint bgMiddle; GLuint bgFar; GLuint bgVeryFar; + //menus + GLuint bgMainMenu; + GLuint bgCredits; + GLuint bgOptions; + GLuint bgLoadMap; + GLuint bgPaused; + GLuint bgUpgrades; + GLuint bgActive; //programs GLuint pgmText; diff --git a/main.cpp b/main.cpp index 895e96f..72864a8 100644 --- a/main.cpp +++ b/main.cpp @@ -267,6 +267,12 @@ void loop1() renderer.takeScreenshot(); sm->resetScreenShotFlag(); } + + if (sm->stateChanged()) + { + renderer.changeMenuBackground(sm->_activeStateName); + sm->resetStateChangedFlag(); + } } } diff --git a/shaders/button.frag b/shaders/button.frag index b778cd5..bea6f64 100644 --- a/shaders/button.frag +++ b/shaders/button.frag @@ -3,6 +3,7 @@ in vec2 texpos; uniform sampler2D tex; uniform int use_blur; +uniform int use_grayscale; vec4 blur(sampler2D tex, vec2 coords) { @@ -20,12 +21,21 @@ vec4 blur(sampler2D tex, vec2 coords) return sum; } +vec4 grayscale(vec4 color) +{ + float gs = (0.2126 * color.r) + (0.7152 * color.g) + (0.0722 * color.b); + return vec4(gs, gs, gs, 1.0); +} + void main(void) { - if (texture2D(tex, texpos).rgb == vec3(1, 0, 1)) + vec4 texture_color = texture2D(tex, texpos); + + if (texture_color.rgb == vec3(1, 0, 1)) discard; - gl_FragColor = texture2D(tex, texpos); + gl_FragColor = texture_color; + if (use_blur == 1) { gl_FragColor = blur(tex, texpos); @@ -33,5 +43,8 @@ void main(void) gl_FragColor.g = 0; } - //gl_FragColor = vec4(1, 0, 0, 1); + if (use_grayscale == 1) + { + gl_FragColor = grayscale(texture_color); + } } \ No newline at end of file diff --git a/statemanager.cpp b/statemanager.cpp index 3686c4d..2c35ab1 100644 --- a/statemanager.cpp +++ b/statemanager.cpp @@ -44,8 +44,10 @@ StateManager::StateManager() _winX = 800; _winY = 600; _settingsChanged = false; + _stateChanged = false; _activeMapFilename = ""; _mapMusicFilename = ""; + _activeStateName = MAINMENU_SCREEN; Locator::getAudio()->playMenuMusic(); } @@ -130,6 +132,9 @@ void StateManager::switchToState(eState state) break; } + _stateChanged = true; + _activeStateName = state; + //done to prevent the mouse cursor sprite from being initially drawn in the old position. _activeState->setMousePosition(old_x, old_y); } @@ -328,4 +333,14 @@ void StateManager::resetScreenShotFlag() _loadMapState->tookScreenshot = false; _optionsState->tookScreenshot = false; _upgradesState->tookScreenshot = false; +} + +bool StateManager::stateChanged() +{ + return _stateChanged; +} + +void StateManager::resetStateChangedFlag() +{ + _stateChanged = false; } \ No newline at end of file diff --git a/statemanager.h b/statemanager.h index 669cb9c..739f42e 100644 --- a/statemanager.h +++ b/statemanager.h @@ -60,6 +60,9 @@ class StateManager void resetSettingsFlag(); bool screenshotTaken(); void resetScreenShotFlag(); + bool stateChanged(); + void resetStateChangedFlag(); + eState _activeStateName; private: BaseState* _activeState; BaseState* _gameState; @@ -72,6 +75,7 @@ class StateManager BaseState* _optionsState; BaseState* _upgradesState; bool _settingsChanged; + bool _stateChanged; std::string _activeMapFilename; std::string _mapMusicFilename; int _winX;