#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h>
#include <pixelflinger2/pixelflinger2_interface.h>
int ApproximatelyEqual(const Vector4 lhs, const Vector4 rhs, const float t)
{
if (fabs(lhs.x - rhs.x) > t)
return 0;
if (fabs(lhs.y - rhs.y) > t)
return 0;
if (fabs(lhs.z - rhs.z) > t)
return 0;
if (fabs(lhs.w - rhs.w) > t)
return 0;
return 1;
}
extern void * llvmCtx;
void contextless_test()
{
static const char vsGLSL [] =
"uniform vec4 uVec4; \n"
"uniform sampler2D sampler2d; \n"
"attribute vec4 aPosition; \n"
"attribute vec4 aTexCoord; \n"
"varying vec4 vTexCoord; \n"
"varying vec4 vTexColor; \n"
"void main() { \n"
" gl_Position = aPosition; \n"
" vTexCoord = aTexCoord; \n"
" vTexColor = texture2D(sampler2d, aTexCoord.zw); \n"
" gl_PointSize = 432.0; \n"
"}";
gl_shader_t * vs = GGLShaderCreate(GL_VERTEX_SHADER);
const char * infoLog = NULL;
if (!GGLShaderCompile(vs, vsGLSL, &infoLog)) {
printf("GGLShaderCompile vs failed:\n%s\n", infoLog);
assert(0);
}
static const char fsGLSL [] =
"uniform vec4 uVec4; \n"
"uniform sampler2D sampler2d; \n"
"varying vec4 vTexCoord; \n"
"varying vec4 vTexColor; \n"
"void main() { \n"
" gl_FragColor = texture2D(sampler2d, vTexCoord.zw); \n"
"}";
gl_shader_t * fs = GGLShaderCreate(GL_FRAGMENT_SHADER);
if (!GGLShaderCompile(fs, fsGLSL, &infoLog)) {
printf("GGLShaderCompile fs failed:\n%s\n", infoLog);
assert(0);
}
gl_shader_program_t * prog = GGLShaderProgramCreate();
unsigned glError = GL_NO_ERROR;
glError = GGLShaderAttach(prog, vs);
assert(GL_NO_ERROR == glError);
glError = GGLShaderAttach(prog, fs);
assert(GL_NO_ERROR == glError);
GGLShaderAttributeBind(prog, 4, "aPosition");
GGLShaderAttributeBind(prog, 5, "aTexCoord");
if (!GGLShaderProgramLink(prog, &infoLog)) {
printf("GGLShaderProgramLink failed:\n%s\n", infoLog);
assert(0);
}
// llvm::LLVMContext * llvmCtx = new llvm::LLVMContext();
GGLState_t gglState = {0};
unsigned texels0 [] = {0xff10ffff, 0x22222222, 0x66666666, 0xffffffff};
GGLTexture_t texture0 = {GL_TEXTURE_2D, GGL_PIXEL_FORMAT_RGBA_8888,
2, 2, 1, // width, height, levelCount
texels0, GGL_CLAMP_TO_EDGE, GGL_CLAMP_TO_EDGE,
GGL_NEAREST, GGL_NEAREST
};
gglState.textureState.textures[0] = texture0;
gglState.textureState.textureData[0] = gglState.textureState.textures[0].levels;
gglState.textureState.textureDimensions[0 * 2 + 0] = gglState.textureState.textures[0].width;
gglState.textureState.textureDimensions[0 * 2 + 1] = gglState.textureState.textures[0].height;
GGLShaderUse(llvmCtx, &gglState, prog);
VertexInput_t input = {0, 0, 0, 0};
input.attributes[4] = VECTOR4_CTR(0,0,0,1);
input.attributes[5] = VECTOR4_CTR(0,0,0,0);
VertexOutput_t output = {0};
GGLProcessVertex(prog, &input, &output, NULL);
int vTexColor = -1;
GGLShaderVaryingLocation(prog, "vTexColor", &vTexColor);
if (vTexColor >= 0) {
if (memcmp(((Vector4 *)&output) + vTexColor, &VECTOR4_CTR(1,1,16/255.0f,1), sizeof(Vector4))) {
puts("((Vector4 *)&output)[vTexColor] != Vector4(1,1,0,1)");
assert(0);
}
} else {
puts("vTexColor < 0");
assert(0);
}
static const char fsGLSL1 [] =
"uniform vec4 uVec4; \n"
"uniform sampler2D sampler2d; \n"
"varying vec4 vTexCoord; \n"
"varying vec4 vTexColor; \n"
"void main() { \n"
" gl_FragColor = vTexColor; \n"
"}";
gl_shader_t * fs1 = GGLShaderCreate(GL_FRAGMENT_SHADER);
if (!GGLShaderCompile(fs1, fsGLSL1, &infoLog)) {
printf("GGLShaderCompile fs failed:\n%s\n", infoLog);
assert(0);
}
gl_shader_program_t * prog1 = GGLShaderProgramCreate();
glError = GGLShaderAttach(prog1, vs);
assert(GL_NO_ERROR == glError);
glError = GGLShaderAttach(prog1, fs1);
assert(GL_NO_ERROR == glError);
GGLShaderAttributeBind(prog1, 1, "aPosition");
GGLShaderAttributeBind(prog1, 2, "aTexCoord");
if (!GGLShaderProgramLink(prog1, &infoLog)) {
printf("GGLShaderProgramLink failed:\n%s\n", infoLog);
assert(0);
}
GGLShaderUse(llvmCtx, &gglState, prog1);
VertexInput_t input1 = {0};
input1.attributes[1] = VECTOR4_CTR(1,1,0,1);
input1.attributes[2] = VECTOR4_CTR(1,1,0,0);
VertexOutput_t output1 = {0};
GGLProcessVertex(prog1, &input1, &output1, NULL);
int vTexCoord = -1;
assert(2 == GGLShaderAttributeLocation(prog1, "aTexCoord"));
GGLShaderVaryingLocation(prog1, "vTexCoord", &vTexCoord);
if (vTexCoord >= 0) {
if (memcmp(((Vector4 *)&output1) + vTexCoord, input1.attributes + 2, sizeof(Vector4))) {
puts("((Vector4 *)&output1)[vTexCoord] != input1.attributes[1]");
assert(0);
}
} else {
puts("vTexCoord < 0");
assert(0);
}
puts("***\n finished contextless_test \n***");
GGLShaderProgramDelete(prog);
GGLShaderProgramDelete(prog1);
GLContextDctr();
}
int cmain(int argc, char **argv)
{
contextless_test();
const char * infoLog = NULL;
GGLInterface_t * ggl = CreateGGLInterface();
gl_shader_t * shader0 = ggl->ShaderCreate(ggl, GL_VERTEX_SHADER);
assert(shader0);
const char * glsl0 =
"uniform vec4 uVec4; \n"
"uniform sampler2D sampler2d; \n"
"attribute vec4 aPosition; \n"
"attribute vec4 aTexCoord; \n"
"varying vec4 vTexCoord; \n"
"varying vec4 vTexColor; \n"
"void main() { \n"
" gl_Position = aPosition; \n"
" vTexCoord = aTexCoord + uVec4; \n"
" vTexColor = texture2D(sampler2d, aTexCoord.zw); \n"
" gl_PointSize = 432; \n"
"}";
puts(glsl0);
GLboolean compileStatus = ggl->ShaderCompile(ggl, shader0, glsl0, &infoLog);
if (!compileStatus)
fprintf(stderr, "failed to compile vertex shader 0, infoLog: \n %s \n", infoLog);
assert(compileStatus);
gl_shader_t * shader1 = ggl->ShaderCreate(ggl, GL_FRAGMENT_SHADER);
assert(shader1);
const char * glsl1 =
"uniform vec4 uVec4; \n"
"uniform sampler2D sampler2d; \n"
"varying vec4 vTexCoord; \n"
"varying vec4 vTexColor; \n"
"void main() { \n"
" gl_FragColor = vTexCoord + vTexColor; \n"
"}";
puts(glsl1);
compileStatus = ggl->ShaderCompile(ggl, shader1, glsl1, &infoLog);
if (!compileStatus)
fprintf(stderr, "failed to compile fragment shader 0, infoLog: \n %s \n", infoLog);
assert(compileStatus);
gl_shader_program_t * program0 = ggl->ShaderProgramCreate(ggl);
assert(program0);
ggl->ShaderAttach(ggl, program0, shader0);
ggl->ShaderAttach(ggl, program0, shader1);
ggl->ShaderAttributeBind(program0, 2, "aTexCoord");
ggl->ShaderAttributeBind(program0, 3, "aPosition");
GLboolean linkStatus = ggl->ShaderProgramLink(program0, &infoLog);
if (!linkStatus)
fprintf(stderr, "failed to link program 0, infoLog: \n %s \n", infoLog);
assert(linkStatus);
ggl->ShaderUse(ggl, program0);
unsigned texels0 [] = {0xffffffff, 0x22222222, 0x66666666, 0xffffffff};
GGLTexture_t texture0 = {GL_TEXTURE_2D, GGL_PIXEL_FORMAT_RGBA_8888,
2, 2, 1, // width, height, levelCount
texels0, GGL_CLAMP_TO_EDGE, GGL_MIRRORED_REPEAT, GGL_LINEAR, GGL_LINEAR
}; // levels, wrapS, wrapT, minFilter, magFilter
int sampler2dLoc = ggl->ShaderUniformLocation(program0, "sampler2d");
if (0 <= sampler2dLoc) {
int samplerUnit = -1;
//ggl->ShaderUniformGetiv(ggl, program0, sampler2dLoc, &samplerUnit);
samplerUnit = sampler2dLoc;
ggl->SetSampler(ggl, samplerUnit, &texture0);
}
Vector4 uVec4 = {1.125f, 1.5f, 1.75f, 1.75f};
int uVec4Loc = ggl->ShaderUniformLocation(program0, "uVec4");
ggl->ShaderUniform(program0, uVec4Loc, 1, &uVec4, GL_FLOAT_VEC4);
VertexInput_t v0 = {0};
v0.attributes[2] = VECTOR4_CTR(0,0,1,1); // aTexCoord
v0.attributes[3] = VECTOR4_CTR(0.25f, 0.25f, 0.5f,1); // aPosition
VertexOutput_t vout0 = {0};
ggl->ProcessVertex(ggl, &v0, &vout0);
if (memcmp(&vout0.position,&v0.attributes[3],sizeof(vout0.position))) {
fprintf(stderr, "gl_Position != aPosition \n");
assert(0);
}
int vTexCoordIndex = ggl->ShaderVaryingLocation(program0, "vTexCoord", NULL) - 2;
VECTOR4_OP_UNARY(vout0.varyings[vTexCoordIndex],-=,uVec4);
if (memcmp(&vout0.varyings[vTexCoordIndex],&v0.attributes[2],sizeof uVec4)) {
fprintf(stderr, "vTexCoord != aTexCoord + uVec4 \n");
assert(0);
}
Vector4 ones = {1,1,1,1};
int vTexColorIndex = ggl->ShaderVaryingLocation(program0, "vTexColor", NULL) - 2;
if (memcmp(&vout0.varyings[vTexColorIndex],&ones,sizeof ones)) { // should be the last texel color
fprintf(stderr, "vTexColor != Vector4(1,1,1,1) \n");
assert(0);
}
if (vout0.pointSize.x != 432) {
fprintf(stderr, "gl_PointSize != 432 \n");
assert(0);
}
v0.attributes[2] = VECTOR4_CTR(0,0, 1.5f, 1.5f);
texture0.wrapS = GGL_REPEAT;
texture0.wrapT = GGL_REPEAT;
sampler2dLoc = ggl->ShaderUniformLocation(program0, "sampler2d");
if (0 <= sampler2dLoc) {
int samplerUnit = -1;
//ggl->ShaderUniformGetiv(ggl, program0, sampler2dLoc, &samplerUnit);
samplerUnit = sampler2dLoc;
ggl->SetSampler(ggl, samplerUnit, &texture0);
}
ggl->ShaderUse(ggl, program0);
ggl->ProcessVertex(ggl, &v0, &vout0);
const float filtered = (float)(0xff + 0x22 + 0x66 + 0xff) / (4 * 0xff);
if (!ApproximatelyEqual(vout0.varyings[vTexColorIndex],
VECTOR4_CTR(filtered, filtered, filtered, filtered), 1.0f / 255)) {
fprintf(stderr, "failed linear filter and/or wrapS and wrapT test");
assert(0);
}
const unsigned width = 60, height = 100;
GGLSurface_t colorSurface = {width, height, GGL_PIXEL_FORMAT_RGBA_8888, malloc(width * height * 4)};
assert(colorSurface.data);
ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, &colorSurface);
GGLSurface_t depthSurface = {width, height, GGL_PIXEL_FORMAT_Z_32, malloc(width * height * 4)};
assert(depthSurface.data);
ggl->SetBuffer(ggl, GL_DEPTH_BUFFER_BIT, &depthSurface);
GGLSurface_t stencilSurface = {width, height, GGL_PIXEL_FORMAT_S_8, malloc(width * height * 1)};
assert(stencilSurface.data);
ggl->SetBuffer(ggl, GL_STENCIL_BUFFER_BIT, &stencilSurface);
ggl->ClearColor(ggl, 0.1f, 0.1f, 0.1f, 1.0f);
ggl->ClearDepthf(ggl, 0.5f);
// TODO DXL test scanline and fs
free(colorSurface.data);
colorSurface.data = NULL;
free(depthSurface.data);
depthSurface.data = NULL;
free(stencilSurface.data);
stencilSurface.data = NULL;
ggl->ShaderProgramDelete(ggl, program0);
puts("*******************");
puts("*** end of test ***");
puts("*******************");
DestroyGGLInterface(ggl);
return 0;
}