1 // Copyright (c) 2012 The Chromium 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.
5 #include <GLES2/gl2ext.h>
10 // Some tests for occlusion queries.
11 #include "gpu/demos/framework/demo_factory.h"
12 #include "gpu/demos/gles2_book/example.h"
19 class OcclusionQueryTest
;
22 OcclusionQueryTest
* demo
;
25 class OcclusionQueryTest
: public gles2_book::Example
<STUserData
> {
35 last_query_status_(0) {
37 RegisterCallbacks(stInit
, stUpdate
, stDraw
, stShutDown
);
40 const wchar_t* Title() const {
41 return L
"Occlusion Query Test";
49 int Init(ESContext
* esContext
);
50 void Update(ESContext
* esContext
, float elapsed_sec
);
51 void Draw(ESContext
* esContext
);
52 void ShutDown(ESContext
* esContext
);
55 void DrawRect(float x
, float z
, float scale
, float* color
);
57 static int stInit(ESContext
* esContext
) {
58 static_cast<STUserData
*>(esContext
->userData
)->demo
= test_
;
60 return static_cast<STUserData
*>(esContext
->userData
)->demo
->Init(esContext
);
63 static void stUpdate (ESContext
* esContext
, float elapsed_sec
) {
64 static_cast<STUserData
*>(esContext
->userData
)->demo
->Update(
65 esContext
, elapsed_sec
);
68 static void stShutDown (ESContext
* esContext
) {
69 static_cast<STUserData
*>(esContext
->userData
)->demo
->ShutDown(
73 static void stDraw (ESContext
* esContext
) {
74 static_cast<STUserData
*>(esContext
->userData
)->demo
->Draw(
78 // This is the test being created. Because the GLES2 book's framework
79 // has no way to pass anything into the init funciton this is a hacky
81 static OcclusionQueryTest
* test_
;
90 GLuint last_query_status_
;
93 static float green_
[4];
94 static float blue_
[4];
97 OcclusionQueryTest
* OcclusionQueryTest::test_
;
98 float OcclusionQueryTest::red_
[4] = { 1, 0, 0, 1, };
99 float OcclusionQueryTest::green_
[4] = { 0, 1, 0, 1, };
100 float OcclusionQueryTest::blue_
[4] = { 0, 0, 1, 1, };
102 void CheckGLError(const char* func_name
, int line_no
) {
104 GLenum error
= GL_NO_ERROR
;
105 while ((error
= glGetError()) != GL_NO_ERROR
) {
106 fprintf(stderr
, "GL ERROR in %s at line %d : 0x%04x\n",
107 func_name
, line_no
, error
);
112 GLuint
LoadShader(GLenum type
, const char* shaderSrc
) {
113 CheckGLError("LoadShader", __LINE__
);
114 GLuint shader
= glCreateShader(type
);
118 // Load the shader source
119 glShaderSource(shader
, 1, &shaderSrc
, NULL
);
120 // Compile the shader
121 glCompileShader(shader
);
122 // Check the compile status
124 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &value
);
128 glGetShaderInfoLog(shader
, sizeof(buffer
), &length
, buffer
);
129 std::string
log(buffer
, length
);
130 fprintf(stderr
, "Error compiling shader: %s\n", log
.c_str());
131 glDeleteShader(shader
);
137 void OcclusionQueryTest::InitShaders() {
138 static const char* v_shader_str
=
139 "uniform mat4 worldMatrix;\n"
140 "attribute vec3 g_Position;\n"
143 " gl_Position = worldMatrix *\n"
144 " vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);\n"
146 static const char* f_shader_str
=
147 "precision mediump float;"
148 "uniform vec4 color;\n"
151 " gl_FragColor = color;\n"
154 CheckGLError("InitShaders", __LINE__
);
155 GLuint vertex_shader
= LoadShader(GL_VERTEX_SHADER
, v_shader_str
);
156 GLuint fragment_shader
= LoadShader(GL_FRAGMENT_SHADER
, f_shader_str
);
157 // Create the program object
158 GLuint program
= glCreateProgram();
160 fprintf(stderr
, "Creating program failed\n");
163 glAttachShader(program
, vertex_shader
);
164 glAttachShader(program
, fragment_shader
);
165 // Bind g_Position to attribute 0
166 glBindAttribLocation(program
, 0, "g_Position");
168 glLinkProgram(program
);
169 // Check the link status
171 glGetProgramiv(program
, GL_LINK_STATUS
, &linked
);
175 glGetProgramInfoLog(program
, sizeof(buffer
), &length
, buffer
);
176 std::string
log(buffer
, length
);
177 fprintf(stderr
, "Error linking program: %s\n", log
.c_str());
178 glDeleteProgram(program
);
182 matrix_loc_
= glGetUniformLocation(program_
, "worldMatrix");
183 color_loc_
= glGetUniformLocation(program_
, "color");
184 glGenBuffers(1, &vbo_
);
185 glBindBuffer(GL_ARRAY_BUFFER
, vbo_
);
186 static float vertices
[] = {
194 glBufferData(GL_ARRAY_BUFFER
,
198 glBufferSubData(GL_ARRAY_BUFFER
, 0, sizeof(vertices
), vertices
);
199 CheckGLError("InitShaders", __LINE__
);
201 glGenQueriesEXT(1, &query_
);
202 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, query_
);
203 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
204 CheckGLError("InitShaders", __LINE__
);
207 } // anonymous namespace.
209 int OcclusionQueryTest::Init(ESContext
* esContext
) {
210 CheckGLError("GLFromCPPInit", __LINE__
);
211 glClearColor(0.0f
, 0.1f
, 0.2f
, 1.0f
);
213 CheckGLError("GLFromCPPInit", __LINE__
);
217 void OcclusionQueryTest::Update(ESContext
* esContext
, float elapsed_sec
) {
218 elasped_sec_
= elapsed_sec
;
221 static void SetMatrix(float x
, float z
, float scale
, float* matrix
) {
243 void OcclusionQueryTest::DrawRect(float x
, float z
, float scale
, float* color
) {
246 SetMatrix(x
, z
, scale
, matrix
);
248 // Set up the model matrix
249 glUniformMatrix4fv(matrix_loc_
, 1, GL_FALSE
, matrix
);
251 glUniform4fv(color_loc_
, 1, color
);
252 CheckGLError("GLFromCPPDraw", __LINE__
);
254 glDrawArrays(GL_TRIANGLES
, 0, 6);
255 CheckGLError("GLFromCPPDraw", __LINE__
);
258 void OcclusionQueryTest::Draw(ESContext
* esContext
) {
259 CheckGLError("GLFromCPPDraw", __LINE__
);
260 clock_
+= elasped_sec_
;
262 // Note: the viewport is automatically set up to cover the entire Canvas.
263 // Clear the color buffer
264 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
265 glEnable(GL_DEPTH_TEST
);
266 CheckGLError("GLFromCPPDraw", __LINE__
);
267 // Use the program object
268 glUseProgram(program_
);
269 CheckGLError("GLFromCPPDraw", __LINE__
);
271 // Load the vertex data
272 glBindBuffer(GL_ARRAY_BUFFER
, vbo_
);
273 glEnableVertexAttribArray(0);
274 glVertexAttribPointer(0, 3, GL_FLOAT
, GL_FALSE
, 0, 0);
275 CheckGLError("GLFromCPPDraw", __LINE__
);
277 DrawRect(sinf(clock_
), 0.0f
, 0.50f
,
278 last_query_status_
? green_
: red_
);
280 bool started_query
= false;
282 glGetQueryObjectuivEXT(query_
, GL_QUERY_RESULT_AVAILABLE_EXT
, &result
);
283 CheckGLError("GLFromCPPDraw", __LINE__
);
285 glGetQueryObjectuivEXT(query_
, GL_QUERY_RESULT_EXT
, &last_query_status_
);
286 CheckGLError("GLFromCPPDraw", __LINE__
);
287 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, query_
);
288 CheckGLError("GLFromCPPDraw", __LINE__
);
289 started_query
= true;
292 DrawRect(-0.125f
, 0.1f
, 0.25f
, blue_
);
295 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
296 CheckGLError("GLFromCPPDraw", __LINE__
);
302 void OcclusionQueryTest::ShutDown(ESContext
* esContext
) {
306 return new OcclusionQueryTest();