// Sh: A GPU metaprogramming language. // // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory // Project administrator: Michael D. McCool // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa, // Michael D. McCool // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must // not claim that you wrote the original software. If you use this // software in a product, an acknowledgment in the product documentation // would be appreciated but is not required. // // 2. Altered source versions must be plainly marked as such, and must // not be misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source // distribution. ////////////////////////////////////////////////////////////////////////////// #include #include #include #include "Shader.hpp" #include "Globals.hpp" #include "LCD.hpp" using namespace SH; LCD::LCD() : Shader("LCD") { } LCD::~LCD() { } template ShAttrib construct(double a, ...) { va_list ap; va_start(ap, a); float args[N]; args[0] = a; for (int i = 1; i < N; i++) { args[i] = va_arg(ap, double); } va_end(ap); return ShAttrib(args); } ShAttrib1f lcd(const ShTexCoord2f& tc, ShAttrib1f number, int intDigits, int fracDigits, bool showgrid, bool handleneg) { float w = 0.2; float h = 0.5; float t = 0.02; float eps = 0.01; ShAttrib<7, SH_CONST> segments[10] = { // TT LT RT CE LB RB BB construct<7>(1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0), // 0 construct<7>(0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0), // 1 construct<7>(1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0), // 2 construct<7>(1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0), // 3 construct<7>(0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0), // 4 construct<7>(1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0), // 5 construct<7>(1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0), // 6 construct<7>(1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0), // 7 construct<7>(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), // 8 construct<7>(1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0)};// 9 ShAttrib<7, SH_CONST> posns[4] = { construct<7>(0.0 , 0.0 , w - t, t , 0.0 , w - t , 0.0), // left construct<7>(w , t , w , w - t , t , w , w ), // right construct<7>(h - t, h/2.0, h/2.0, (h - t)/2.0, 0.0 , 0.0 , 0.0), // bottom construct<7>(h , h , h , (h + t)/2.0, h/2.0, h/2.0 , t )}; // top ShAttrib1f result(0.0f); ShTexCoord2f loc = tc; ShAttrib1f f = floor(loc(0) / (w + t)); ShAttrib1f index = f - intDigits + 1; number = number * pow(10.0, index); loc(0) = loc(0) - f * (w+t); ShAttrib1f digit = floor(number) - floor(number / 10.0f)*10.0f; if (handleneg) { digit = cond(number < 0.0, 9.0 - digit, digit); } // digit = abs(index); // Useful for debugging ShAttrib<7, SH_TEMP> in[4]; in[0] = posns[0] < loc(0); in[1] = posns[1] > loc(0); in[2] = posns[2] < loc(1); in[3] = posns[3] > loc(1); in[0] = in[0] * in[1] * in[2] * in[3]; for (int d = 0; d < 10; d++) { result += (abs(digit - (float)d) < eps) * dot(segments[d], in[0]); } result *= (index < fracDigits + 1 + eps); if (handleneg) { result = cond(index < -0.9 && abs(number/10.0) < 0.1, ShConstAttrib1f(0.0f), result); result = cond(number < 0.0 && index < -0.9 && abs(number/10.0) < 0.1 && abs(number) > 0.1, in[0][3], result); result = cond(number < 0.0 && index > -1.1 && index < -0.9 && abs(number) < 0.1, in[0][3], result); } if (showgrid) { result = result || (dot(fillcast<7>(ShConstAttrib1f(0.1)), in[0]) > 0.0) * 0.2; } return result; } bool LCD::init() { vsh = SH_BEGIN_PROGRAM("gpu:vertex") { ShInputPosition4f ipos; ShInputNormal3f inorm; ShOutputPosition4f opos; // Position in NDC ShOutputNormal3f onorm; ShInOutTexCoord2f tc; // pass through tex coords ShOutputVector3f lightv; // direction to light opos = Globals::mvp | ipos; // Compute NDC position onorm = Globals::mv | inorm; // Compute view-space normal ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position lightv = normalize(Globals::lightPos - posv); // Compute light direction } SH_END; ShAttrib1f SH_DECL(value); value.range(-500.1, 50.1); ShColor3f SH_DECL(background) = ShColor3f(0.69, 0.75, 0.68); ShColor3f SH_DECL(foreground) = ShColor3f(0.18, 0.20, 0.18); ShVector2f SH_DECL(offset) = ShVector2f(0.0, 0.25); ShVector2f SH_DECL(scale) = ShVector2f(1.0, 1.0); scale.range(0.01, 3.0); fsh = SH_BEGIN_PROGRAM("gpu:fragment") { ShInputNormal3f normal; ShInputTexCoord2f tc; // ignore texcoords ShInputVector3f light; ShInputPosition4f posh; ShOutputColor3f result; normal = normalize(normal); light = normalize(light); tc *= scale; tc(1) = 1.0 - tc(1); result = cond(lcd(tc - offset, value), foreground, background); } SH_END; return true; } LCD LCD::instance = LCD();