1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the libgltf project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include "FPSCounter.h"
11 #include "TimeFunction.h"
12 
13 #include <glm/gtc/matrix_transform.hpp>
14 #include <glm/gtc/type_ptr.hpp>
15 
16 namespace libgltf
17 {
18 
FPSCounter(ShaderProgram * pShaderProgram)19 FPSCounter::FPSCounter(ShaderProgram* pShaderProgram)
20     : pFont(new Font())
21     , uiFPSProgram(0)
22     , mLastTime(0.0)
23     , mFrames(0)
24     , mFPS(0)
25 #if WRITEFPS2FILE
26     , FPSRecoder()
27     , FPSFile()
28     , timeCounter(0)
29 #endif
30 {
31     pFont->loadFont();
32     init(pShaderProgram);
33 }
34 
~FPSCounter()35 FPSCounter::~FPSCounter()
36 {
37     if (NULL != pFont)
38     {
39         pFont->deleteFont();
40         delete pFont;
41     }
42     glDeleteProgram(uiFPSProgram);
43 #if WRITEFPS2FILE
44     FPSFile.open(FPS_FILE);
45     for (unsigned int i = 0;i < FPSRecoder.size();++i)
46     {
47         FPSFile << "FPS:" << FPSRecoder[i] << "\n";
48     }
49     FPSFile.close();
50     timeCounter = 0;
51     FPSRecoder.clear();
52 #endif
53 }
54 
loadFPSShader(ShaderProgram * pShaderProgram)55 bool FPSCounter::loadFPSShader(ShaderProgram* pShaderProgram)
56 {
57     uiFPSProgram = glCreateProgram();
58     pShaderProgram->loadShader(uiFPSProgram, VERTSHADER, strlen(VERTSHADER),
59                                GL_VERTEX_SHADER);
60     pShaderProgram->loadShader(uiFPSProgram, FRAGSHADER, strlen(FRAGSHADER),
61                                GL_FRAGMENT_SHADER);
62     pFont->setShaderProgram(uiFPSProgram);
63     return true;
64 }
65 
init(ShaderProgram * pShaderProgram)66 void FPSCounter::init(ShaderProgram* pShaderProgram)
67 {
68     loadFPSShader(pShaderProgram);
69 
70 #if WRITEFPS2FILE
71     timeCounter = 0;
72 #endif
73 }
74 
timeStamp()75 void FPSCounter::timeStamp()
76 {
77     if( mLastTime <= 0.0001 )
78     {
79         mLastTime = libgltf::time::getCurrentTime();
80     }
81 }
82 
83 #if QA_TEST
84 static int countTime = 0;
85 #endif
86 
printFPS(glTFViewport * pViewport)87 void FPSCounter::printFPS(glTFViewport* pViewport)
88 {
89     glUseProgram(uiFPSProgram);
90     glDisable(GL_DEPTH_TEST);
91     GLuint iLoc = glGetUniformLocation(uiFPSProgram, "projMatrix");
92     const glm::mat4 aMat = glm::ortho(0.0f, float(pViewport->width), 0.0f,
93                                       float(pViewport->height));
94     glUniformMatrix4fv(iLoc, 1, false, glm::value_ptr(aMat));
95     glm::vec4 lightVector = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f);
96     iLoc = glGetUniformLocation(uiFPSProgram, "vColor");
97     glUniform4fv(iLoc, 1, (GLfloat*)&lightVector);
98 
99     double mCurrentTime = libgltf::time::getCurrentTime();
100     double fDiff = libgltf::time::diffTime(mCurrentTime,mLastTime);
101 
102     if (fDiff >= 1.0)
103     {
104         mFPS = mFrames;
105         mFrames = 0;
106         mLastTime = mCurrentTime;
107 
108 #if WRITEFPS2FILE
109         timeCounter++;
110         if (timeCounter >= TIMETHRESHOLD)
111         {
112             FPSRecoder.push_back(mFPS);
113             timeCounter = 0;
114         }
115 #endif
116 
117 #if QA_TEST
118         countTime++;
119         if (countTime >= AUTO_CLOSE_TIME)
120         {
121             delete this;
122             exit(0);
123         }
124 #endif
125     }
126     else
127     {
128         ++mFrames;
129     }
130 
131     pFont->printFormattedString(pViewport->width - 40, 10, 15, "%d", mFPS);
132 
133     glEnable(GL_DEPTH_TEST);
134 }
135 
136 } // namespace libgltf
137 
138 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
139