146 строки
4.9 KiB
C++
146 строки
4.9 KiB
C++
#include "SDL/SDL_opengl.h"
|
|
#include "SDL/SDL.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <emscripten.h>
|
|
|
|
void RunTest(int testVariant)
|
|
{
|
|
GLuint vs = 0;
|
|
|
|
const char *vsCode = "#version 100\n"
|
|
"attribute vec4 pos; void main() { gl_Position = pos; }";
|
|
|
|
vs = glCreateShader(GL_VERTEX_SHADER);
|
|
glShaderSource(vs, 1, &vsCode, NULL);
|
|
glCompileShader(vs);
|
|
|
|
GLuint ps = 0;
|
|
|
|
const char *psCode = "#version 100\n"
|
|
"precision lowp float;\n"
|
|
"uniform vec3 color;\n"
|
|
"uniform vec3 colors[3];\n"
|
|
"void main() { gl_FragColor = vec4(color,1) + vec4(colors[0].r, colors[1].g, colors[2].b, 1); }";
|
|
|
|
ps = glCreateShader(GL_FRAGMENT_SHADER);
|
|
glShaderSource(ps, 1, &psCode, NULL);
|
|
glCompileShader(ps);
|
|
|
|
GLuint program = 0;
|
|
program = glCreateProgram();
|
|
glAttachShader(program, vs);
|
|
glAttachShader(program, ps);
|
|
glBindAttribLocation(program, 0, "pos");
|
|
glLinkProgram(program);
|
|
|
|
// Also test that GL_ACTIVE_ATTRIBUTE_MAX_LENGTH and GL_ACTIVE_UNIFORM_MAX_LENGTH work. See https://github.com/kripken/emscripten/issues/1796.
|
|
GLint param;
|
|
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, ¶m);
|
|
printf("active attrib max length: %d\n", param);
|
|
assert(param == 4); // "pos"+null terminator
|
|
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, ¶m);
|
|
printf("active uniform max length: %d\n", param);
|
|
assert(param == 10); // "colors[0]"+null terminator
|
|
|
|
int color_loc = glGetUniformLocation(program, "color");
|
|
assert(color_loc != -1);
|
|
|
|
glUseProgram(program);
|
|
float col[3] = { 0.2f, 0.2f, 0.2f };
|
|
glUniform3fv(color_loc, 1, col);
|
|
|
|
int loc = glGetUniformLocation(program, "colors");
|
|
assert(loc != -1);
|
|
// In previous Emscripten GL layer code, calling glGetUniformLocation would do extra caching operations that interacts how glUniform** after that will work,
|
|
// so to exhibit extra issues in old code (and to keep new code from regressing), must test both with and without excess glGetUniformLocation calls.
|
|
if ((testVariant&1) != 0)
|
|
{
|
|
printf("check glGetUniformLocation with indexes\n");
|
|
// Deliberately check in odd order to make sure any kind of lazy operations won't affect the indices we get.
|
|
assert(glGetUniformLocation(program, "colors[2]") == loc+2);
|
|
assert(glGetUniformLocation(program, "colors[0]") == loc);
|
|
assert(glGetUniformLocation(program, "colors[3]") == -1);
|
|
assert(glGetUniformLocation(program, "colors[1]") == loc+1);
|
|
assert(glGetUniformLocation(program, "colors[]") == loc);
|
|
assert(glGetUniformLocation(program, "colors[-100]") == -1);
|
|
assert(glGetUniformLocation(program, "colors[bleh]") == -1);
|
|
printf(" ...ok\n");
|
|
}
|
|
|
|
float colors[4*3] = { 1,0,0, 0,0.5,0, 0,0,0.2, 1,1,1 };
|
|
|
|
if ((testVariant&2)!=0)
|
|
{
|
|
glUniform3fv(loc+1, 3, colors+3); // Pass the actual colors (testing a nonzero location offset), but do a mistake by setting one index too many. Spec says this should be gracefully handled, and that excess elements are ignored.
|
|
assert(glGetError() == GL_NO_ERROR);
|
|
glUniform3fv(loc, 1, colors); // Set the first index as well.
|
|
assert(glGetError() == GL_NO_ERROR);
|
|
}
|
|
else
|
|
{
|
|
glUniform3fv(loc, 4, colors); // Just directly set the full array.
|
|
assert(glGetError() == GL_NO_ERROR);
|
|
}
|
|
|
|
assert(glGetError() == GL_NO_ERROR);
|
|
|
|
GLuint vbo = 0;
|
|
const GLfloat v[] = { -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1 };
|
|
glGenBuffers(1, &vbo);
|
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
|
|
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0);
|
|
glEnableVertexAttribArray(0);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
|
|
int in_worker = EM_ASM_INT_V({
|
|
return typeof importScripts !== 'undefined'
|
|
});
|
|
|
|
if (!in_worker) {
|
|
printf("Doing readpixels check\n");
|
|
unsigned char pixel[4];
|
|
glReadPixels(1,1,1,1,GL_RGBA,GL_UNSIGNED_BYTE, pixel);
|
|
//printf("%d,%d,%d,%d\n", pixel[0], pixel[1], pixel[2], pixel[3]);
|
|
assert(pixel[0] == 255);
|
|
assert(pixel[1] == 178);
|
|
assert(pixel[2] == 102);
|
|
assert(pixel[3] == 255);
|
|
}
|
|
|
|
printf("OK: Case %d passed.\n", testVariant);
|
|
// Lazy, don't clean up afterwards.
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
SDL_Surface *screen;
|
|
|
|
// Slightly different SDL initialization
|
|
if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
|
|
printf("Unable to initialize SDL: %s\n", SDL_GetError());
|
|
return 1;
|
|
}
|
|
|
|
screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
|
|
if ( !screen ) {
|
|
printf("Unable to set video mode: %s\n", SDL_GetError());
|
|
return 1;
|
|
}
|
|
|
|
for(int i = 0; i < 4; ++i)
|
|
RunTest(i);
|
|
|
|
#ifdef REPORT_RESULT
|
|
int result = 1;
|
|
REPORT_RESULT();
|
|
#endif
|
|
|
|
return 0;
|
|
}
|