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, (*gl.Uint)(&d.threshold_glids.vbuffer)) gl.DeleteBuffers(1, (*gl.Uint)(&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, (*gl.Uint)(&d.door_glids.vbuffer)) gl.DeleteBuffers(1, (*gl.Uint)(&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, (*gl.Uint)(&d.threshold_glids.vbuffer)) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(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, (*gl.Uint)(&d.threshold_glids.floor_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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, (*gl.Uint)(&d.door_glids.floor_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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, (*gl.Uint)(&room.vbuffer)) gl.DeleteBuffers(1, (*gl.Uint)(&room.left_buffer)) gl.DeleteBuffers(1, (*gl.Uint)(&room.right_buffer)) gl.DeleteBuffers(1, (*gl.Uint)(&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, (*gl.Uint)(&room.vbuffer)) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(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, (*gl.Uint)(&room.left_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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, (*gl.Uint)(&room.right_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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, (*gl.Uint)(&room.floor_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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 (wt *WallTexture) setupGlStuff(x, y, dx, dy int, gl_ids *wallTextureGlIds) { if gl_ids.vbuffer != 0 { gl.DeleteBuffers(1, (*gl.Uint)(&gl_ids.vbuffer)) gl.DeleteBuffers(1, (*gl.Uint)(&gl_ids.left_buffer)) gl.DeleteBuffers(1, (*gl.Uint)(&gl_ids.right_buffer)) gl.DeleteBuffers(1, (*gl.Uint)(&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.Uint)(&gl_ids.floor_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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.Uint)(&gl_ids.left_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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.Uint)(&gl_ids.right_buffer)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(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.Uint)(&gl_ids.vbuffer)) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(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) } }