| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609 |
- package gui
- import (
- "fmt"
- "github.com/g3n/engine/core"
- "github.com/g3n/engine/geometry"
- "github.com/g3n/engine/gls"
- "github.com/g3n/engine/graphic"
- "github.com/g3n/engine/material"
- "github.com/g3n/engine/math32"
- "github.com/g3n/engine/renderer/shader"
- )
- func init() {
- shader.AddShader("shaderChartVertex", shaderChartVertex)
- shader.AddShader("shaderChartFrag", shaderChartFrag)
- shader.AddProgram("shaderChart", "shaderChartVertex", "shaderChartFrag")
- }
- // ChartLine implements a panel which can contain several line charts
- type ChartLine struct {
- Panel // Embedded panel
- title *Label // Optional title
- baseX float32 // NDC x coordinate for y axis
- baseY float32 // NDC y coordinate for x axis
- scaleX *ChartScaleX // X scale objet
- firstX float32 // First value for X label
- stepX float32 // Step value for X label
- formatX string // Format for X labels
- //scaleY *ChartScaleY // Y scale objet
- //graphs []*LineGraph // Array of line graphs
- }
- // NewChartLine creates and returns a new line chart panel with
- // the specified dimensions in pixels.
- func NewChartLine(width, height float32) *ChartLine {
- cl := new(ChartLine)
- cl.Panel.Initialize(width, height)
- cl.baseX = 0.1
- cl.baseY = -0.9
- cl.firstX = 0.0
- cl.stepX = 1.0
- cl.formatX = "%2.1f"
- return cl
- }
- func (cl *ChartLine) SetTitle(title *Label) {
- cl.title = title
- if cl.title != nil {
- cl.Add(cl.title)
- } else {
- cl.Remove(cl.title)
- }
- if cl.scaleX != nil {
- cl.scaleX.recalc()
- }
- }
- // SetScaleX sets the line chart x scale number of lines and color
- func (cl *ChartLine) SetScaleX(lines int, color *math32.Color) {
- if cl.scaleX != nil {
- cl.Remove(cl.scaleX)
- cl.scaleX.Dispose()
- }
- cl.scaleX = newChartScaleX(cl, lines, color)
- cl.Add(cl.scaleX)
- }
- //// SetScaleY sets the line chart y scale number of lines and color
- //func (cl *ChartLine) SetScaleY(lines int, color *math32.Color) {
- //
- // if cl.scaleY != nil {
- // cl.Node.Remove(cl.scaleY)
- // cl.scaleY.Dispose()
- // }
- // cl.scaleY = newChartScaleY(cl, lines, color)
- // cl.Node.Add(cl.scaleY)
- //}
- //
- //// AddLine adds a line graph to the chart
- //func (cl *ChartLine) AddGraph(name, title string, color *math32.Color, data []float32) {
- //
- // graph := newLineGraph(&cl.Panel, name, title, color, data)
- // cl.graphs = append(cl.graphs, graph)
- // cl.Node.Add(graph)
- //}
- /*
- ChartScaleX is a panel with LINE geometry which draws the chart X horizontal scale axis,
- vertical lines and line labels.
- | |
- | |
- | |
- | |
- +-----+------------------
- L L
- */
- type ChartScaleX struct {
- Panel
- chart *ChartLine // Container chart
- }
- //func NewChartScaleX(width, height float32, lines int, color *math32.Color) *ChartScaleX {
- //
- // sx := new(ChartScaleX)
- // baseY := float32(-0.9)
- //
- // // Generates grid lines using Normalized Device Coordinates and
- // // considering that the parent panel model coordinates are:
- // // 0,0,0 1,0,0
- // // +---------------+
- // // | |
- // // | |
- // // +---------------+
- // // 0,-1,0 1,-1,0
- // positions := math32.NewArrayF32(0, 0)
- // // Appends scaleX bottom horizontal base line
- // positions.Append(
- // 0, baseY, 0, color.R, color.G, color.B, // line start vertex and color
- // 1, baseY, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // // Appends scale X vertical lines
- // step := 1 / (float32(lines) + 1)
- // for i := 1; i < lines+1; i++ {
- // nx := float32(i) * step
- // positions.Append(
- // nx, 0, 0, color.R, color.G, color.B, // line start vertex and color
- // nx, baseY, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // //l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
- // //px, py := ndc2pix(&sx.chart.Panel, nx, chart.baseY)
- // //log.Error("label px:%v py:%v", px, py)
- // //l.SetPosition(px, py)
- // //sx.Add(l)
- // }
- //
- // // Creates geometry using one interlaced VBO
- // geom := geometry.NewGeometry()
- // geom.AddVBO(gls.NewVBO().
- // AddAttrib("VertexPosition", 3).
- // AddAttrib("VertexColor", 3).
- // SetBuffer(positions),
- // )
- //
- // // Creates material
- // mat := material.NewMaterial()
- // mat.SetLineWidth(1.0)
- // mat.SetShader("shaderChart")
- //
- // sx.Panel.InitializeGraphic(width, height, geom, mat, gls.LINES)
- // sx.SetBounded(true)
- //
- // l2 := NewLabel("LABEL......")
- // l2.SetPosition(10, 10)
- // sx.Panel.Add(l2)
- // log.Error("sx children:%v", sx.Children())
- // return sx
- //}
- func newChartScaleX(chart *ChartLine, lines int, color *math32.Color) *ChartScaleX {
- sx := new(ChartScaleX)
- sx.chart = chart
- // Generates grid lines using Normalized Device Coordinates and
- // considering that the parent panel model coordinates are:
- // 0,0,0 1,0,0
- // +---------------+
- // | |
- // | |
- // +---------------+
- // 0,-1,0 1,-1,0
- positions := math32.NewArrayF32(0, 0)
- // Appends scaleX bottom horizontal base line
- positions.Append(
- 0, chart.baseY, 0, color.R, color.G, color.B, // line start vertex and color
- 1, chart.baseY, 0, color.R, color.G, color.B, // line end vertex and color
- )
- // Appends scale X vertical lines
- step := 1 / (float32(lines) + 1)
- for i := 1; i < lines+1; i++ {
- nx := float32(i) * step
- positions.Append(
- nx, 0, 0, color.R, color.G, color.B, // line start vertex and color
- nx, chart.baseY, 0, color.R, color.G, color.B, // line end vertex and color
- )
- }
- // Creates geometry using one interlaced VBO
- geom := geometry.NewGeometry()
- geom.AddVBO(gls.NewVBO().
- AddAttrib("VertexPosition", 3).
- AddAttrib("VertexColor", 3).
- SetBuffer(positions),
- )
- // Creates material
- mat := material.NewMaterial()
- mat.SetLineWidth(1.0)
- mat.SetShader("shaderChart")
- // Initializes the panel with this graphic
- gr := graphic.NewGraphic(geom, gls.LINES)
- gr.AddMaterial(sx, mat, 0, 0)
- sx.Panel.InitializeGraphic(chart.ContentWidth(), chart.ContentHeight(), gr)
- // Add labels after the panel is initialized
- for i := 1; i < lines+1; i++ {
- nx := float32(i) * step
- l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
- px, py := ndc2pix(&sx.chart.Panel, nx, chart.baseY)
- log.Error("label x:%v y:%v", px, py)
- l.SetPosition(px, py-20)
- sx.Add(l)
- }
- sx.recalc()
- return sx
- }
- func (sx *ChartScaleX) recalc() {
- if sx.chart.title != nil {
- th := sx.chart.title.Height()
- sx.SetPosition(0, th)
- sx.SetHeight(sx.chart.ContentHeight() - th)
- } else {
- sx.SetPosition(0, 0)
- sx.SetHeight(sx.chart.ContentHeight())
- }
- }
- // RenderSetup is called by the renderer before drawing this graphic
- // Calculates the model matrix and transfer to OpenGL.
- func (sx *ChartScaleX) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
- log.Error("ChartScaleX RenderSetup:%p", sx)
- // Sets model matrix and transfer to shader
- var mm math32.Matrix4
- sx.SetModelMatrix(gs, &mm)
- sx.modelMatrixUni.SetMatrix4(&mm)
- sx.modelMatrixUni.Transfer(gs)
- }
- //func newChartScaleX(chart *ChartLine, lines int, color *math32.Color) *ChartScaleX {
- //
- // sx := new(ChartScaleX)
- // sx.chart = chart
- //
- // // Generates grid lines using Normalized Device Coordinates and
- // // considering that the parent panel model coordinates are:
- // // 0,0,0 1,0,0
- // // +---------------+
- // // | |
- // // | |
- // // +---------------+
- // // 0,-1,0 1,-1,0
- // positions := math32.NewArrayF32(0, 0)
- //
- // // Appends scaleX bottom horizontal base line
- // positions.Append(
- // 0, chart.baseY, 0, color.R, color.G, color.B, // line start vertex and color
- // 1, chart.baseY, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // // Appends scale X vertical lines
- // step := 1 / (float32(lines) + 1)
- // for i := 1; i < lines+1; i++ {
- // nx := float32(i) * step
- // positions.Append(
- // nx, 0, 0, color.R, color.G, color.B, // line start vertex and color
- // nx, chart.baseY, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
- // px, py := ndc2pix(&sx.chart.Panel, nx, chart.baseY)
- // l.SetPosition(px, py)
- // sx.chart.Add(l)
- // }
- //
- // // Creates geometry using one interlaced VBO
- // geom := geometry.NewGeometry()
- // geom.AddVBO(gls.NewVBO().
- // AddAttrib("VertexPosition", 3).
- // AddAttrib("VertexColor", 3).
- // SetBuffer(positions),
- // )
- //
- // // Creates material
- // mat := material.NewMaterial()
- // mat.SetLineWidth(1.0)
- // mat.SetShader("shaderChart")
- //
- // // Initializes the grid graphic
- // sx.Graphic.Init(geom, gls.LINES)
- // sx.AddMaterial(sx, mat, 0, 0)
- // sx.modelMatrixUni.Init("ModelMatrix")
- //
- // return sx
- //}
- //
- //
- // Converts panel ndc coordinates to relative pixels inside panel
- func ndc2pix(p *Panel, nx, ny float32) (px, py float32) {
- w := p.ContentWidth()
- h := p.ContentHeight()
- return w * nx, -h * ny
- }
- //// RenderSetup is called by the renderer before drawing this graphic
- //// Calculates the model matrix and transfer to OpenGL.
- //func (sx *ChartScaleX) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
- //
- // // Set this model matrix the same as the chart panel
- // var mm math32.Matrix4
- // sx.chart.SetModelMatrix(gs, &mm)
- //
- // // Sets and transfer the model matrix uniform
- // sx.modelMatrixUni.SetMatrix4(&mm)
- // sx.modelMatrixUni.Transfer(gs)
- //}
- //
- ////
- ////
- ////
- //// ChartScaleY
- ////
- ////
- ////
- //type ChartScaleY struct {
- // graphic.Graphic // It is a Graphic
- // chart *ChartLine // Container chart
- // modelMatrixUni gls.UniformMatrix4f // Model matrix uniform
- //}
- //
- //func newChartScaleY(chart *ChartLine, lines int, color *math32.Color) *ChartScaleY {
- //
- // sy := new(ChartScaleY)
- // sy.chart = chart
- //
- // // Generates grid lines using Normalized Device Coordinates and
- // // considering that the parent panel model coordinates are:
- // // 0,0,0 1,0,0
- // // +---------------+
- // // | |
- // // | |
- // // +---------------+
- // // 0,-1,0 1,-1,0
- // positions := math32.NewArrayF32(0, 0)
- //
- // // Appends scaleY left vertical axis line
- // positions.Append(
- // chart.baseX, 0, 0, color.R, color.G, color.B, // line start vertex and color
- // chart.baseX, -1, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // // Appends scale horizontal lines starting from baseX
- // step := 1 / (float32(lines) + 1)
- // for i := 1; i < lines+1; i++ {
- // ny := -float32(i) * step
- // positions.Append(
- // chart.baseX, ny, 0, color.R, color.G, color.B, // line start vertex and color
- // 1, ny, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // // l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
- // // px, py := ndc2pix(&sx.chart.Panel, nx, baseY)
- // // l.SetPosition(px, py)
- // // sx.chart.Add(l)
- // }
- //
- // // Creates geometry using one interlaced VBO
- // geom := geometry.NewGeometry()
- // geom.AddVBO(gls.NewVBO().
- // AddAttrib("VertexPosition", 3).
- // AddAttrib("VertexColor", 3).
- // SetBuffer(positions),
- // )
- //
- // // Creates material
- // mat := material.NewMaterial()
- // mat.SetLineWidth(1.0)
- // mat.SetShader("shaderChart")
- //
- // // Initializes the grid graphic
- // sy.Graphic.Init(geom, gls.LINES)
- // sy.AddMaterial(sy, mat, 0, 0)
- // sy.modelMatrixUni.Init("ModelMatrix")
- //
- // return sy
- //}
- //
- //// RenderSetup is called by the renderer before drawing this graphic
- //// Calculates the model matrix and transfer to OpenGL.
- //func (sy *ChartScaleY) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
- //
- // // Set this model matrix the same as the chart panel
- // var mm math32.Matrix4
- // sy.chart.SetModelMatrix(gs, &mm)
- //
- // // Sets and transfer the model matrix uniform
- // sy.modelMatrixUni.SetMatrix4(&mm)
- // sy.modelMatrixUni.Transfer(gs)
- //}
- //
- ////
- ////
- ////
- //// ChartGrid
- ////
- ////
- ////
- //
- //// ChartGrid implements a 2D grid used inside charts
- //type ChartGrid struct {
- // graphic.Graphic // It is a Graphic
- // chart *Panel // Container chart
- // modelMatrixUni gls.UniformMatrix4f // Model matrix uniform
- //}
- //
- //// NewChartGrid creates and returns a pointer to a chart grid graphic for the
- //// specified parent chart and with the specified number of grid lines and color.
- //func NewChartGrid(chart *Panel, xcount, ycount int, color *math32.Color) *ChartGrid {
- //
- // cg := new(ChartGrid)
- // cg.chart = chart
- //
- // // Generates grid lines using Normalized Device Coordinates and
- // // considering that the parent panel model coordinates are:
- // // 0,0,0 1,0,0
- // // +---------------+
- // // | |
- // // | |
- // // +---------------+
- // // 0,-1,0 1,-1,0
- // positions := math32.NewArrayF32(0, 0)
- // xstep := 1 / (float32(xcount) + 1)
- // for xi := 1; xi < xcount+1; xi++ {
- // posx := float32(xi) * xstep
- // positions.Append(
- // posx, 0, 0, color.R, color.G, color.B, // line start vertex and color
- // posx, -1, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // }
- // ystep := 1 / (float32(ycount) + 1)
- // for yi := 1; yi < ycount+1; yi++ {
- // posy := -float32(yi) * ystep
- // positions.Append(
- // 0, posy, 0, color.R, color.G, color.B, // line start vertex and color
- // 1, posy, 0, color.R, color.G, color.B, // line end vertex and color
- // )
- // }
- //
- // // Creates geometry using one interlaced VBO
- // geom := geometry.NewGeometry()
- // geom.AddVBO(
- // gls.NewVBO().
- // AddAttrib("VertexPosition", 3).
- // AddAttrib("VertexColor", 3).
- // SetBuffer(positions),
- // )
- //
- // // Creates material
- // mat := material.NewMaterial()
- // mat.SetLineWidth(1.0)
- // mat.SetShader("shaderChart")
- //
- // // Initializes the grid graphic
- // cg.Graphic.Init(geom, gls.LINES)
- // cg.AddMaterial(cg, mat, 0, 0)
- // cg.modelMatrixUni.Init("ModelMatrix")
- // return cg
- //}
- //
- //// RenderSetup is called by the renderer before drawing this graphic
- //// Calculates the model matrix and transfer to OpenGL.
- //func (cg *ChartGrid) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
- //
- // // Set this model matrix the same as the chart panel
- // var mm math32.Matrix4
- // cg.chart.SetModelMatrix(gs, &mm)
- //
- // // Sets and transfer the model matrix uniform
- // cg.modelMatrixUni.SetMatrix4(&mm)
- // cg.modelMatrixUni.Transfer(gs)
- //}
- //
- ////
- ////
- ////
- //// LineGraph
- ////
- ////
- ////
- //
- //// LineGraph implemens a 2D line graph
- //type LineGraph struct {
- // graphic.Graphic // It is a Graphic
- // chart *Panel // Container chart
- // modelMatrixUni gls.UniformMatrix4f // Model matrix uniform
- // name string // Name id
- // title string // Title string
- // color *math32.Color // Line color
- // data []float32 // Data
- //}
- //
- //// newLineGraph creates and returns a pointer to a line graph graphic for the
- //// specified parent chart
- //func newLineGraph(chart *Panel, name, title string, color *math32.Color, data []float32) *LineGraph {
- //
- // lg := new(LineGraph)
- // lg.chart = chart
- // lg.name = name
- // lg.title = title
- // lg.color = color
- // lg.data = data
- //
- // // Generates graph lines using Normalized Device Coordinates and
- // // considering that the parent panel model coordinates are:
- // // 0,0,0 1,0,0
- // // +---------------+
- // // | |
- // // | |
- // // +---------------+
- // // 0,-1,0 1,-1,0
- // positions := math32.NewArrayF32(0, 0)
- // for i := 0; i < len(data); i++ {
- // px := float32(i) / float32(len(data))
- // py := -1 + data[i]
- // positions.Append(px, py, 0, color.R, color.G, color.B)
- // }
- //
- // // Creates geometry using one interlaced VBO
- // geom := geometry.NewGeometry()
- // geom.AddVBO(gls.NewVBO().
- // AddAttrib("VertexPosition", 3).
- // AddAttrib("VertexColor", 3).
- // SetBuffer(positions),
- // )
- //
- // // Creates material
- // mat := material.NewMaterial()
- // mat.SetLineWidth(2.5)
- // mat.SetShader("shaderChart")
- //
- // // Initializes the graphic
- // lg.Graphic.Init(geom, gls.LINE_STRIP)
- // lg.AddMaterial(lg, mat, 0, 0)
- // lg.modelMatrixUni.Init("ModelMatrix")
- //
- // return lg
- //}
- //
- //// RenderSetup is called by the renderer before drawing this graphic
- //// Calculates the model matrix and transfer to OpenGL.
- //func (lg *LineGraph) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
- //
- // // Set this graphic model matrix the same as the container chart panel
- // var mm math32.Matrix4
- // lg.chart.SetModelMatrix(gs, &mm)
- //
- // // Sets and transfer the model matrix uniform
- // lg.modelMatrixUni.SetMatrix4(&mm)
- // lg.modelMatrixUni.Transfer(gs)
- //}
- //
- // Vertex Shader template
- //
- const shaderChartVertex = `
- #version {{.Version}}
- // Vertex attributes
- {{template "attributes" .}}
- // Input uniforms
- uniform mat4 ModelMatrix;
- // Outputs for fragment shader
- out vec3 Color;
- void main() {
- Color = VertexColor;
- // Set position
- vec4 pos = vec4(VertexPosition.xyz, 1);
- gl_Position = ModelMatrix * pos;
- }
- `
- //
- // Fragment Shader template
- //
- const shaderChartFrag = `
- #version {{.Version}}
- in vec3 Color;
- out vec4 FragColor;
- void main() {
- FragColor = vec4(Color, 1.0);
- }
- `
|