func initquad() { ver := []gl.Float{-1, 1, 1, 1, -1, -1, 1, -1} gl.BindBuffer(gl.ARRAY_BUFFER, 1) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(4*len(ver)), gl.Pointer(&ver[0]), gl.STATIC_DRAW) gl.VertexPointer(2, gl.FLOAT, 0, nil) tex := []gl.Float{0, 0, 1, 0, 0, 1, 1, 1} gl.BindBuffer(gl.ARRAY_BUFFER, 2) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(4*len(tex)), gl.Pointer(&tex[0]), gl.STATIC_DRAW) gl.TexCoordPointer(2, gl.FLOAT, 0, nil) gl.EnableClientState(gl.VERTEX_ARRAY) gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) }
// Move moves the Shape object a specified distance. func (shape *Shape) Move(x, y float64) { var verticies []float32 for i := 0; i < len(shape.verticies); i += 2 { shape.verticies[i] += float32(x) shape.verticies[i+1] += float32(y) } if shape.scaleX != 1 || shape.scaleY != 1 { verticies = make([]float32, len(shape.verticies)) xTransform := shape.verticies[0] - (shape.verticies[0] * float32(shape.scaleX)) yTransform := shape.verticies[1] - (shape.verticies[1] * float32(shape.scaleY)) for i := range verticies { if i%2 == 0 { verticies[i] = shape.verticies[i] * float32(shape.scaleX) verticies[i] += xTransform } else { verticies[i] = shape.verticies[i] * float32(shape.scaleY) verticies[i] += yTransform } } } else { verticies = shape.verticies } gl.BindBuffer(gl.ARRAY_BUFFER, shape.vertexBuffer) gl.BufferSubData(gl.ARRAY_BUFFER, 0, gl.Sizeiptr(len(verticies)*4), gl.Pointer(&verticies[0])) gl.BindBuffer(gl.ARRAY_BUFFER, 0) }
func (m *Model) init() (err error) { m.shader.init("shader/simple.vert", "shader/simple.frag") /* gl.GenBuffers(1, &m.buffer) gl.BindBuffer(gl.ARRAY_BUFFER, m.buffer); gl.BufferData( gl.ARRAY_BUFFER, gl.Sizeiptr(len(m.vertices)* int(unsafe.Sizeof(m.vertices[0]))), gl.Pointer(&m.vertices[0]), gl.STATIC_DRAW); */ m.initBufferFloat(&m.buffer, gl.ARRAY_BUFFER, &m.vertices) gl.GenBuffers(1, &m.index) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, m.index) gl.BufferData( gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(len(m.indices)*int(unsafe.Sizeof(m.indices[0]))), gl.Pointer(&m.indices[0]), gl.STATIC_DRAW) gl.GenBuffers(1, &m.normal_buf) gl.BindBuffer(gl.ARRAY_BUFFER, m.normal_buf) gl.BufferData( gl.ARRAY_BUFFER, gl.Sizeiptr(len(m.normals)*int(unsafe.Sizeof(m.normals[0]))), gl.Pointer(&m.normals[0]), gl.STATIC_DRAW) m.initTexture() if m.has_uv { gl.GenBuffers(1, &m.texcoord) gl.BindBuffer(gl.ARRAY_BUFFER, m.texcoord) gl.BufferData( gl.ARRAY_BUFFER, gl.Sizeiptr(len(m.uvs)*int(unsafe.Sizeof(m.uvs[0]))), gl.Pointer(&m.uvs[0]), gl.STATIC_DRAW) } return }
func (m *Model) initBufferFloat(buffer *gl.Uint, t gl.Enum, data *[]gl.Float) { gl.GenBuffers(1, buffer) gl.BindBuffer(t, *buffer) gl.BufferData( t, gl.Sizeiptr(len(*data)*int(unsafe.Sizeof((*data)[0]))), gl.Pointer(&(*data)[0]), gl.STATIC_DRAW) }
// NewSprite creates a new Sprite object using the given data, which is // expected to be in RGBA format. If you use PNG image files, you can use the // NewSpriteFromImage shortcut function instead. func NewSprite(x, y, width, height float64, data []byte, clip int) (*Sprite, error) { verticies := []float64{ x, y, x + width, y, x, y + height, x + width, y + height, x + width, y, x, y + height} shape, err := NewShape(gl.TRIANGLES, verticies) if err != nil { return nil, err } sprite := &Sprite{texcoordBuffer: 0, texture: nil, shape: shape} texCoords := []float32{ 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1} gl.GenBuffers(1, &sprite.texcoordBuffer) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(sprite.texcoordBuffer)) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(texCoords)*4), gl.Pointer(&texCoords[0]), gl.STREAM_DRAW) gl.BindBuffer(gl.ARRAY_BUFFER, 0) sprite.texture = make([]gl.Uint, clip) gl.GenTextures(gl.Sizei(clip), &sprite.texture[0]) clips := make([][]byte, clip) for i := range clips { clips[i] = data[i*(len(data)/len(clips)) : (i+1)*(len(data)/len(clips))] gl.BindTexture(gl.TEXTURE_2D, sprite.texture[len(clips)-1-i]) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.Sizei(width), gl.Sizei(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Pointer(&clips[i][0])) } gl.BindTexture(gl.TEXTURE_2D, 0) return sprite, checkForErrors() }
// NewShapeFromShape creates a copy of an existing Shape object. func NewShapeFromShape(copyShape *Shape) (*Shape, error) { shape := &Shape{mode: copyShape.mode, size: copyShape.size, verticies: make([]float32, len(copyShape.verticies)), scaleX: copyShape.scaleX, scaleY: copyShape.scaleY} copy(shape.verticies, copyShape.verticies) gl.GenBuffers(1, &shape.vertexBuffer) gl.BindBuffer(gl.ARRAY_BUFFER, shape.vertexBuffer) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(shape.verticies)*4), gl.Pointer(&shape.verticies[0]), gl.DYNAMIC_DRAW) gl.BindBuffer(gl.ARRAY_BUFFER, 0) return shape, checkForErrors() }
func loadCubeToGPU() { newNormal(0, 0, 1) newVertex(-1, -1, 1) newVertex(1, -1, 1) newVertex(1, 1, 1) newVertex(-1, 1, 1) newNormal(0, 0, -1) newVertex(-1, -1, -1) newVertex(-1, 1, -1) newVertex(1, 1, -1) newVertex(1, -1, -1) newNormal(0, 1, 0) newVertex(-1, 1, -1) newVertex(-1, 1, 1) newVertex(1, 1, 1) newVertex(1, 1, -1) newNormal(0, -1, 0) newVertex(-1, -1, -1) newVertex(1, -1, -1) newVertex(1, -1, 1) newVertex(-1, -1, 1) newNormal(1, 0, 0) newVertex(1, -1, -1) newVertex(1, 1, -1) newVertex(1, 1, 1) newVertex(1, -1, 1) newNormal(-1, 0, 0) newVertex(-1, -1, -1) newVertex(-1, -1, 1) newVertex(-1, 1, 1) newVertex(-1, 1, -1) gl.GenBuffers(1, &gVBO) gl.BindBuffer(gl.ARRAY_BUFFER, gVBO) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(unsafe.Sizeof(Vertex{})*24), gl.Pointer(&Vertices[0]), gl.STATIC_DRAW) gl.EnableClientState(gl.VERTEX_ARRAY) gl.EnableClientState(gl.NORMAL_ARRAY) gl.VertexPointer(3, gl.FLOAT, 24, nil) tmpStruct := Vertex{} gl.NormalPointer(gl.FLOAT, gl.Sizei(unsafe.Sizeof(Vertex{})), gl.Pointer(unsafe.Offsetof(tmpStruct.normal))) }
// NewShape creates a new Shape object based on the verticies and shape type. func NewShape(shapeType ShapeType, verticies []float64) (*Shape, error) { verticies32 := make([]float32, len(verticies)) for i, val := range verticies { verticies32[i] = float32(val) } shape := &Shape{mode: gl.Enum(shapeType), size: len(verticies), vertexBuffer: 0, verticies: verticies32, scaleX: 1, scaleY: 1} gl.GenBuffers(1, &shape.vertexBuffer) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(shape.vertexBuffer)) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(shape.size*4), gl.Pointer(&shape.verticies[0]), gl.DYNAMIC_DRAW) gl.BindBuffer(gl.ARRAY_BUFFER, 0) return shape, checkForErrors() }
// SetScaling sets the scaling factor of the Shape object. For instance, an x // and y scale value of two will make the Shape object twice as large. func (shape *Shape) SetScaling(scaleX, scaleY float64) { shape.scaleX = scaleX shape.scaleY = scaleY verticies := make([]float32, len(shape.verticies)) xTransform := shape.verticies[0] - (shape.verticies[0] * float32(scaleX)) yTransform := shape.verticies[1] - (shape.verticies[1] * float32(scaleY)) for i := range verticies { if i%2 == 0 { verticies[i] = shape.verticies[i] * float32(scaleX) verticies[i] += xTransform } else { verticies[i] = shape.verticies[i] * float32(scaleY) verticies[i] += yTransform } } gl.BindBuffer(gl.ARRAY_BUFFER, shape.vertexBuffer) gl.BufferSubData(gl.ARRAY_BUFFER, 0, gl.Sizeiptr(len(verticies)*4), gl.Pointer(&verticies[0])) gl.BindBuffer(gl.ARRAY_BUFFER, 0) }
func (wt *WallTexture) setupGlStuff(x, y, dx, dy int, gl_ids *wallTextureGlIds) { if gl_ids.vbuffer != 0 { gl.DeleteBuffers(1, &gl_ids.vbuffer) gl.DeleteBuffers(1, &gl_ids.left_buffer) gl.DeleteBuffers(1, &gl_ids.right_buffer) gl.DeleteBuffers(1, &gl_ids.floor_buffer) gl_ids.vbuffer = 0 gl_ids.left_buffer = 0 gl_ids.right_buffer = 0 gl_ids.floor_buffer = 0 } // All vertices for both walls and the floor will go here and get sent to // opengl all at once var vs []roomVertex // Conveniently casted values frx := float32(x) fry := float32(y) frdx := float32(dx) frdy := float32(dy) tdx := float32(wt.Texture.Data().Dx()) / 100 tdy := float32(wt.Texture.Data().Dy()) / 100 wtx := wt.X wty := wt.Y wtr := wt.Rot if wtx > frdx { wtr -= 3.1415926535 / 2 } // Floor verts := []mathgl.Vec2{ {-tdx / 2, -tdy / 2}, {-tdx / 2, tdy / 2}, {tdx / 2, tdy / 2}, {tdx / 2, -tdy / 2}, } var m, run mathgl.Mat3 run.Identity() m.Translation(wtx, wty) run.Multiply(&m) m.RotationZ(wtr) run.Multiply(&m) if wt.Flip { m.Scaling(-1, 1) run.Multiply(&m) } for i := range verts { verts[i].Transform(&run) } p := mathgl.Poly(verts) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{0, 0}, B: mathgl.Vec2{0, frdy}}) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{0, frdy}, B: mathgl.Vec2{frdx, frdy}}) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{frdx, frdy}, B: mathgl.Vec2{frdx, 0}}) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{frdx, 0}, B: mathgl.Vec2{0, 0}}) if len(p) >= 3 { // floor indices var is []uint16 for i := 1; i < len(p)-1; i++ { is = append(is, uint16(len(vs)+0)) is = append(is, uint16(len(vs)+i)) is = append(is, uint16(len(vs)+i+1)) } gl.GenBuffers(1, &gl_ids.floor_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl_ids.floor_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is)), gl.Pointer(&is[0]), gl.STATIC_DRAW) gl_ids.floor_count = gl.Sizei(len(is)) run.Inverse() for i := range p { v := mathgl.Vec2{p[i].X, p[i].Y} v.Transform(&run) vs = append(vs, roomVertex{ x: p[i].X, y: p[i].Y, u: v.X/tdx + 0.5, v: -(v.Y/tdy + 0.5), los_u: (fry + p[i].Y) / LosTextureSize, los_v: (frx + p[i].X) / LosTextureSize, }) } } // Left Wall verts = []mathgl.Vec2{ {-tdx / 2, -tdy / 2}, {-tdx / 2, tdy / 2}, {tdx / 2, tdy / 2}, {tdx / 2, -tdy / 2}, } run.Identity() m.Translation(wtx, wty) run.Multiply(&m) m.RotationZ(wtr) run.Multiply(&m) if wt.Flip { m.Scaling(-1, 1) run.Multiply(&m) } for i := range verts { verts[i].Transform(&run) } p = mathgl.Poly(verts) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{0, 0}, B: mathgl.Vec2{0, frdy}}) p.Clip(&mathgl.Seg2{B: mathgl.Vec2{0, frdy}, A: mathgl.Vec2{frdx, frdy}}) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{frdx, frdy}, B: mathgl.Vec2{frdx, 0}}) if len(p) >= 3 { // floor indices var is []uint16 for i := 1; i < len(p)-1; i++ { is = append(is, uint16(len(vs)+0)) is = append(is, uint16(len(vs)+i)) is = append(is, uint16(len(vs)+i+1)) } gl.GenBuffers(1, &gl_ids.left_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl_ids.left_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is)), gl.Pointer(&is[0]), gl.STATIC_DRAW) gl_ids.left_count = gl.Sizei(len(is)) run.Inverse() for i := range p { v := mathgl.Vec2{p[i].X, p[i].Y} v.Transform(&run) vs = append(vs, roomVertex{ x: p[i].X, y: frdy, z: frdy - p[i].Y, u: v.X/tdx + 0.5, v: -(v.Y/tdy + 0.5), los_u: (fry + frdy - 0.5) / LosTextureSize, los_v: (frx + p[i].X) / LosTextureSize, }) } } // Right Wall verts = []mathgl.Vec2{ {-tdx / 2, -tdy / 2}, {-tdx / 2, tdy / 2}, {tdx / 2, tdy / 2}, {tdx / 2, -tdy / 2}, } run.Identity() m.Translation(wtx, wty) run.Multiply(&m) m.RotationZ(wtr) run.Multiply(&m) if wt.Flip { m.Scaling(-1, 1) run.Multiply(&m) } for i := range verts { verts[i].Transform(&run) } p = mathgl.Poly(verts) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{0, frdy}, B: mathgl.Vec2{frdx, frdy}}) p.Clip(&mathgl.Seg2{B: mathgl.Vec2{frdx, frdy}, A: mathgl.Vec2{frdx, 0}}) p.Clip(&mathgl.Seg2{A: mathgl.Vec2{frdx, 0}, B: mathgl.Vec2{0, 0}}) if len(p) >= 3 { // floor indices var is []uint16 for i := 1; i < len(p)-1; i++ { is = append(is, uint16(len(vs)+0)) is = append(is, uint16(len(vs)+i)) is = append(is, uint16(len(vs)+i+1)) } gl.GenBuffers(1, &gl_ids.right_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl_ids.right_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is)), gl.Pointer(&is[0]), gl.STATIC_DRAW) gl_ids.right_count = gl.Sizei(len(is)) run.Inverse() for i := range p { v := mathgl.Vec2{p[i].X, p[i].Y} v.Transform(&run) vs = append(vs, roomVertex{ x: frdx, y: p[i].Y, z: frdx - p[i].X, u: v.X/tdx + 0.5, v: -(v.Y/tdy + 0.5), los_u: (fry + p[i].Y) / LosTextureSize, los_v: (frx + frdx - 0.5) / LosTextureSize, }) } } if len(vs) > 0 { gl.GenBuffers(1, &gl_ids.vbuffer) gl.BindBuffer(gl.ARRAY_BUFFER, gl_ids.vbuffer) size := int(unsafe.Sizeof(roomVertex{})) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(size*len(vs)), gl.Pointer(&vs[0].x), gl.STATIC_DRAW) } }
func (d *Door) setupGlStuff(room *Room) { var state doorState state.facing = d.Facing state.pos = d.Pos state.room.x = room.X state.room.y = room.Y state.room.dx = room.roomDef.Size.Dx state.room.dy = room.roomDef.Size.Dy if state == d.state { return } if d.TextureData().Dy() == 0 { // Can't build this data until the texture is loaded, so we'll have to try // again later. return } d.state = state if d.threshold_glids.vbuffer != 0 { gl.DeleteBuffers(1, &d.threshold_glids.vbuffer) gl.DeleteBuffers(1, &d.threshold_glids.floor_buffer) d.threshold_glids.vbuffer = 0 d.threshold_glids.floor_buffer = 0 } if d.door_glids.vbuffer != 0 { gl.DeleteBuffers(1, &d.door_glids.vbuffer) gl.DeleteBuffers(1, &d.door_glids.floor_buffer) d.door_glids.vbuffer = 0 d.door_glids.floor_buffer = 0 } // far left, near right, do threshold // near left, far right, do threshold // far left, far right, do door var vs []roomVertex if d.Facing == FarLeft || d.Facing == NearRight { x1 := float32(d.Pos) x2 := float32(d.Pos + d.Width) var y1 float32 = -0.25 var y2 float32 = 0.25 if d.Facing == FarLeft { y1 = float32(room.roomDef.Size.Dy) y2 = float32(room.roomDef.Size.Dy) - 0.25 } // los_x1 := (x1 + float32(room.X)) / LosTextureSize vs = append(vs, roomVertex{x: x1, y: y1}) vs = append(vs, roomVertex{x: x1, y: y2}) vs = append(vs, roomVertex{x: x2, y: y2}) vs = append(vs, roomVertex{x: x2, y: y1}) for i := 0; i < 4; i++ { vs[i].los_u = (y2 + float32(room.Y)) / LosTextureSize vs[i].los_v = (vs[i].x + float32(room.X)) / LosTextureSize } } if d.Facing == FarRight || d.Facing == NearLeft { y1 := float32(d.Pos) y2 := float32(d.Pos + d.Width) var x1 float32 = -0.25 var x2 float32 = 0.25 if d.Facing == FarRight { x1 = float32(room.roomDef.Size.Dx) x2 = float32(room.roomDef.Size.Dx) - 0.25 } // los_y1 := (y1 + float32(room.Y)) / LosTextureSize vs = append(vs, roomVertex{x: x1, y: y1}) vs = append(vs, roomVertex{x: x1, y: y2}) vs = append(vs, roomVertex{x: x2, y: y2}) vs = append(vs, roomVertex{x: x2, y: y1}) for i := 0; i < 4; i++ { vs[i].los_u = (vs[i].y + float32(room.Y)) / LosTextureSize vs[i].los_v = (x2 + float32(room.X)) / LosTextureSize } } dz := -float32(d.Width*d.TextureData().Dy()) / float32(d.TextureData().Dx()) if d.Facing == FarRight { x := float32(room.roomDef.Size.Dx) y1 := float32(d.Pos + d.Width) y2 := float32(d.Pos) los_v := (float32(room.X) + x - 0.5) / LosTextureSize los_u1 := (float32(room.Y) + y1) / LosTextureSize los_u2 := (float32(room.Y) + y2) / LosTextureSize vs = append(vs, roomVertex{ x: x, y: y1, z: 0, u: 0, v: 1, los_u: los_u1, los_v: los_v, }) vs = append(vs, roomVertex{ x: x, y: y1, z: dz, u: 0, v: 0, los_u: los_u1, los_v: los_v, }) vs = append(vs, roomVertex{ x: x, y: y2, z: dz, u: 1, v: 0, los_u: los_u2, los_v: los_v, }) vs = append(vs, roomVertex{ x: x, y: y2, z: 0, u: 1, v: 1, los_u: los_u2, los_v: los_v, }) } if d.Facing == FarLeft { x1 := float32(d.Pos) x2 := float32(d.Pos + d.Width) y := float32(room.roomDef.Size.Dy) los_v1 := (float32(room.X) + x1) / LosTextureSize los_v2 := (float32(room.X) + x2) / LosTextureSize los_u := (float32(room.Y) + y - 0.5) / LosTextureSize vs = append(vs, roomVertex{ x: x1, y: y, z: 0, u: 0, v: 1, los_u: los_u, los_v: los_v1, }) vs = append(vs, roomVertex{ x: x1, y: y, z: dz, u: 0, v: 0, los_u: los_u, los_v: los_v1, }) vs = append(vs, roomVertex{ x: x2, y: y, z: dz, u: 1, v: 0, los_u: los_u, los_v: los_v2, }) vs = append(vs, roomVertex{ x: x2, y: y, z: 0, u: 1, v: 1, los_u: los_u, los_v: los_v2, }) } gl.GenBuffers(1, &d.threshold_glids.vbuffer) gl.BindBuffer(gl.ARRAY_BUFFER, d.threshold_glids.vbuffer) size := int(unsafe.Sizeof(roomVertex{})) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(size*len(vs)), gl.Pointer(&vs[0].x), gl.STATIC_DRAW) is := []uint16{0, 1, 2, 0, 2, 3} gl.GenBuffers(1, &d.threshold_glids.floor_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, d.threshold_glids.floor_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is)), gl.Pointer(&is[0]), gl.STATIC_DRAW) d.threshold_glids.floor_count = 6 if d.Facing == FarLeft || d.Facing == FarRight { is2 := []uint16{4, 5, 6, 4, 6, 7} gl.GenBuffers(1, &d.door_glids.floor_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, d.door_glids.floor_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is2)), gl.Pointer(&is2[0]), gl.STATIC_DRAW) d.door_glids.floor_count = 6 } }
func (room *Room) setupGlStuff() { if room.X == room.gl.x && room.Y == room.gl.y && room.Size.Dx == room.gl.dx && room.Size.Dy == room.gl.dy && room.Wall.Data().Dx() == room.gl.wall_tex_dx && room.Wall.Data().Dy() == room.gl.wall_tex_dy { return } room.gl.x = room.X room.gl.y = room.Y room.gl.dx = room.Size.Dx room.gl.dy = room.Size.Dy room.gl.wall_tex_dx = room.Wall.Data().Dx() room.gl.wall_tex_dy = room.Wall.Data().Dy() if room.vbuffer != 0 { gl.DeleteBuffers(1, &room.vbuffer) gl.DeleteBuffers(1, &room.left_buffer) gl.DeleteBuffers(1, &room.right_buffer) gl.DeleteBuffers(1, &room.floor_buffer) } dx := float32(room.Size.Dx) dy := float32(room.Size.Dy) var dz float32 if room.Wall.Data().Dx() > 0 { dz = -float32(room.Wall.Data().Dy()*(room.Size.Dx+room.Size.Dy)) / float32(room.Wall.Data().Dx()) } // Conveniently casted values frx := float32(room.X) fry := float32(room.Y) frdx := float32(room.Size.Dx) frdy := float32(room.Size.Dy) // c is the u-texcoord of the corner of the room c := frdx / (frdx + frdy) // lt_llx := frx / LosTextureSize // lt_lly := fry / LosTextureSize // lt_urx := (frx + frdx) / LosTextureSize // lt_ury := (fry + frdy) / LosTextureSize lt_llx_ep := (frx + 0.5) / LosTextureSize lt_lly_ep := (fry + 0.5) / LosTextureSize lt_urx_ep := (frx + frdx - 0.5) / LosTextureSize lt_ury_ep := (fry + frdy - 0.5) / LosTextureSize vs := []roomVertex{ // Walls {0, dy, 0, 0, 1, lt_ury_ep, lt_llx_ep}, {dx, dy, 0, c, 1, lt_ury_ep, lt_urx_ep}, {dx, 0, 0, 1, 1, lt_lly_ep, lt_urx_ep}, {0, dy, dz, 0, 0, lt_ury_ep, lt_llx_ep}, {dx, dy, dz, c, 0, lt_ury_ep, lt_urx_ep}, {dx, 0, dz, 1, 0, lt_lly_ep, lt_urx_ep}, // Floor // This is the bulk of the floor, containing all but the outer edges of // the room. los_tex can map directly onto this so we don't need to do // anything weird here. {0.5, 0.5, 0, 0.5 / dx, 1 - 0.5/dy, lt_lly_ep, lt_llx_ep}, {0.5, dy - 0.5, 0, 0.5 / dx, 0.5 / dy, lt_ury_ep, lt_llx_ep}, {dx - 0.5, dy - 0.5, 0, 1 - 0.5/dx, 0.5 / dy, lt_ury_ep, lt_urx_ep}, {dx - 0.5, 0.5, 0, 1 - 0.5/dx, 1 - 0.5/dy, lt_lly_ep, lt_urx_ep}, {0, 0.5, 0, 0, 1 - 0.5/dy, lt_lly_ep, lt_llx_ep}, {0, dy - 0.5, 0, 0, 0.5 / dy, lt_ury_ep, lt_llx_ep}, {0.5, dy - 0.5, 0, 0.5 / dx, 0.5 / dy, lt_ury_ep, lt_llx_ep}, {0.5, 0.5, 0, 0.5 / dx, 1 - 0.5/dy, lt_lly_ep, lt_llx_ep}, {0.5, 0, 0, 0.5 / dx, 1, lt_lly_ep, lt_llx_ep}, {0.5, 0.5, 0, 0.5 / dx, 1 - 0.5/dy, lt_lly_ep, lt_llx_ep}, {dx - 0.5, 0.5, 0, 1 - 0.5/dx, 1 - 0.5/dy, lt_lly_ep, lt_urx_ep}, {dx - 0.5, 0, 0, 1 - 0.5/dx, 1, lt_lly_ep, lt_urx_ep}, {dx - 0.5, 0.5, 0, 1 - 0.5/dx, 1 - 0.5/dy, lt_lly_ep, lt_urx_ep}, {dx - 0.5, dy - 0.5, 0, 1 - 0.5/dx, 0.5 / dy, lt_ury_ep, lt_urx_ep}, {dx, dy - 0.5, 0, 1, 0.5 / dy, lt_ury_ep, lt_urx_ep}, {dx, 0.5, 0, 1, 1 - 0.5/dy, lt_lly_ep, lt_urx_ep}, {0.5, dy - 0.5, 0, 0.5 / dx, 0.5 / dy, lt_ury_ep, lt_llx_ep}, {0.5, dy, 0, 0.5 / dx, 0, lt_ury_ep, lt_llx_ep}, {dx - 0.5, dy, 0, 1 - 0.5/dx, 0, lt_ury_ep, lt_urx_ep}, {dx - 0.5, dy - 0.5, 0, 1 - 0.5/dx, 0.5 / dy, lt_ury_ep, lt_urx_ep}, {0, 0, 0, 0, 1, lt_lly_ep, lt_llx_ep}, {0, 0.5, 0, 0, 1 - 0.5/dy, lt_lly_ep, lt_llx_ep}, {0.5, 0.5, 0, 0.5 / dx, 1 - 0.5/dy, lt_lly_ep, lt_llx_ep}, {0.5, 0, 0, 0.5 / dx, 1, lt_lly_ep, lt_llx_ep}, {0, dy - 0.5, 0, 0, 0.5 / dy, lt_ury_ep, lt_llx_ep}, {0, dy, 0, 0, 0, lt_ury_ep, lt_llx_ep}, {0.5, dy, 0, 0.5 / dx, 0, lt_ury_ep, lt_llx_ep}, {0.5, dy - 0.5, 0, 0.5 / dx, 0.5 / dy, lt_ury_ep, lt_llx_ep}, {dx - 0.5, dy - 0.5, 0, 1 - 0.5/dx, 0.5 / dy, lt_ury_ep, lt_urx_ep}, {dx - 0.5, dy, 0, 1 - 0.5/dx, 0, lt_ury_ep, lt_urx_ep}, {dx, dy, 0, 1, 0, lt_ury_ep, lt_urx_ep}, {dx, dy - 0.5, 0, 1, 0.5 / dy, lt_ury_ep, lt_urx_ep}, {dx - 0.5, 0, 0, 1 - 0.5/dx, 1, lt_lly_ep, lt_urx_ep}, {dx - 0.5, 0.5, 0, 1 - 0.5/dx, 1 - 0.5/dy, lt_lly_ep, lt_urx_ep}, {dx, 0.5, 0, 1, 1 - 0.5/dy, lt_lly_ep, lt_urx_ep}, {dx, 0, 0, 1, 1, lt_lly_ep, lt_urx_ep}, } gl.GenBuffers(1, &room.vbuffer) gl.BindBuffer(gl.ARRAY_BUFFER, room.vbuffer) size := int(unsafe.Sizeof(roomVertex{})) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(size*len(vs)), gl.Pointer(&vs[0].x), gl.STATIC_DRAW) // left wall indices is := []uint16{0, 3, 4, 0, 4, 1} gl.GenBuffers(1, &room.left_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, room.left_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is)), gl.Pointer(&is[0]), gl.STATIC_DRAW) // right wall indices is = []uint16{1, 4, 5, 1, 5, 2} gl.GenBuffers(1, &room.right_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, room.right_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is)), gl.Pointer(&is[0]), gl.STATIC_DRAW) // floor indices is = []uint16{ 6, 7, 8, 6, 8, 9, // middle 10, 11, 12, 10, 12, 13, // left side 14, 15, 16, 14, 16, 17, // bottom side 18, 19, 20, 18, 20, 21, // right side 22, 23, 24, 22, 24, 25, // top side 26, 27, 28, 26, 28, 29, // bottom left corner 30, 31, 32, 30, 32, 33, // upper left corner 34, 35, 36, 34, 36, 37, // upper right corner 38, 39, 40, 38, 40, 41, // lower right corner } gl.GenBuffers(1, &room.floor_buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, room.floor_buffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(is[0]))*len(is)), gl.Pointer(&is[0]), gl.STATIC_DRAW) room.floor_count = len(is) }
func (d *Dictionary) RenderString(s string, x, y, z, height float64, just Justification) { if len(s) == 0 { return } strbuf, ok := d.strs[s] if !ok { defer d.RenderString(s, x, y, z, height, just) } else { render.EnableShader("glop.font") diff := 20/math.Pow(height, 1.0) + 5*math.Pow(d.data.Scale, 1.0)/math.Pow(height, 1.0) if diff > 0.4 { // TODO: Need to come up with decent values here diff = 0.4 } render.SetUniformF("glop.font", "dist_min", float32(0.5-diff)) render.SetUniformF("glop.font", "dist_max", float32(0.5+diff)) defer render.EnableShader("") } size := unsafe.Sizeof(dictVert{}) scale := height / float64(d.data.Maxy-d.data.Miny) width := float32(d.figureWidth(s) * scale) x_pos := float32(x) switch just { case Center: x_pos -= width / 2 case Right: x_pos -= width } if ok { gl.PushMatrix() defer gl.PopMatrix() gl.Translated(gl.Double(x_pos), gl.Double(y), gl.Double(z)) gl.Scaled(gl.Double(scale), gl.Double(scale), 1) gl.PushAttrib(gl.COLOR_BUFFER_BIT) defer gl.PopAttrib() gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Enable(gl.TEXTURE_2D) gl.BindTexture(gl.TEXTURE_2D, gl.Uint(d.texture)) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(strbuf.vbuffer)) gl.EnableClientState(gl.VERTEX_ARRAY) gl.VertexPointer(2, gl.FLOAT, gl.Sizei(size), nil) gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(size), gl.Pointer(unsafe.Offsetof(strbuf.vs[0].u))) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(strbuf.ibuffer)) gl.DrawElements(gl.TRIANGLES, gl.Sizei(len(strbuf.is)), gl.UNSIGNED_SHORT, nil) gl.DisableClientState(gl.VERTEX_ARRAY) gl.DisableClientState(gl.TEXTURE_COORD_ARRAY) gl.Disable(gl.TEXTURE_2D) return } x_pos = 0 var prev rune for _, r := range s { if _, ok := d.data.Kerning[prev]; ok { x_pos += float32(d.data.Kerning[prev][r]) } prev = r info := d.getInfo(r) xleft := x_pos + float32(info.Full_bounds.Min.X) xright := x_pos + float32(info.Full_bounds.Max.X) ytop := float32(info.Full_bounds.Max.Y) + float32(-d.data.Miny) ybot := float32(info.Full_bounds.Min.Y) + float32(-d.data.Miny) start := uint16(len(strbuf.vs)) strbuf.is = append(strbuf.is, start+0) strbuf.is = append(strbuf.is, start+1) strbuf.is = append(strbuf.is, start+2) strbuf.is = append(strbuf.is, start+0) strbuf.is = append(strbuf.is, start+2) strbuf.is = append(strbuf.is, start+3) strbuf.vs = append(strbuf.vs, dictVert{ x: xleft, y: ytop, u: float32(info.Pos.Min.X) / float32(d.data.Dx), v: float32(info.Pos.Max.Y) / float32(d.data.Dy), }) strbuf.vs = append(strbuf.vs, dictVert{ x: xleft, y: ybot, u: float32(info.Pos.Min.X) / float32(d.data.Dx), v: float32(info.Pos.Min.Y) / float32(d.data.Dy), }) strbuf.vs = append(strbuf.vs, dictVert{ x: xright, y: ybot, u: float32(info.Pos.Max.X) / float32(d.data.Dx), v: float32(info.Pos.Min.Y) / float32(d.data.Dy), }) strbuf.vs = append(strbuf.vs, dictVert{ x: xright, y: ytop, u: float32(info.Pos.Max.X) / float32(d.data.Dx), v: float32(info.Pos.Max.Y) / float32(d.data.Dy), }) x_pos += float32(info.Advance) // - float32((info.Full_bounds.Dx() - info.Bounds.Dx())) } gl.GenBuffers(1, (*gl.Uint)(&strbuf.vbuffer)) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(strbuf.vbuffer)) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(int(size)*len(strbuf.vs)), gl.Pointer(&strbuf.vs[0].x), gl.STATIC_DRAW) gl.GenBuffers(1, (*gl.Uint)(&strbuf.ibuffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(strbuf.ibuffer)) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.Sizeiptr(int(unsafe.Sizeof(strbuf.is[0]))*len(strbuf.is)), gl.Pointer(&strbuf.is[0]), gl.STATIC_DRAW) d.strs[s] = strbuf }