source/viewer/MenuScreen.h (143 lines of code) (raw):

/** * Copyright 2004-present Facebook. All Rights Reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #ifdef WIN32 #include <algorithm> #include <functional> #include <iostream> #include "OVR_CAPI_GL.h" #include "Samples/OculusRoomTiny_Advanced/Common/Win32_GLAppUtil.h" #include "source/thirdparty/stb_image.h" namespace fb360_dep { struct MenuScreen { Model* model = nullptr; ShaderFill* gridMaterial = nullptr; int transitionCounter = 0; static const int kTransitionFrames = 180; bool isHidden = false; bool doFadeOut = false; std::function<void()> exitMenuCallback; // this will be called when we leave the menu MenuScreen() { setupShaders(); model = new Model(Vector3f(0, 0, 0), gridMaterial); model->AddSolidColorBox(-0.5, -0.5, 2, 0.5, 0.5, 2, 0xffffffff); // logo box model->AllocateBuffers(); } void startFadeOut() { if (doFadeOut) { return; } // dont restart transition if it already started doFadeOut = true; transitionCounter = 0; } void resetToMenu() { doFadeOut = false; transitionCounter = 0; isHidden = false; } void update() { if (isHidden) { return; } if (doFadeOut) { ++transitionCounter; transitionCounter = std::min(transitionCounter, kTransitionFrames); } if (doFadeOut && (transitionCounter == kTransitionFrames)) { isHidden = true; doFadeOut = false; exitMenuCallback(); } } void setupShaders() { static const GLchar* VertexShaderSrc = "#version 150\n" "uniform mat4 matWVP;\n" "in vec4 Position;\n" "in vec4 Color;\n" "in vec2 TexCoord;\n" "out vec2 oTexCoord;\n" "out vec4 oColor;\n" "void main()\n" "{\n" " gl_Position = (matWVP * Position);\n" " oTexCoord = TexCoord;\n" " oColor.rgb = pow(Color.rgb, vec3(2.2));\n" // convert from sRGB to linear " oColor.a = Color.a;\n" "}\n"; static const char* FragmentShaderSrc = "#version 150\n" "uniform sampler2D Texture0;\n" "in vec4 oColor;\n" "in vec2 oTexCoord;\n" "out vec4 FragColor;\n" "void main()\n" "{\n" " FragColor = oColor * texture2D(Texture0, -oTexCoord + vec2(0.5, 0.5));\n" "}\n"; GLuint vshader = CreateShader(GL_VERTEX_SHADER, VertexShaderSrc); GLuint fshader = CreateShader(GL_FRAGMENT_SHADER, FragmentShaderSrc); static const std::string kLogoFilename = "logo.png"; static const int kDstChannels = 4; int width, height, channels; uint8_t* textureBytes = stbi_load(kLogoFilename.c_str(), &width, &height, &channels, kDstChannels); if (!textureBytes) { std::cout << "ERROR LOADING LOGO TEXTURE: " << kLogoFilename << std::endl; static uint8_t dummy[] = { 255, 0, 0, 0, }; textureBytes = dummy; width = 1; height = 1; channels = 4; } TextureBuffer* generated_texture = new TextureBuffer(false, Sizei(width, height), 4, (unsigned char*)textureBytes); gridMaterial = new ShaderFill(vshader, fshader, generated_texture); glDeleteShader(vshader); glDeleteShader(fshader); } ~MenuScreen() { if (model != nullptr) { delete model; } if (gridMaterial != nullptr) { delete gridMaterial; } } void draw(Matrix4f view, Matrix4f proj) { glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glClearColor(0, 0, 0, 1); if (transitionCounter > 0) { float brightness = pow(std::min(1.0f, float(transitionCounter) / float(kTransitionFrames)), 2.2f); glClearColor(brightness, brightness, brightness, 1); } model->Render(view, proj); CHECK_EQ(glGetError(), GL_NO_ERROR); } // NOTE: this is copy-pasted from Win32_GLAppUtil.h static GLuint CreateShader(GLenum type, const GLchar* src) { GLuint shader = glCreateShader(type); glShaderSource(shader, 1, &src, NULL); glCompileShader(shader); GLint r; glGetShaderiv(shader, GL_COMPILE_STATUS, &r); if (!r) { GLchar msg[1024]; glGetShaderInfoLog(shader, sizeof(msg), 0, msg); if (msg[0]) { OVR_DEBUG_LOG(("Compiling shader failed: %s\n", msg)); } return 0; } return shader; } }; } // namespace fb360_dep #endif // end ifdef WIN32