blob: 2fb4541c63649479c45f3c14623ab58cc0e52fca [file] [log] [blame]
Vincent Scheibc5114c12010-04-08 08:49:50 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Application that displays graphics using OpenGL [ES] with the intent
6// of being used in functional tests.
7
8#include <gflags/gflags.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <time.h>
13
14#include <cmath>
15
16#include "main.h"
17#include "utils.h"
18
19
20GLuint GenerateAndBindTexture() {
21 GLuint name = ~0;
22 glGenTextures(1, &name);
23 glBindTexture(GL_TEXTURE_2D, name);
24 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
25 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
26 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
27 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
28 return name;
29}
30
31
32unsigned char* CreateBitmap(int w, int h) {
33 unsigned char* bitmap = new unsigned char[w * h];
34 unsigned char* pixel = bitmap;
35 float w2 = w/2.0f;
36 float h2 = h/2.0f;
37 for (int y = 0; y < h; y++) {
38 for (int x = 0; x < w; x++) {
39 // Fill with soft ellipse
40 float dx = fabs((x - w2) / w2);
41 float dy = fabs((y - h2) / h2);
42 float dist2 = dx*dx + dy*dy;
43 if (dist2 > 1.f)
44 dist2 = 1.f;
45 *pixel = (1.f-dist2) * 255.f;
46 pixel++;
47 }
48 }
49 return bitmap;
50}
51
52
53const char kVertexShader[] =
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070054 "attribute vec4 vertices;"
Vincent Scheibc5114c12010-04-08 08:49:50 -070055 "void main() {"
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070056 " gl_Position = vertices;"
57 " gl_TexCoord[0] = vec4(vertices.y, vertices.x, 0.0, 0.0);"
Vincent Scheibc5114c12010-04-08 08:49:50 -070058 "}";
59
60const char kFragmentShader[] =
61 "uniform sampler2D tex;"
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070062 "uniform vec4 color;"
Vincent Scheibc5114c12010-04-08 08:49:50 -070063 "void main() {"
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070064 " gl_FragColor = color * texture2D(tex, gl_TexCoord[0].xy);"
Vincent Scheibc5114c12010-04-08 08:49:50 -070065 "}";
66
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070067// Command line flags
68DEFINE_double(screenshot1_sec, 2.f, "seconds delay before screenshot1_cmd");
69DEFINE_double(screenshot2_sec, 1.f, "seconds delay before screenshot2_cmd");
70DEFINE_string(screenshot1_cmd, "", "system command to take a screen shot 1");
71DEFINE_string(screenshot2_cmd, "", "system command to take a screen shot 2");
72DEFINE_double(cooldown_sec, 1.f, "seconds delay after all screenshots");
Vincent Scheibc5114c12010-04-08 08:49:50 -070073
74int main(int argc, char* argv[]) {
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070075 // Configure full screen
Vincent Scheibc5114c12010-04-08 08:49:50 -070076 g_width = -1;
77 g_height = -1;
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070078
Vincent Scheibc5114c12010-04-08 08:49:50 -070079 google::ParseCommandLineFlags(&argc, &argv, true);
80
81 if (!Init()) {
82 printf("# Failed to initialize.\n");
83 return 1;
84 }
85
86 InitContext();
87 glViewport(-g_width, -g_height, g_width*2, g_height*2);
88
89 unsigned char* bitmap = CreateBitmap(g_height, g_width);
90 GLuint texture = GenerateAndBindTexture();
91 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, g_height, g_width, 0,
92 GL_LUMINANCE, GL_UNSIGNED_BYTE, bitmap);
93
94 GLfloat vertices[8] = {
95 0.f, 0.f,
96 1.f, 0.f,
97 0.f, 1.f,
98 1.f, 1.f,
99 };
100
101 GLuint program = InitShaderProgram(kVertexShader, kFragmentShader);
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700102 int attribute_index = glGetAttribLocation(program, "vertices");
Vincent Scheibc5114c12010-04-08 08:49:50 -0700103 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices);
104 glEnableVertexAttribArray(attribute_index);
105
106 int texture_sampler = glGetUniformLocation(program, "tex");
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700107 glUniform1i(texture_sampler, 0);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700108
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700109 int display_color = glGetUniformLocation(program, "color");
110 float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
111 float blue[4] = {0.5f, 0.5f, 1.0f, 1.0f};
112
113 uint64_t last_event_time = GetUTime();
114 enum State {
115 kStateScreenShot1,
116 kStateScreenShot2,
117 kStateCooldown,
118 kStateExit
119 } state = kStateScreenShot1;
120 float seconds_delay_for_next_state[] = {
121 FLAGS_screenshot1_sec,
122 FLAGS_screenshot2_sec,
123 FLAGS_cooldown_sec,
124 0
125 };
126
Vincent Scheibc5114c12010-04-08 08:49:50 -0700127 do {
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700128 // Draw
Vincent Scheibc5114c12010-04-08 08:49:50 -0700129 glClear(GL_COLOR_BUFFER_BIT);
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700130 if (state == kStateScreenShot1)
131 glUniform4fv(display_color, 1, white);
132 else
133 glUniform4fv(display_color, 1, blue);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700134 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
135 SwapBuffers();
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700136
137 // Loop until next event
138 float seconds_since_last_event =
139 static_cast<float>(GetUTime() - last_event_time) / 1000000ULL;
140 if (seconds_since_last_event < seconds_delay_for_next_state[state])
141 continue;
142
143 // State change. Perform action.
144 switch(state) {
145 case kStateScreenShot1:
146 system(FLAGS_screenshot1_cmd.c_str());
147 break;
148 case kStateScreenShot2:
149 system(FLAGS_screenshot2_cmd.c_str());
150 break;
151 default:
152 break;
153 }
154
155 // Advance to next state
156 last_event_time = GetUTime();
157 state = static_cast<State>(state + 1);
158
159 } while (state != kStateExit);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700160
161 glDeleteTextures(1, &texture);
162 DestroyContext();
163 return 0;
164}