#include #include #include #include #include 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; }