Initial commit
[gltest.git] / gltest.cpp
1 // stdlib includes
2 #include <time.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <limits.h>
7 #include <unistd.h>
8 #include <assert.h>
9 #include <GL/gl.h>
10
11 // include proper GL connector
12 #include "glwindow.h"
13 #if defined(USE_GLX)
14 #include "glxbackend.h"
15 GLBackend *createGLBackend()
16 {
17         return new GLXBackend();
18 }
19 #elif defined(USE_EGL)
20 #include "eglbackend.h"
21 GLBackend *createGLBackend()
22 {
23         return new EGLBackend();
24 }
25 #else
26 #error "No GL window type selected"
27 #endif
28
29 // configuration
30 const GLfloat boxWidth = 0.045f;
31 const GLfloat boxSpeed = 1.25f; // per second
32
33 // profiler
34 const int numProfilerStates = 5;
35 const char *profilerStateNames[numProfilerStates] = { "Pre-Render", "Drawing", "Swapping", "Post-Render", "Outside renderer"};
36
37 // utility functions
38 static double getTime()
39 {
40         struct timespec tp;
41         clock_gettime(CLOCK_MONOTONIC, &tp);
42         return tp.tv_sec + 1e-9 * tp.tv_nsec;
43 }
44
45 static void drawRect(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
46 {
47         glVertex2f(x1, y1); glVertex2f(x2, y1); glVertex2f(x2, y2); glVertex2f(x1, y2);
48 }
49
50 // the window
51 class TearTestWindow : public GLWindow {
52 public:
53         TearTestWindow() : GLWindow(XOpenDisplay(0), createGLBackend()), boxPos(0), boxDirection(1)
54         {}
55
56 protected:
57         virtual void initGL()
58         {
59                 getBackend()->setSwapInterval(1);
60                 // initialize GL proper
61                 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
62                 glDisable(GL_DEPTH_TEST);
63                 // initialize clocks
64                 lastFrame = getTime();
65                 // initailize profiler
66                 framect = 0;
67                 memset(stateTime, 0, sizeof(stateTime));
68                 curState = -1;
69                 lastDisplay = lastProfile = getTime();
70         }
71         
72         virtual void resizeGL(unsigned int width, unsigned int height)
73         {
74                 /* prevent divide-by-zero */                      
75                 if (height == 0)                                  
76                         height = 1;                                   
77                 glViewport(0, 0, width, height);
78                 glMatrixMode(GL_PROJECTION);                      
79                 glLoadIdentity();                                 
80                 glOrtho (0, 1, 1, 0, 0, 1);
81                 glMatrixMode(GL_MODELVIEW);      
82                 glClear(GL_COLOR_BUFFER_BIT);                                                 
83                 glFlush();
84         }
85         
86         void profilerTick(int nextState)
87         {
88                 assert (nextState >= 0 && nextState < numProfilerStates);
89                 double time = getTime();
90                 if (curState >= 0)
91                         stateTime[curState] += time-lastProfile;
92                 curState = nextState;
93                 lastProfile = time;
94                 // display?
95                 const double elapsed = time-lastDisplay;
96                 if (elapsed >= 3) {
97                         printf("%.1f fps, time spent: ", framect/elapsed);
98                         for (int i = 0; i < numProfilerStates; ++i) {
99                                 if (i != 0) printf(", ");
100                                 printf("%s %.1f%%", profilerStateNames[i], stateTime[i]/elapsed*100);
101                         }
102                         printf("\n");
103                         lastDisplay = time;
104                         framect = 0;
105                         memset(stateTime, 0, sizeof(stateTime));
106                 }
107         }
108         
109         void renderGL()
110         {                            
111                 profilerTick(0);
112                 double time = getTime();
113                 // anim
114                 double passedTime = time-lastFrame;
115                 boxPos += boxSpeed*passedTime*boxDirection;
116                 while (boxPos < 0 || boxPos+boxWidth > 1) { // wrapover
117                         if (boxPos < 0) {
118                                 boxPos = -boxPos;
119                                 boxDirection = -boxDirection;
120                         }
121                         else {
122                                 boxPos = 1.0-boxWidth-(boxPos+boxWidth-1.0);
123                                 boxDirection = -boxDirection;
124                         }
125                 }
126                 lastFrame = time;
127                 // draw
128                 //glFlush();
129                 profilerTick(1);
130                 //glClear(GL_COLOR_BUFFER_BIT);
131                 glBegin(GL_QUADS);
132                 // clear manually
133                 glColor3f(0.0f, 0.0f, 0.0f);
134                 drawRect(0, 0, 1, 1);
135                 glColor3f(0.8f, 1.0f, 0.75f);
136                 drawRect(boxPos, 0, boxPos+boxWidth, 1);
137                 glEnd();
138                 usleep(20*1000);
139                 profilerTick(2);
140                 getBackend()->swapBuffers();
141 //              glDrawBuffer(GL_FRONT);
142 //              int xpos = 0;
143 //              int ypos = 0;
144                 //foreach (const QRect &r, region.rects()) {
145                         // convert to OpenGL coordinates
146                         //int y = displayHeight() - 0 - r.height();
147 //                      glBitmap(0, 0, 0, 0, 0 - xpos, 0 - ypos, NULL); // not glRasterPos2f, see glxbackend.cpp
148 //                      xpos = 0;
149 //                      ypos = 0;
150 //                      glCopyPixels(0, 0, getWidth(), getHeight(), GL_COLOR);
151                 //}
152 //              glBitmap(0, 0, 0, 0, -xpos, -ypos, NULL); // move position back to 0,0
153 //              glDrawBuffer(GL_BACK);
154                 profilerTick(3);
155                 glFlush();
156                 ++framect;
157                 profilerTick(4);
158         }
159         
160         virtual void handleKeyPress(KeySym key)
161         {
162                 switch (key) {
163                         case XK_Escape: close(); break;
164                         case XK_F1: setFullscreen(!getFullscreen()); break;
165                         default: break;
166                 }
167         }
168
169 private:
170         double lastFrame;
171         GLfloat boxPos, boxDirection;
172         // FPS
173         double lastDisplay, lastProfile;                 
174         int framect, curState;
175         double stateTime[numProfilerStates];
176 };
177
178
179
180 int main(int argc, char ** argv)
181 {
182         TearTestWindow w;
183         w.open(800, 600);
184         w.exec();
185 }