// setCounts ensures the draw frame has the most recent number of // verticies and faces. The objects may have been updated after the // draw object was created by the engine. func (m *machine) setCounts(d render.Draw) { if cnts, ok := m.counts[d.Vao()]; ok { d.SetCounts(cnts.faces, cnts.verticies) } else { log.Printf("machine.setCounts: must have mesh counts %d", d.Vao()) } }
// toDraw sets the render data needed for a single draw call. // The data is copied into a render.Draw instance. One of the key jobs // of this method is to put each draw request into a particular // render bucket so that they are drawn in order once sorted. func (sm *scene) toDraw(d render.Draw, p *pov, cam *camera, m *model, rt uint32) { d.SetMv(sm.mv.Mult(p.mm, cam.vm)) // model-view d.SetMvp(sm.mvp.Mult(sm.mv, cam.pm)) // model-view-projection d.SetPm(cam.pm) // projection only. d.SetScale(p.Scale()) d.SetTag(p.eid) // Set the drawing order hints. Overlay trumps transparency since 2D overlay // objects can't be sorted by distance anyways. bucket := render.OPAQUE // used to sort the draw data. Lowest first. switch { case m.castShadow && rt > 0: bucket = render.DEPTH_PASS // pre-passes first. case cam.overlay > 0: bucket = cam.overlay // OVERLAY draw last. case m.alpha < 1: bucket = render.TRANSPARENT // sort and draw after opaque. } depth := cam.depth && m.depth // both must be true for depth rendering. tocam := 0.0 if depth { tocam = p.toc } d.SetHints(bucket, tocam, depth, rt) // use the shadow map texture for models that show shadows. if m.hasShadows { m.UseLayer(sm.shadowMap) } }
// toDraw sets all the data references and uniform data needed // by the rendering layer. func (m *model) toDraw(d render.Draw, eid uint64, depth bool, overlay int, distToCam float64) { d.SetTag(eid) d.SetAlpha(float64(m.alpha)) // 1 : no transparency as the default. // Set the drawing hints. Overlay trumps transparency since 2D overlay // objects can't be sorted by distance anyways. bucket := OPAQUE // used to sort the draw data. Lowest first. switch { case overlay > 0: bucket = overlay // OVERLAY draw last. case m.alpha < 1: bucket = TRANSPARENT // sort and draw after opaque. } depth = depth && m.depth // both must be true for depth rendering. tocam := 0.0 if depth { tocam = distToCam } d.SetHints(bucket, tocam, depth) // Set the drawing references. d.SetRefs(m.shd.program, m.msh.vao, m.drawMode) if total := len(m.texs); total > 0 { for cnt, t := range m.texs { d.SetTex(total, cnt, t.tid, t.f0, t.fn) } } else { d.SetTex(0, 0, 0, 0, 0) // clear any previous data. } // Set uniform values. These can be sent as a reference because they // are fixed on shader creation. d.SetUniforms(m.shd.uniforms) // shader integer uniform references. if m.anm != nil && len(m.pose) > 0 { d.SetPose(m.pose) } else { d.SetPose(nil) // clear data. } d.SetTime(time.Since(m.time).Seconds()) // For shaders that need elapsed time. // Set colour uniforms. d.SetFloats("kd", m.kd.R, m.kd.G, m.kd.B) d.SetFloats("ks", m.ks.R, m.ks.G, m.ks.B) d.SetFloats("ka", m.ka.R, m.ka.G, m.ka.B) // Set user specificed uniforms. for uniform, uvalues := range m.uniforms { d.SetFloats(uniform, uvalues...) } }
// toDraw sets all the data references and uniform data needed // by the rendering layer. func (l *light) toDraw(d render.Draw, px, py, pz float64) { d.SetFloats("l", float32(px), float32(py), float32(pz), 1) d.SetFloats("ld", float32(l.r), float32(l.g), float32(l.b)) }
// toDraw sets the model specific bound data references and // uniform data needed by the rendering layer. func (m *model) toDraw(d render.Draw, mm *lin.M4) { d.SetAlpha(float64(m.alpha)) // 1 : no transparency as the default. // Use any previous render to texture passes. if m.layer != nil { switch m.layer.attr { case render.IMAGE_BUFF: // handled as regular texture below. // Leave it to the shader to use the right the "uv#" uniform. case render.DEPTH_BUFF: d.SetShadowmap(m.layer.tex.tid) // texture with depth values. // Shadow depth bias is the mvp matrix from the light. // It needs to be adjusted to allow shadow maps to work. m.sm.Mult(mm, m.layer.vp) // model (light) view. m.sm.Mult(m.sm, m.layer.bm) // incorporate shadow bias. d.SetDbm(m.sm) } } // Set the bound data references. d.SetRefs(m.shd.program, m.msh.vao, m.drawMode) if total := len(m.texs); total > 0 { for cnt, t := range m.texs { d.SetTex(total, cnt, t.tid, t.f0, t.fn) } } else { d.SetTex(0, 0, 0, 0, 0) // clear any previous data. } // Set uniform values. These can be sent as a reference because they // are fixed on shader creation. d.SetUniforms(m.shd.uniforms) // shader integer uniform references. if m.anm != nil && len(m.pose) > 0 { d.SetPose(m.pose) } else { d.SetPose(nil) // clear data. } d.SetTime(time.Since(m.time).Seconds()) // For shaders that need elapsed time. // Set colour uniforms. d.SetFloats("kd", m.kd.R, m.kd.G, m.kd.B) d.SetFloats("ks", m.ks.R, m.ks.G, m.ks.B) d.SetFloats("ka", m.ka.R, m.ka.G, m.ka.B) // Set user specificed uniforms. for uniform, uvalues := range m.uniforms { d.SetFloats(uniform, uvalues...) } }