GLShader::GLShader(const GLchar** vertex_shader, GLuint line, const GLchar** fragment_shader, GLuint line2): _success_code(0) { GLchar* _buffer; _buffer = _make_source(vertex_shader, line); printf("vertex source is: %s\n", _buffer); _vertex_shader = glCreateShader(GL_VERTEX_SHADER); _compile(_buffer, _vertex_shader); delete []_buffer; if (!_success_code) { return; } _buffer = _make_source(fragment_shader, line2); printf("fragment source is: %s\n", _buffer); _fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); _compile(_buffer, _fragment_shader); delete []_buffer; if (!_success_code) { return; } }
int init_column_analysis() { const int FLAGS = REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE; if( _compile( _pattern_NA, &_compiled_re_NA, FLAGS ) ) return -1; #ifdef HAVE_BOOLEAN_DETECTION if( _compile( _pattern_BOOL, &_compiled_re_BOOL, FLAGS ) ) return -1; #endif read_environment_overrides(); return 0; }
//----------------------------------------------------------------------- void CompositorChain::preViewportUpdate(const RenderTargetViewportEvent& evt) { // Only set up if there is at least one compositor enabled, and it's this viewport if(evt.source != mViewport || !mAnyCompositorsEnabled) return; // set original scene details from viewport CompositionPass* pass = mOriginalScene->getTechnique()->getOutputTargetPass()->getPass(0); CompositionTargetPass* passParent = pass->getParent(); if (pass->getClearBuffers() != mViewport->getClearBuffers() || pass->getClearColour() != mViewport->getBackgroundColour() || passParent->getVisibilityMask() != mViewport->getVisibilityMask() || passParent->getMaterialScheme() != mViewport->getMaterialScheme() || passParent->getShadowsEnabled() != mViewport->getShadowsEnabled()) { // recompile if viewport settings are different pass->setClearBuffers(mViewport->getClearBuffers()); pass->setClearColour(mViewport->getBackgroundColour()); passParent->setVisibilityMask(mViewport->getVisibilityMask()); passParent->setMaterialScheme(mViewport->getMaterialScheme()); passParent->setShadowsEnabled(mViewport->getShadowsEnabled()); _compile(); } Camera *cam = mViewport->getCamera(); if (cam) { /// Prepare for output operation preTargetOperation(mOutputOperation, mViewport, cam); } }
Filter* compile(Filter *f) { if(f == nil) return f; /* fill in the missing header filters */ f = complete(f, nil); /* constant folding */ f = optimize(f); if(!toflag) printfilter(f, "after optimize"); /* protocol specific compilations */ _compile(f, nil); /* at this point, the root had better be the root proto */ if(findbogus(f)){ fprint(2, "bogus filter\n"); exits("bad filter"); } return f; }
GLShader::GLShader(const GLchar* vertexPath, const GLchar* fragmentPath) { // 1. Retrieve the vertex/fragment source code from filePath std::string vertexCode; std::string fragmentCode; std::ifstream vShaderFile; std::ifstream fShaderFile; // ensures ifstream objects can throw exceptions: vShaderFile.exceptions(std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::badbit); try { // Open files vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); std::stringstream vShaderStream, fShaderStream; // Read file's buffer contents into streams vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); // close file handlers vShaderFile.close(); fShaderFile.close(); // Convert stream into GLchar array vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch(std::ifstream::failure e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; } const GLchar* _buffer = vertexCode.c_str(); printf("vertex source is: %s\n", _buffer); _vertex_shader = glCreateShader(GL_VERTEX_SHADER); _compile(_buffer, _vertex_shader); if (!_success_code) { return; } _buffer = fragmentCode.c_str(); printf("fragment source is: %s\n", _buffer); _fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); _compile(_buffer, _fragment_shader); if (!_success_code) { return; } }
void Shader::compile() { if (shader != 0) return; for (std::list<Ptr>::const_iterator i = dependencies.begin(), e = dependencies.end(); i != e; ++i) { (*i)->compile(); } _compile(); }
InstructionList compile(Expression *expr) { InstructionList ilist(10); Expression *root = new Expression(strdup("root"), expr, new Expression(0)); initialize(); _compile(ilist, root, 0); cout << "Generated compiled code:" << endl; cout << ilist << endl; return ilist; }
void Shader::_attachTo(GLuint program, bool compile) { if (tag == s_tag) return; tag = s_tag; for (std::list<Ptr>::const_iterator i = dependencies.begin(), e = dependencies.end(); i != e; ++i) { (*i)->_attachTo(program, compile); } if (compile && shader == 0) _compile(); if (shader != 0) { glAttachObjectARB(program, shader); } }
/* * compile the filter */ static void _compile(Filter *f, Proto *last) { if(f == nil) return; switch(f->op){ case '!': _compile(f->l, last); break; case LOR: case LAND: _compile(f->l, last); _compile(f->r, last); break; case WORD: if(last != nil){ if(last->compile == nil) sysfatal("unknown %s subprotocol: %s", f->pr->name, f->s); (*last->compile)(f); } if(f->l) _compile(f->l, f->pr); break; case '=': if(last == nil) sysfatal("internal error: compilewalk: badly formed tree"); if(last->compile == nil) sysfatal("unknown %s field: %s", f->pr->name, f->s); (*last->compile)(f); break; default: sysfatal("internal error: compilewalk op: %d", f->op); } }
void CombinerInfo::setCombine(uint64_t _mux ) { if (m_pCurrent != NULL && m_pCurrent->getMux() == _mux) { m_bChanged = false; m_pCurrent->update(false); return; } Combiners::const_iterator iter = m_combiners.find(_mux); if (iter != m_combiners.end()) { m_pCurrent = iter->second; m_pCurrent->update(false); } else { m_pCurrent = _compile(_mux); m_pCurrent->update(true); m_pUniformCollection->bindWithShaderCombiner(m_pCurrent); m_combiners[_mux] = m_pCurrent; } m_bChanged = true; }
void CombinerInfo::setCombine(u64 _mux ) { const u64 key = getCombinerKey(_mux); if (m_pCurrent != nullptr && m_pCurrent->getKey() == key) { m_bChanged = false; m_pCurrent->update(false); return; } Combiners::const_iterator iter = m_combiners.find(key); if (iter != m_combiners.end()) { m_pCurrent = iter->second; m_pCurrent->update(false); } else { m_pCurrent = _compile(_mux); m_pCurrent->update(true); m_pUniformCollection->bindWithShaderCombiner(m_pCurrent); m_combiners[m_pCurrent->getKey()] = m_pCurrent; } m_bChanged = true; }
//----------------------------------------------------------------------- void CompositorChain::preRenderTargetUpdate(const RenderTargetEvent& evt) { /// Compile if state is dirty if(mDirty) _compile(); // Do nothing if no compositors enabled if (!mAnyCompositorsEnabled) { return; } /// Update dependent render targets; this is done in the preRenderTarget /// and not the preViewportUpdate for a reason: at this time, the /// target Rendertarget will not yet have been set as current. /// ( RenderSystem::setViewport(...) ) if it would have been, the rendering /// order would be screwed up and problems would arise with copying rendertextures. Camera *cam = mViewport->getCamera(); if (!cam) { return; } cam->getSceneManager()->_setActiveCompositorChain(this); /// Iterate over compiled state CompositorInstance::CompiledState::iterator i; for(i=mCompiledState.begin(); i!=mCompiledState.end(); ++i) { /// Skip if this is a target that should only be initialised initially if(i->onlyInitial && i->hasBeenRendered) continue; i->hasBeenRendered = true; /// Setup and render preTargetOperation(*i, i->target->getViewport(0), cam); i->target->update(); postTargetOperation(*i, i->target->getViewport(0), cam); } }
static void _compile(InstructionList &insts, Expression *expr, unsigned ecnt) { cout << "Compiling: " << expr << endl; if (expr->is_binary()){ _compile(insts, expr->expr1, ecnt); _compile(insts, expr->expr2, ecnt); } if (expr->is_unary()) _compile(insts, expr->unary, ecnt); switch (expr->t) { // primitives case Expression::INT: { insts.append(Instruction::_push(expr->ival)); break; } case Expression::FLOAT: insts.append(Instruction::_push(expr->fval)); break; case Expression::CHAR: insts.append(Instruction::_push(expr->cval)); break; case Expression::STRING: insts.append(Instruction::_push(expr->strval)); break; case Expression::BOOL: insts.append(Instruction::_push(expr->bval, Primitive::BOOL)); break; case Expression::VAR: { if (expr->type) { int i = arg_num(*expr->name); insts.append(Instruction::_pusharg(i)); } else { SymbolInfo res = lookup(*expr->name); if (res.s != SymbolInfo::OK) { char buf[250]; sprintf(buf, "Error: %s has no type and is not defined " "in this scope", expr->name->c_str()); throw string(buf); } // then it's a function, we need to call it... this needs work! unsigned unr = res.expr->unresolved(); insts.append(Instruction::_call(new string(res.full_name), unr)); } break; } case Expression::INVOKE: // this should really be the same as a variable! { for (unsigned i = 0; i < expr->expr_list->size(); ++i) { _compile(insts, (*expr->expr_list)[i], ecnt); } //if this expression is a variable, we can just call it if (expr->func->t == Expression::VAR) { SymbolInfo info = lookup(*expr->func->name); insts.append(Instruction::_call(new string(info.full_name), expr->expr_list->size())); //otherwise, we have a lamba so we need to create an anonymous context } else { char lbl[100]; sprintf(lbl, "$%d", ecnt); string *lblname = new string(name_stack.render() + lbl); insts.append(Instruction::_call(lblname, expr->expr_list->size())); insts.append(Instruction::_label(lblname)); _compile(insts, expr->func, ecnt + 1); } break; } // logical flow case Expression::IF: { _compile(insts, expr->cond, ecnt); char lbl[100]; sprintf(lbl, "$%d", ecnt); name_stack.push(lbl); insts.append(Instruction::_elsegoto(new string(name_stack.render()))); _compile(insts, expr->if_true, ecnt); insts.append(Instruction::_label(new string(name_stack.render()))); _compile(insts, expr->if_false, ecnt + 1); break; } case Expression::ASSIGN: { cout << "Assignment! current expression: " << expr << endl; cout << "current namespace is '" << name_stack.render() << "'" << endl; name_stack.push(*expr->vname); Expression *content = expr->right_hand; cout << "lhs: " << *expr->vname << " rhs: " << expr->right_hand << endl; store(*expr->vname, name_stack.render(), expr->right_hand); // compile all of the sub-assignments cout << "searching for the first non-assignment within " << *expr->vname << endl; if (content->t == Expression::ASSIGN) { _compile(insts, content, 0); content = content->next; } cout << "found first non-assignment within "<< *expr->vname << ", which is: " << content << endl; // make a label for the function name cout << "appending a label " << name_stack.render() << endl; insts.append(Instruction::_label(new string(name_stack.render()))); name_stack.pop(); // compile the instructions for the right-hand of this assignment _compile(insts, content, 0); insts.append(Instruction::_return(1)); _compile(insts, expr->next, 0); break; } // arithmetic case Expression::ADD: { insts.append(Instruction::_add()); break; } case Expression::SUB: { insts.append(Instruction::_sub()); break; } case Expression::MULT: { insts.append(Instruction::_mult()); break; } case Expression::DIV: { insts.append(Instruction::_div()); break; } case Expression::MOD: { insts.append(Instruction::_mod()); break; } case Expression::EXP: { insts.append(Instruction::_exp()); break; } case Expression::EQ: { insts.append(Instruction::_eq()); break; } case Expression::NEQ: { insts.append(Instruction::_neq()); break; } case Expression::LT: { insts.append(Instruction::_lt()); break; } case Expression::GT: { insts.append(Instruction::_gt()); break; } case Expression::LEQ: { insts.append(Instruction::_leq()); break; } case Expression::GEQ: { insts.append(Instruction::_geq()); break; } case Expression::LOG_AND: { insts.append(Instruction::_and()); break; } case Expression::LOG_OR: { insts.append(Instruction::_or()); break; } case Expression::LOG_NOT: { insts.append(Instruction::_not()); break; } case Expression::NEG: { insts.append(Instruction::_neg()); break; } case Expression::UNRESOLVED: throw string("why are we seeing unresolved variables?"); // default: case Expression::BIT_AND: case Expression::BIT_OR: case Expression::BIT_XOR: case Expression::BIT_NOT: throw string("we can't handle this stuff yet!"); } }
// Internal helper function for the compilation // This is where the actual compilation is done. // It is done recursivly for each parenthesis. int Expression::_compile(int start, Vector<Token>& tokens, Vector<Token>& rpn) { int i; Stack<eTokenType> opStack; eTokenType lastTok = NONE; for(i = start; i < tokens.size(); i++) { if(tokens[i].type == RPAREN) break; switch(tokens[i].type) { case PLUS: case MINUS: // do some simple optimizations of the // expression (instead of having unary // operations for these kind of series) if(lastTok==MINUS) { if(tokens[i].type==MINUS) { opStack.pop(); opStack.push(PLUS); break; } } else if(lastTok==PLUS) { if(tokens[i].type==MINUS) { opStack.pop(); opStack.push(MINUS); break; } } else { // if next token is a number and this // token is a minus (unary) then just negate the number if( i+1<tokens.size() && IS_EVALUATABLE_LEFT(tokens[i+1].type) && !(IS_EVALUATABLE_RIGHT(lastTok)) && tokens[i].type == MINUS) { opStack.push(MINUS); rpn.add(Token(NUMBER, 0.0)); break; } } case DIV: case MUL: // just push the operator on the operator stack. opStack.push(tokens[i].type); break; case LPAREN: case FUNCTION: case VARIABLE: case NUMBER: // if we found a left parenthesis lets recurse into it and increment our // index with the amount of tokens that has been parsed through the // recursion. Else just add the number to the rpn expression. if(tokens[i].type==LPAREN||tokens[i].type==FUNCTION) { if(tokens[i].type==FUNCTION) { int last_i = i; i+=_compile(i+1, tokens, rpn)+1; rpn.add(tokens[last_i]); } else { i+=_compile(i+1, tokens, rpn)+1; } } else { rpn.add(tokens[i]); } // if our operator stack isn't empty lets peek the last operator // and see if it is time to add it to the rpn (according to predecence) if(!opStack.empty()) { eTokenType lastOp = opStack.peek(); eTokenType nextOp = NONE; if(i+1<tokens.size()) nextOp = tokens[i+1].type; if((lastOp == PLUS || lastOp == MINUS) && (nextOp == PLUS || nextOp == MINUS || nextOp == RPAREN || nextOp == NONE)) { rpn.add(Token(lastOp)); opStack.pop(); } else if((lastOp == MUL || lastOp == DIV)) { rpn.add(Token(lastOp)); opStack.pop(); if(nextOp == PLUS || nextOp == MINUS || nextOp == RPAREN || nextOp == NONE) { // nothing has lower predecence than these operators so just empty // the operator stack and add the operators to the rpn expression while(opStack.empty()!=true) { rpn.add(Token(opStack.peek())); opStack.pop(); } } } } break; case RPAREN: case END: case NONE: ; // do nothing } lastTok = tokens[i].type; } // add the remaining operators to the rpn expression while(opStack.empty()!=true) { rpn.add(Token(opStack.peek())); opStack.pop(); } return i-start; }
// this function takes a string containing an arithmetic // expression in infix notation and compiles it into an // internal reverse polish notation representation. // which can then easily be evaluated (and re-evaluated) // This is done by first tokenizing the string // and then parse the tokens, converting // the infix notation to rpn. bool Expression::compile(const char *string) { const char *src = string; Vector<Token> tokens; // tokenize it and parse and convert numbers. while(*src) { if(IS_WHITESPACE(*src)) { src++; continue; } switch(*src) { case '(': tokens.add(Token(LPAREN)); break; case ')': tokens.add(Token(RPAREN)); break; case '-': tokens.add(Token(MINUS)); break; case '+': tokens.add(Token(PLUS)); break; case '*': tokens.add(Token(MUL)); break; case '/': tokens.add(Token(DIV)); break; default: if(IS_NUMBER(*src)) { char num[32]; num[0] = *src; src++; char *num_dest = num+1; int numDots = 0; while(IS_NUMBER(*src)||*src=='.') { if(*src=='.') { numDots++; if(numDots>1) { // error printf("wrong amount of dots in constant number."); return false; } } *num_dest = *src; num_dest++; src++; } *num_dest = 0; float i = atof(num); tokens.add(Token(NUMBER, i)); continue; } else if(IS_LETTER(*src)) { char litteral[255]; litteral[0] = *src; src++; char *litteral_dest = litteral+1; while(IS_LETTER(*src)||IS_NUMBER(*src)) { *litteral_dest = *src; litteral_dest++; src++; } *litteral_dest = 0; while(IS_WHITESPACE(*src)) src++; if(*src=='(') { tokens.add(Token(FUNCTION, scope.getFunction(litteral))); src++; } else { tokens.add(Token(VARIABLE, scope.getVariable(litteral))); } continue; } else return false; } src++; } // compile! this is done recursivly rpn.clear(); _compile(0, tokens, rpn); rpn.add(Token(END)); return true; }
char * compile(const char *sp, char *ep, char *endbuf) { return (_compile(sp, ep, endbuf, 0)); }