func (me *uberShaders) setShaderSourceEnsureFunc(op *FxProc, fn *uberShaderFunc, srcBody *ustr.Buffer, inputs map[string]bool) error { var ( str, _procID_ string parts []string df *uberShaderFunc ) isFxOp := strings.HasPrefix(fn.name, "fx_") && op != nil if isFxOp { _procID_ = "_" + op.procID + "_" } rewriteUnis := map[string]string{} for _, str = range fn.allInputs { if isFxOp && strings.HasPrefix(str, "uni_") && strings.Contains(str, _procID_) { parts = strings.Split(str, "_") rewriteUnis[str] = op.unifName(parts[1], parts[3]) str = rewriteUnis[str] } inputs[str] = true } for _, str = range fn.dependsOn { if isFxOp && strings.HasPrefix(str, "fx_") { return errf("%s depends on %s. One fx_ func must not depend directly on another.", fn.name, str) } for _, m := range me.allMaps() { if df = (*m)[str]; df != nil { break } } if df == nil { return errf(str) } me.setShaderSourceEnsureFunc(nil, df, srcBody, inputs) } str = fn.rawSrc if isFxOp { str = strings.Replace(str, fn.name, strf("%s%d", fn.name, op.procIndex), -1) for k, v := range rewriteUnis { str = strings.Replace(str, k, v, -1) } } srcBody.Writeln(str + "\n") return nil }
func (me *FxEffect) UpdateRoutine() { var ( i, tc int buf ustr.Buffer rt string ) if len(me.KeepProcIDsLast) > 0 { me.FxProcs.EnsureLast(me.KeepProcIDsLast...) me.ext.EnsureLast(me.KeepProcIDsLast...) } ops, ext, counts := me.FxProcs, len(me.ext) > 0, make(map[string]int, len(me.FxProcs)+len(me.ext)) doOps: for o := 0; o < len(ops); o++ { if ops[o].Enabled { buf.Write("_%s", ops[o].procID) i = counts[ops[o].procID] ops[o].setProcIndex(i) counts[ops[o].procID] = i + 1 if ops[o].IsTex() { tc++ } } } if ext { ext, ops = false, me.ext goto doOps } me.uberName = buf.String() for rt, _ = range Core.Render.KnownTechniques { me.uberPnames[rt] = strf("uber_%s%s", rt, me.uberName) } thrRend.curEffect = nil if tc > Stats.Programs.maxTexUnits { Stats.Programs.maxTexUnits = tc } }
func makeEmbeds(srcDirPath string) { defer wait.Done() filePath := filepath.Join(srcDirPath, "splash.png") var buf ustr.Buffer buf.Writeln("\t//\tEmbedded binary from %s", filePath) if raw := ufs.ReadBinaryFile(filePath, true); len(raw) > 0 { if strings.HasSuffix(filePath, ".png") { if src, _, err := image.Decode(bytes.NewReader(raw)); err == nil { dst, _ := ugfx.CreateLike(src, false) ugfx.PreprocessImage(src, dst, true, true, true) w := new(bytes.Buffer) png.Encode(w, dst) raw = w.Bytes() } else { panic(err) } } if len(raw) > 0 { buf.Writeln("\tCore.Libs.Images.SplashScreen.InitFrom.RawData = %#v", raw) } } newSrc.embeds = buf.String() }
func (me *uberShaders) setShaderSourceVert(job *uberShaderJob, vertTech string, varyings map[string]bool) (vertSrc string, err error) { var ( i int srcBody, srcHead ustr.Buffer shFunc *uberShaderFunc inout, fname string outputs = []string{"gl_Position"} inputs = map[string]bool{} ) for inout, _ = range varyings { if inout[:4] == "var_" { outputs = append(outputs, inout) } } for i, inout = range outputs { if fname = "vx_" + vertTech + "_" + inout; i > 0 { srcHead.Writeln("%sout %s %s;", job.quals[inout], me.inoutTypeSpec(inout), inout) } if shFunc = me.allFuncs.vertex[fname]; shFunc == nil { err = errf("uberShader.setShaderSourceVert('%s') -- unknown vertex func '%s'", job.pname, fname) return } me.setShaderSourceEnsureFunc(nil, shFunc, &srcBody, inputs) } for inout, _ = range inputs { switch inout[:4] { case "att_": uslice.StrAppendUnique(&job.progAtts, inout) srcHead.Writeln("in %s %s;", me.inoutTypeSpec(inout), inout) case "uni_": uslice.StrAppendUnique(&job.progUnis, inout) srcHead.Writeln("uniform %s %s;", me.inoutTypeSpec(inout), inout) } } srcBody.Writeln("void main () {") for _, inout = range outputs { srcBody.Writeln("\t%s = vx_%s_%s();", inout, vertTech, inout) } srcBody.Writeln("}") vertSrc = srcHead.String() + "\n" + srcBody.String() return }
func (me *uberShaders) setShaderSourceFrag(job *uberShaderJob, fx *FxEffect, inputs map[string]bool) (fragSrc string, err error) { var ( srcBody, srcHead ustr.Buffer i int shid string op *FxProc ops FxProcs shFunc *uberShaderFunc ) srcHead.Writeln("out vec3 out_Color;") allOps := []FxProcs{fx.FxProcs, fx.ext} for _, ops = range allOps { for i = 0; i < len(ops); i++ { if op = &ops[i]; op.Enabled { if shid = Core.Render.Fx.procFuncs[op.procID]; len(shid) == 0 { err = errf("uberShader.setShaderSourceFrag('%s') -- unknown fxProc ID '%s'", job.pname, op.procID) return } if shFunc = me.allFuncs.fragment[shid]; shFunc == nil { err = errf("uberShader.setShaderSourceFrag('%s') -- unknown fragment func '%s'", job.pname, shid) return } me.setShaderSourceEnsureFunc(op, shFunc, &srcBody, inputs) inputs[op.unifName("float", "MixWeight")] = true for shid, _ = range inputs { if job.quals[shid] = op.qualifiers(shid); len(job.quals[shid]) > 0 { job.quals[shid] = job.quals[shid] + " " } } } } } for shid, _ = range inputs { switch shid[:4] { case "uni_": uslice.StrAppendUnique(&job.progUnis, shid) srcHead.Writeln("uniform %s %s;", me.inoutTypeSpec(shid), shid) case "var_": srcHead.Writeln("%sin %s %s;", job.quals[shid], me.inoutTypeSpec(shid), shid) } } srcBody.Writeln("void main () {") srcBody.Writeln("\tvec3 vCol = vec3(0);") for _, ops = range allOps { for i = 0; i < len(ops); i++ { if op = &ops[i]; op.Enabled { shFunc = me.allFuncs.fragment[Core.Render.Fx.procFuncs[op.procID]] srcBody.Writeln("\tvCol = mix(vCol, %s%d(vCol), %s);", shFunc.name, op.procIndex, op.unifName("float", "MixWeight")) } } } srcBody.Writeln("\tout_Color = vCol;") srcBody.Writeln("}") fragSrc = srcHead.String() + "\n" + srcBody.String() return }
func generateShadersSource(srcDirPath string, stripComments bool) (err error, newSrc string) { var ( shaderSource shaderSrc shaderName, tmpSrc string srcBuf ustr.Buffer ) srcBuf.Writeln("\togl.progs.Init()\n\togl.uber.init()") allShaders := shaderSrcSortables{shaderSrcSortable{}, shaderSrcSortable{}, shaderSrcSortable{}, shaderSrcSortable{}, shaderSrcSortable{}, shaderSrcSortable{}} incShaders := map[string]string{} collectShaders(srcDirPath, &allShaders, incShaders, stripComments) sort.Sort(allShaders.comp) sort.Sort(allShaders.frag) sort.Sort(allShaders.geo) sort.Sort(allShaders.tessCtl) sort.Sort(allShaders.tessEval) sort.Sort(allShaders.vert) allNames := map[string]bool{} for varName, shaderSrcItem := range allShaders.mapAll() { for _, shaderSource = range shaderSrcItem { if shaderName = shaderSource.name[:strings.LastIndex(shaderSource.name, ".")]; !allNames[shaderName] { srcBuf.Writeln("\togl.progs.AddNew(%#v)", shaderName) allNames[shaderName] = true } srcBuf.Writeln("\togl.progs.Get(%#v).Sources.In.%s = %#v", shaderName, varName, includeShaders(shaderSource.name, shaderSource.src, incShaders)) } } for shaderName, tmpSrc = range incShaders { srcBuf.Writeln("\togl.uber.rawSources[%#v] = %#v", shaderName[:strings.Index(shaderName, ".")], tmpSrc) } newSrc = srcBuf.String() return }