~ubuntu-branches/ubuntu/trusty/emscripten/trusty-proposed

« back to all changes in this revision

Viewing changes to tests/test_webgl_context_attributes_common.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2014-01-19 14:12:40 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20140119141240-jg1l42cc158j59tn
Tags: 1.9.0~20140119~7dc8c2f-1
* New snapshot release (Closes: #733714)
* Provide sources for javascript and flash. Done in orig-tar.sh
  Available in third_party/websockify/include/web-socket-js/src/
  (Closes: #735903)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <stdbool.h>
 
5
 
 
6
#include <emscripten.h>
 
7
 
 
8
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
 
9
 
 
10
static const int WINDOWS_SIZE = 500;
 
11
 
 
12
static GLfloat vertices[] = { 0.0f,  250.f, 0.0f, 
 
13
                             -250.f, -250.f, 0.0f,
 
14
                              250.f, -250.f, 0.0f };
 
15
 
 
16
static GLfloat vertices2[] = { 0.0f,  250.f, -1.0f, 
 
17
                              -250.f, -250.f, -1.0f,
 
18
                               250.f, -250.f, -1.0f };
 
19
 
 
20
static GLuint shaderProgram = 0;                       
 
21
static GLuint verticesVBO = 0;
 
22
static GLuint verticesVBO2 = 0;
 
23
 
 
24
static unsigned char backgroundColor[4] = {255, 255, 255, 255};
 
25
static unsigned char triangleColor[4] = {255, 0, 0, 255};
 
26
static unsigned char triangleColor2[4] = {0, 255, 0, 255};
 
27
 
 
28
static char vertexShaderSrc[] =
 
29
    "precision highp float;"
 
30
    "precision highp int;"
 
31
 
 
32
    "uniform mat4 u_mvpMatrix;"
 
33
    "uniform vec4 u_color;"
 
34
    
 
35
    "attribute vec3 a_position;"
 
36
    
 
37
    "varying vec4 v_color;"
 
38
 
 
39
    "void main() {"
 
40
    "   gl_Position = u_mvpMatrix * vec4(a_position, 1.0);"
 
41
    "   v_color = u_color;"
 
42
    "}"
 
43
    ;
 
44
 
 
45
static char fragmentShaderSrc[] =
 
46
    "precision highp float;"
 
47
    "precision highp int;"
 
48
 
 
49
    "varying vec4 v_color;"
 
50
 
 
51
    "void main() {"
 
52
    "  gl_FragColor = v_color;"
 
53
    "}"
 
54
    ;
 
55
 
 
56
static GLuint createShader(const char *source, int type) {
 
57
    GLuint shader = glCreateShader(type);
 
58
    glShaderSource(shader, 1, (const GLchar**)(&source), NULL);
 
59
    glCompileShader(shader);
 
60
    return shader;
 
61
}
 
62
 
 
63
static GLuint createShaderProgram(const char *vertexShaderSrc, const char *fragmentShaderSrc) {
 
64
    GLuint program = glCreateProgram();
 
65
    glAttachShader(program, createShader(vertexShaderSrc, GL_VERTEX_SHADER));
 
66
    glAttachShader(program, createShader(fragmentShaderSrc, GL_FRAGMENT_SHADER));
 
67
    glLinkProgram(program);
 
68
    return program;
 
69
}
 
70
 
 
71
void ortho(float  left,  float  right,  float  bottom,  float  top,  float  nearVal,  float  farVal, GLfloat *projMatrix) {
 
72
    float tx = -(right+left)/(right-left);
 
73
    float ty = -(top+bottom)/(top-bottom);
 
74
    float tz = -(farVal+nearVal)/(farVal-nearVal);
 
75
    memset(projMatrix, 0, 16 * sizeof(GLfloat));
 
76
    projMatrix[0] = 2.0f / (right-left);
 
77
    projMatrix[3] = tx;
 
78
    projMatrix[1*4+1] = 2.0f / (top-bottom);
 
79
    projMatrix[1*4+3] = ty;
 
80
    projMatrix[2*4+2] = -2.0f / (farVal-nearVal);
 
81
    projMatrix[2*4+3] = tz;
 
82
    projMatrix[3*4+3] = 1.0f;
 
83
}
 
84
 
 
85
static void initGlObjects() {
 
86
    glGenBuffers(1, &verticesVBO);
 
87
    glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
 
88
    glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), vertices, GL_STATIC_DRAW);
 
89
    glBindBuffer(GL_ARRAY_BUFFER, 0);
 
90
    
 
91
    glGenBuffers(1, &verticesVBO2);
 
92
    glBindBuffer(GL_ARRAY_BUFFER, verticesVBO2);
 
93
    glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), vertices2, GL_STATIC_DRAW);
 
94
    glBindBuffer(GL_ARRAY_BUFFER, 0);
 
95
    
 
96
    shaderProgram = createShaderProgram(vertexShaderSrc, fragmentShaderSrc);
 
97
}
 
98
 
 
99
static void drawTriangle(GLuint verticesVBO, unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
 
100
    glUseProgram(shaderProgram);
 
101
    GLuint posLoc = glGetAttribLocation(shaderProgram, "a_position");
 
102
    GLuint mvpLoc = glGetUniformLocation(shaderProgram, "u_mvpMatrix");
 
103
    GLuint colorLoc = glGetUniformLocation(shaderProgram, "u_color");
 
104
    
 
105
    GLfloat mvpMat[16];
 
106
    ortho(-WINDOWS_SIZE/2, WINDOWS_SIZE/2, -WINDOWS_SIZE/2, WINDOWS_SIZE/2, -100, 100, mvpMat);
 
107
    
 
108
    glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvpMat);
 
109
    glUniform4f(colorLoc, r/255.f, g/255.f, b/255.f, a/255.f);
 
110
    
 
111
    glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);  
 
112
    glEnableVertexAttribArray(posLoc);
 
113
    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), BUFFER_OFFSET(0));
 
114
    
 
115
    glDrawArrays(GL_TRIANGLES, 0, 3);
 
116
    
 
117
    glBindBuffer(GL_ARRAY_BUFFER, 0);
 
118
    glUseProgram(0);
 
119
}
 
120
 
 
121
// Draw a red triangle on a white background. If antialiasing is disabled, resulting pixels
 
122
// will only have white and red colors. If antialiasing is enabled, there will be pixels
 
123
// whose color is different from red and white.
 
124
static int testAntiAliasing(bool activated) {
 
125
    glViewport(0, 0, WINDOWS_SIZE, WINDOWS_SIZE);
 
126
    glClearColor(backgroundColor[0]/255.f, backgroundColor[1]/255.f, backgroundColor[2]/255.f, backgroundColor[3]/255.f);
 
127
    glClear(GL_COLOR_BUFFER_BIT);
 
128
    
 
129
    drawTriangle(verticesVBO, triangleColor[0], triangleColor[1], triangleColor[2], triangleColor[3]);
 
130
    
 
131
    bool antialiased = false;
 
132
    
 
133
    unsigned char buffer[(WINDOWS_SIZE*WINDOWS_SIZE)*4];
 
134
    glReadPixels(0, 0, WINDOWS_SIZE, WINDOWS_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]);
 
135
    glFinish();
 
136
    for (unsigned int i = 0 ; i < WINDOWS_SIZE ; ++i) {
 
137
      for (unsigned int j = 0 ; j < WINDOWS_SIZE ; ++j) {
 
138
        unsigned char r = buffer[4*(i*WINDOWS_SIZE+j)];
 
139
        unsigned char g = buffer[4*(i*WINDOWS_SIZE+j)+1];
 
140
        unsigned char b = buffer[4*(i*WINDOWS_SIZE+j)+2];
 
141
        unsigned char a = buffer[4*(i*WINDOWS_SIZE+j)+3];
 
142
        if ((r == backgroundColor[0] && g == backgroundColor[1] && b == backgroundColor[2] && a == backgroundColor[3]) || 
 
143
            (r == triangleColor[0] && g == triangleColor[1] && b == triangleColor[2] && a == triangleColor[3])) {
 
144
          continue;
 
145
        } else {
 
146
          antialiased = true;
 
147
          break;
 
148
        }
 
149
      }
 
150
    }
 
151
    
 
152
    return (activated && antialiased) || (!activated && !antialiased);
 
153
}
 
154
 
 
155
// Draw a red triangle with depth equals to 0 then a green triangle whose depth equals -1.
 
156
// If there is an attached depth buffer, the resulting image will be a red triangle. If not,
 
157
// the resulting image will be a green triangle.
 
158
static int testDepth(bool activated) {
 
159
    glViewport(0, 0, WINDOWS_SIZE, WINDOWS_SIZE);
 
160
    glClearColor(backgroundColor[0]/255.f, backgroundColor[1]/255.f, backgroundColor[2]/255.f, backgroundColor[3]/255.f);
 
161
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
162
    
 
163
    glEnable(GL_DEPTH_TEST);
 
164
    glDepthFunc(GL_LEQUAL);
 
165
    
 
166
    drawTriangle(verticesVBO, triangleColor[0], triangleColor[1], triangleColor[2], triangleColor[3]);
 
167
    drawTriangle(verticesVBO2, triangleColor2[0], triangleColor2[1], triangleColor2[2], triangleColor2[3]);
 
168
    
 
169
    glDisable(GL_DEPTH_TEST);
 
170
    
 
171
    // read the pixel at the center of the resulting image.
 
172
    unsigned char buffer[4];
 
173
    glReadPixels(WINDOWS_SIZE/2, WINDOWS_SIZE/2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]);
 
174
    
 
175
    bool frontTriangleColor = (buffer[0] == triangleColor[0] && buffer[1] == triangleColor[1] &&
 
176
                               buffer[2] == triangleColor[2] && buffer[3] == triangleColor[3]);
 
177
    
 
178
    bool backTriangleColor = (buffer[0] == triangleColor2[0] && buffer[1] == triangleColor2[1] &&
 
179
                              buffer[2] == triangleColor2[2] && buffer[3] == triangleColor2[3]);
 
180
    
 
181
    return (activated && frontTriangleColor) || (!activated && backTriangleColor);
 
182
}
 
183
 
 
184
// The stencil function is set to GL_LEQUAL so fragments will be written to the 
 
185
// back buffer only if the ref value is less or equal than the one in the stencil buffer.
 
186
// The content of the stencil buffer is initialized to 0xFF.
 
187
// First draw a red triangle whose stencil ref value is 0x1.
 
188
// Then draw a green triangle whose stencil ref value is 0xFF.
 
189
// If there is an attached stencil buffer, the resulting image will be a red triangle. If not,
 
190
// the resulting image will be a green triangle.
 
191
static int testStencil(bool activated) {
 
192
    glViewport(0, 0, WINDOWS_SIZE, WINDOWS_SIZE);
 
193
    glClearColor(backgroundColor[0]/255.f, backgroundColor[1]/255.f, backgroundColor[2]/255.f, backgroundColor[3]/255.f);
 
194
    glClearStencil(0xFF);
 
195
    glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
 
196
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
197
    
 
198
    glEnable(GL_STENCIL_TEST);
 
199
    
 
200
    glStencilFunc(GL_LEQUAL, 0x1, 0xFF);
 
201
    drawTriangle(verticesVBO, triangleColor[0], triangleColor[1], triangleColor[2], triangleColor[3]);
 
202
    
 
203
    glStencilFunc(GL_LEQUAL, 0xFF, 0xFF);
 
204
    drawTriangle(verticesVBO, triangleColor2[0], triangleColor2[1], triangleColor2[2], triangleColor2[3]);
 
205
    
 
206
    glDisable(GL_STENCIL_TEST);
 
207
    
 
208
    unsigned char buffer[4];
 
209
    glReadPixels(WINDOWS_SIZE/2, WINDOWS_SIZE/2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]);
 
210
    
 
211
    bool firstTriangleColor = (buffer[0] == triangleColor[0] && buffer[1] == triangleColor[1] &&
 
212
                               buffer[2] == triangleColor[2] && buffer[3] == triangleColor[3]);
 
213
    
 
214
    bool secondTriangleColor = (buffer[0] == triangleColor2[0] && buffer[1] == triangleColor2[1] &&
 
215
                                buffer[2] == triangleColor2[2] && buffer[3] == triangleColor2[3]);
 
216
    
 
217
    return (activated && firstTriangleColor) || (!activated && secondTriangleColor);
 
218
}
 
219
 
 
220
static bool antiAliasingActivated = false;
 
221
static bool depthActivated = false;
 
222
static bool stencilActivated = false;
 
223
 
 
224
static int result = 0;
 
225
static int resultAA = 0;
 
226
static int resultDepth = 0;
 
227
static int resultStencil = 0;
 
228
 
 
229
static void draw() {
 
230
  
 
231
  if (!resultAA) resultAA = testAntiAliasing(antiAliasingActivated);
 
232
   
 
233
  if (!resultDepth) resultDepth = testDepth(depthActivated);
 
234
  
 
235
  if (!resultStencil) resultStencil = testStencil(stencilActivated);
 
236
  
 
237
  result = resultAA && resultDepth && resultStencil;
 
238
 
 
239
}
 
240
 
 
241
extern int webglAntialiasSupported(void);
 
242
extern int webglDepthSupported(void);
 
243
extern int webglStencilSupported(void);
 
244
 
 
245
// Check attributes support in the WebGL implementation (see test_webgl_context_attributes function in test_browser.py)
 
246
// Tests will succeed if they are not.
 
247
static void checkContextAttributesSupport() {
 
248
  if (!webglAntialiasSupported()) {
 
249
    resultAA = 1;
 
250
    EM_ASM(alert('warning: no antialiasing\n'));
 
251
  }
 
252
  if (!webglDepthSupported()) {
 
253
    resultDepth = 1;
 
254
    EM_ASM(alert('warning: no depth\n'));
 
255
  }
 
256
  if (!webglStencilSupported()) {
 
257
    resultStencil = 1;
 
258
    EM_ASM(alert('warning: no stencil\n'));
 
259
  }
 
260
}
 
261
 
 
262