static void cellToQString( const UCell* val, QString& str ) { switch( ur_type(val) ) { case UT_NONE: str.clear(); break; case UT_CHAR: str = QChar( ur_int(val) ); break; case UT_INT: str.setNum( ur_int(val) ); break; case UT_DECIMAL: str.setNum( ur_decimal(val) ); break; case UT_BIGNUM: str.setNum( bignum_l(val) ); break; case UT_STRING: case UT_FILE: { USeriesIter si; int len; ur_seriesSlice( UT, &si, val ); len = si.end - si.it; switch( si.buf->form ) { case UR_ENC_LATIN1: str = QString::fromLatin1( si.buf->ptr.c + si.it, len ); break; case UR_ENC_UTF8: str = QString::fromUtf8( si.buf->ptr.c + si.it, len ); break; case UR_ENC_UCS2: str = QString::fromUtf16( si.buf->ptr.u16 + si.it, len ); break; } } break; default: { UBuffer buf; ur_strInit( &buf, UR_ENC_LATIN1, 0 ); ur_toStr( UT, val, &buf, 0 ); str = QString::fromLatin1( buf.ptr.c, buf.used ); ur_strFree( &buf ); } break; } }
static int slider_select( GWidget* wp, UAtom atom, UCell* res ) { EX_PTR; if( atom == UR_ATOM_VALUE ) { ur_setId(res, ep->dataType); if( ep->dataType == UT_INT ) ur_int(res) = (int32_t) ep->data.val; else ur_decimal(res) = ep->data.val; return UR_OK; } return gui_areaSelect( wp, atom, res ); }
static void slider_setValue( GSlider* ep, const UCell* cell ) { struct Value* da = &ep->data; float n; if( ur_is(cell, UT_INT) ) n = (float) ur_int(cell); else if( ur_is(cell, UT_DECIMAL) ) n = (float) ur_decimal(cell); else n = 0.0; if( n < da->min ) n = da->min; else if( n > da->max ) n = da->max; da->val = n; }
/* Define the words 'pi and 'e. */ void defineWords( UThread* ut ) { static double constants[2] = { 3.14159265358979, 2.71828182845904 }; UAtom atoms[2]; UBuffer* ctx; UCell* cell; int i; ur_internAtoms( ut, "pi e", atoms ); ctx = ur_threadContext( ut ); for( i = 0; i < 2; ++i ) { cell = ur_ctxAddWord( ctx, atoms[i] ); ur_setId( cell, UT_DECIMAL ); ur_decimal(cell) = constants[i]; } ur_ctxSort( ctx ); }
void setShaderUniforms( const Shader* sh, const UBuffer* blk ) { const ShaderParam* pi = sh->param; const ShaderParam* pend = sh->param + sh->paramCount; const UCell* cval = blk->ptr.cell; int texUnit = 0; #ifdef GL_ES_VERSION_2_0 es_matrixUsed = 0; #endif while( pi != pend ) { // There is no cell type checking or conversion here for speed. // If the user loads bad types then we'll just get garbage. ++cval; switch( pi->type ) { case GL_FLOAT: glUniform1f( pi->location, ur_decimal(cval) ); break; case GL_FLOAT_VEC2: glUniform2fv( pi->location, 1, cval->vec3.xyz ); break; case GL_FLOAT_VEC3: glUniform3fv( pi->location, 1, cval->vec3.xyz ); break; //case GL_FLOAT_VEC4: case GL_INT: case GL_BOOL: glUniform1i( pi->location, ur_int(cval) ); break; case GL_INT_VEC2: glUniform2i( pi->location, cval->coord.n[0], cval->coord.n[1] ); break; case GL_INT_VEC3: glUniform3i( pi->location, cval->coord.n[0], cval->coord.n[1], cval->coord.n[2] ); break; //case GL_INT_VEC4: #ifndef GL_ES_VERSION_2_0 case GL_SAMPLER_1D: glActiveTexture( GL_TEXTURE0 + texUnit ); glEnable( GL_TEXTURE_1D ); glBindTexture( GL_TEXTURE_1D, ur_texId(cval) ); glUniform1i( pi->location, texUnit ); ++texUnit; break; #endif case GL_SAMPLER_2D: #ifndef GL_ES_VERSION_2_0 case GL_SAMPLER_2D_SHADOW: #endif glActiveTexture( GL_TEXTURE0 + texUnit ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, ur_texId(cval) ); glUniform1i( pi->location, texUnit ); ++texUnit; break; //case GL_SAMPLER_3D: #ifdef GL_ES_VERSION_2_0 case GL_FLOAT_MAT4: /* fprintf( stderr, "sha %f,%f,%f\n %f,%f,%f\n %f,%f,%f\n", matrixTop[0], matrixTop[1], matrixTop[2], matrixTop[4], matrixTop[5], matrixTop[6], matrixTop[8], matrixTop[9], matrixTop[10] ); */ es_matrixLoc = pi->location; es_matrixUsed = 1; //glUniformMatrix4fv( pi->location, 1, GL_FALSE, matrixTop ); break; #endif } ++pi; } }
/* Sets res to either a shader! or a context! whose first value is a shader!. Returns UR_OK/UR_THROW. */ int ur_makeShader( UThread* ut, const char* vert, const char* frag, UCell* res ) { #define MAX_SHADER_PARAM 16 // LIMIT: User parameters per shader. Shader shad; Shader* sh; UIndex bufN; UBuffer* buf; int i; char name[ 128 ]; ShaderParam param[ MAX_SHADER_PARAM ]; ShaderParam* pi; GLsizei length; GLint size; GLenum type; GLint count = 0; if( ! createShader( ut, &shad, vert, frag ) ) return UR_THROW; glGetProgramiv( shad.program, GL_ACTIVE_UNIFORMS, &count ); // Collect non-gl parameters. pi = param; for( i = 0; i < count; ++i ) { glGetActiveUniform( shad.program, i, 128, &length, &size, &type, name ); if( name[0] == 'g' && name[1] == 'l' && name[2] == '_' ) continue; pi->type = type; pi->location = glGetUniformLocation( shad.program, name ); pi->name = ur_internAtom( ut, name, name + length ); if( pi->name == UR_INVALID_ATOM ) return UR_THROW; ++pi; } count = pi - param; if( count ) { ShaderParam* pend; UBuffer* ctx; UCell* cval; // We have parameters - make context to hold shader & params. ctx = ur_makeContextCell( ut, count + 1, res ); cval = ur_ctxAddWord( ctx, UR_ATOM_SHADER ); pi = param; pend = param + count; while( pi != pend ) { cval = ur_ctxAddWord( ctx, pi->name ); #if 0 printf( "KR Shader Param %d is type %d\n", (int) (pi - param), pi->type ); #endif switch( pi->type ) { case GL_FLOAT: ur_setId( cval, UT_DECIMAL ); ur_decimal( cval ) = 0.0; break; case GL_FLOAT_VEC2: case GL_FLOAT_VEC3: //case GL_FLOAT_VEC4: ur_setId( cval, UT_VEC3 ); cval->vec3.xyz[0] = cval->vec3.xyz[1] = cval->vec3.xyz[2] = 0.0f; break; case GL_INT: ur_setId( cval, UT_INT ); ur_int( cval ) = 0; break; case GL_INT_VEC2: case GL_INT_VEC3: //case GL_INT_VEC4: ur_setId( cval, UT_COORD ); break; case GL_BOOL: ur_setId( cval, UT_LOGIC ); ur_int( cval ) = 0; break; case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: #ifndef GL_ES_VERSION_2_0 case GL_SAMPLER_1D: case GL_SAMPLER_3D: case GL_SAMPLER_1D_SHADOW: case GL_SAMPLER_2D_SHADOW: #endif ur_setId( cval, UT_NONE ); ur_texId(cval) = 0; // Expecting texture!. break; #ifdef GL_ES_VERSION_2_0 case GL_FLOAT_MAT4: ur_setId( cval, UT_NONE ); break; #endif default: ur_setId( cval, UT_NONE ); break; /* GL_BOOL_VEC2: GL_BOOL_VEC3: GL_BOOL_VEC4: GL_FLOAT_MAT2: GL_FLOAT_MAT3: GL_FLOAT_MAT4: GL_SAMPLER_2D_RECT: GL_SAMPLER_2D_RECT_SHADOW: */ } ++pi; } ur_ctxSort( ctx ); } ur_genBuffers( ut, 1, &bufN ); buf = ur_buffer( bufN ); buf->type = UT_SHADER; buf->ptr.v = memAlloc( sizeof(Shader) + sizeof(ShaderParam) * (count - 1) ); sh = (Shader*) buf->ptr.v; sh->program = shad.program; sh->paramCount = count; if( count ) { memCpy( sh->param, param, sizeof(ShaderParam) * count ); // First context value will be set to shader!. res = ur_buffer( res->series.buf )->ptr.cell; } ur_setId( res, UT_SHADER ); ur_setSeries( res, bufN, 0 ); return UR_OK; }
/* Recursively evaluate math expression. \param cell Cell to evaluate. \param res Result. \return UR_OK or UR_THROW. */ int calc_eval( UThread* ut, UCell* cell, double* res ) { switch( ur_type(cell) ) { case UT_WORD: { const UCell* val = ur_wordCell( ut, cell ); if( ! val ) return UR_THROW; if( ur_is(val, UT_DECIMAL) ) *res = ur_decimal(val); else if( ur_is(val, UT_INT) || ur_is(val, UT_CHAR) ) *res = (double) ur_int(val); else { return ur_error( ut, UR_ERR_SCRIPT, "Invalid word '%s", ur_wordCStr( cell ) ); } } break; case UT_DECIMAL: *res = ur_decimal(cell); break; case UT_INT: case UT_CHAR: *res = (double) ur_int(cell); break; case UT_BLOCK: case UT_PAREN: { UBlockIterM bi; double num = 0.0; double right; #define RIGHT_VAL \ if( ++bi.it == bi.end ) \ return ur_error( ut, UR_ERR_SCRIPT, "Expected operator r-value" ); \ if( ! calc_eval( ut, bi.it, &right ) ) \ return UR_THROW; if( ! ur_blkSliceM( ut, &bi, cell ) ) return UR_THROW; ur_foreach( bi ) { if( ur_is(bi.it, UT_WORD) ) { switch( ur_atom(bi.it) ) { case UR_ATOM_PLUS: RIGHT_VAL num += right; break; case UR_ATOM_MINUS: RIGHT_VAL num -= right; break; case UR_ATOM_ASTERISK: RIGHT_VAL num *= right; break; case UR_ATOM_SLASH: RIGHT_VAL num /= right; break; default: if( ! calc_eval( ut, bi.it, &num ) ) return UR_THROW; } } else if( ur_is(bi.it, UT_SETWORD) ) { cell = ur_wordCellM( ut, bi.it ); if( ! cell ) return UR_THROW; ur_setId( cell, UT_DECIMAL ); ur_decimal(cell) = num; } else { if( ! calc_eval( ut, bi.it, &num ) ) return UR_THROW; } } *res = num; } break; default: *res = 0.0; break; } return UR_OK; }