func (f *Furniture) Render(pos mathgl.Vec2, width float32) { var rgba [4]gl.Double gl.GetDoublev(gl.CURRENT_COLOR, &rgba[0]) gl.PushAttrib(gl.CURRENT_BIT) if !f.Blocks_los || !f.alpha_enabled { f.alpha = 1 } var tff gl.Double = 255 gl.Color4ub(gl.Ubyte(tff*rgba[0]), gl.Ubyte(tff*rgba[1]), gl.Ubyte(tff*rgba[2]), gl.Ubyte(tff*rgba[3]*gl.Double(f.alpha))) orientation := f.Orientations[f.Rotation] dy := width * float32(orientation.Texture.Data().Dy()) / float32(orientation.Texture.Data().Dx()) // orientation.Texture.Data().Render(float64(pos.X), float64(pos.Y), float64(width), float64(dy)) orientation.Texture.Data().RenderAdvanced(float64(pos.X), float64(pos.Y), float64(width), float64(dy), 0, !f.Flip) gl.PopAttrib() }
func (sp *SpawnPoint) RenderOnFloor() { re := topSpawnRegexp() if re == nil || !re.MatchString(sp.Name) { return } var rgba [4]gl.Double gl.GetDoublev(gl.CURRENT_COLOR, &rgba[0]) gl.PushAttrib(gl.CURRENT_BIT) gl.Disable(gl.TEXTURE_2D) // This just creates a color that is consistent among all spawn points whose // names match SpawnName-.* prefix := sp.Name for i := range prefix { if prefix[i] == '-' { prefix = prefix[0:i] break } } h := fnv.New32() h.Write([]byte(prefix)) hs := h.Sum32() gl.Color4ub(gl.Ubyte(hs%256), gl.Ubyte((hs/256)%256), gl.Ubyte((hs/(256*256))%256), gl.Ubyte(255*rgba[3])) base.EnableShader("box") base.SetUniformF("box", "dx", float32(sp.Dx)) base.SetUniformF("box", "dy", float32(sp.Dy)) if !sp.temporary { base.SetUniformI("box", "temp_invalid", 0) } else if !sp.invalid { base.SetUniformI("box", "temp_invalid", 1) } else { base.SetUniformI("box", "temp_invalid", 2) } (&texture.Object{}).Data().Render(float64(sp.X), float64(sp.Y), float64(sp.Dx), float64(sp.Dy)) base.EnableShader("") gl.PopAttrib() }
func (e *Entity) drawReticle(pos mathgl.Vec2, rgba [4]float64) { if !e.hovered && !e.selected && !e.controlled { return } gl.PushAttrib(gl.CURRENT_BIT) r := gl.Ubyte(rgba[0] * 255) g := gl.Ubyte(rgba[1] * 255) b := gl.Ubyte(rgba[2] * 255) a := gl.Ubyte(rgba[3] * 255) switch { case e.controlled: gl.Color4ub(0, 0, r, a) case e.selected: gl.Color4ub(r, g, b, a) default: gl.Color4ub(r, g, b, gl.Ubyte((int(a)*200)>>8)) } glow := texture.LoadFromPath(filepath.Join(base.GetDataDir(), "ui", "glow.png")) dx := float64(e.last_render_width + 0.5) dy := float64(e.last_render_width * 150 / 100) glow.Render(float64(pos.X), float64(pos.Y), dx, dy) gl.PopAttrib() }
func (ob *OptionBasic) Draw(x, y, dx int) { gl.Color4ub(255, 255, 255, gl.Ubyte(ob.alpha)) ob.Small.Data().RenderNatural(x, y) }
// Need floor, right wall, and left wall matrices to draw the details func (room *Room) render(floor, left, right mathgl.Mat4, zoom float32, base_alpha byte, drawables []Drawable, los_tex *LosTexture, floor_drawers []FloorDrawer) { do_color := func(r, g, b, a byte) { R, G, B, A := room.Color() A = alphaMult(A, base_alpha) gl.Color4ub(gl.Ubyte(alphaMult(R, r)), gl.Ubyte(alphaMult(G, g)), gl.Ubyte(alphaMult(B, b)), gl.Ubyte(alphaMult(A, a))) } gl.Enable(gl.TEXTURE_2D) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Enable(gl.STENCIL_TEST) gl.ClearStencil(0) gl.Clear(gl.STENCIL_BUFFER_BIT) gl.EnableClientState(gl.VERTEX_ARRAY) gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) defer gl.DisableClientState(gl.VERTEX_ARRAY) defer gl.DisableClientState(gl.TEXTURE_COORD_ARRAY) var vert roomVertex planes := []plane{ {room.left_buffer, room.Wall, &left}, {room.right_buffer, room.Wall, &right}, {room.floor_buffer, room.Floor, &floor}, } gl.PushMatrix() defer gl.PopMatrix() if los_tex != nil { gl.LoadMatrixf((*gl.Float)(&floor[0])) gl.ClientActiveTexture(gl.TEXTURE1) gl.ActiveTexture(gl.TEXTURE1) gl.Enable(gl.TEXTURE_2D) gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) los_tex.Bind() gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(room.vbuffer)) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u))) gl.ClientActiveTexture(gl.TEXTURE0) gl.ActiveTexture(gl.TEXTURE0) base.EnableShader("los") base.SetUniformI("los", "tex2", 1) } var mul, run mathgl.Mat4 for _, plane := range planes { gl.LoadMatrixf((*gl.Float)(&floor[0])) run.Assign(&floor) // Render the doors and cut out the stencil buffer so we leave them empty // if they're open switch plane.mat { case &left: gl.StencilFunc(gl.ALWAYS, 1, 1) gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE) for _, door := range room.Doors { if door.Facing != FarLeft { continue } door.TextureData().Bind() R, G, B, A := door.Color() do_color(R, G, B, alphaMult(A, room.far_left.wall_alpha)) gl.ClientActiveTexture(gl.TEXTURE0) door.TextureData().Bind() if door.door_glids.floor_buffer != 0 { gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(door.threshold_glids.vbuffer)) gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x))) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(door.door_glids.floor_buffer)) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u))) gl.ClientActiveTexture(gl.TEXTURE1) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u))) gl.DrawElements(gl.TRIANGLES, door.door_glids.floor_count, gl.UNSIGNED_SHORT, nil) } } gl.StencilFunc(gl.NOTEQUAL, 1, 1) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) do_color(255, 255, 255, room.far_left.wall_alpha) case &right: gl.StencilFunc(gl.ALWAYS, 1, 1) gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE) for _, door := range room.Doors { if door.Facing != FarRight { continue } door.TextureData().Bind() R, G, B, A := door.Color() do_color(R, G, B, alphaMult(A, room.far_right.wall_alpha)) gl.ClientActiveTexture(gl.TEXTURE0) door.TextureData().Bind() if door.door_glids.floor_buffer != 0 { gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(door.threshold_glids.vbuffer)) gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x))) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(door.door_glids.floor_buffer)) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u))) gl.ClientActiveTexture(gl.TEXTURE1) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u))) gl.DrawElements(gl.TRIANGLES, door.door_glids.floor_count, gl.UNSIGNED_SHORT, nil) } } gl.StencilFunc(gl.NOTEQUAL, 1, 1) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) do_color(255, 255, 255, room.far_right.wall_alpha) case &floor: gl.StencilFunc(gl.ALWAYS, 2, 2) gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE) do_color(255, 255, 255, 255) } gl.ClientActiveTexture(gl.TEXTURE0) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(room.vbuffer)) gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x))) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u))) gl.ClientActiveTexture(gl.TEXTURE1) if los_tex != nil { los_tex.Bind() } gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(room.vbuffer)) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u))) // Now draw the walls gl.LoadMatrixf((*gl.Float)(&floor[0])) plane.texture.Data().Bind() gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(plane.index_buffer)) if (plane.mat == &left || plane.mat == &right) && strings.Contains(string(room.Wall.Path), "gradient.png") { base.EnableShader("gorey") base.SetUniformI("gorey", "tex", 0) base.SetUniformI("gorey", "foo", Foo) base.SetUniformF("gorey", "num_rows", Num_rows) base.SetUniformF("gorey", "noise_rate", Noise_rate) base.SetUniformF("gorey", "num_steps", Num_steps) } if plane.mat == &floor && strings.Contains(string(room.Floor.Path), "gradient.png") { base.EnableShader("gorey") base.SetUniformI("gorey", "tex", 0) base.SetUniformI("gorey", "foo", Foo) base.SetUniformF("gorey", "num_rows", Num_rows) base.SetUniformF("gorey", "noise_rate", Noise_rate) base.SetUniformF("gorey", "num_steps", Num_steps) zexp := math.Log(float64(zoom)) frac := 1 - 1/zexp frac = (frac - 0.6) * 5.0 switch { case frac > 0.7: base.SetUniformI("gorey", "range", 1) case frac > 0.3: base.SetUniformI("gorey", "range", 2) default: base.SetUniformI("gorey", "range", 3) } } if plane.mat == &floor { R, G, B, _ := room.Color() gl.Color4ub(gl.Ubyte(R), gl.Ubyte(G), gl.Ubyte(B), 255) } gl.DrawElements(gl.TRIANGLES, gl.Sizei(room.floor_count), gl.UNSIGNED_SHORT, nil) if los_tex != nil { base.EnableShader("los") } else { base.EnableShader("") } } for _, wt := range room.WallTextures { if room.wall_texture_gl_map == nil { room.wall_texture_gl_map = make(map[*WallTexture]wallTextureGlIds) room.wall_texture_state_map = make(map[*WallTexture]wallTextureState) } ids := room.wall_texture_gl_map[wt] state := room.wall_texture_state_map[wt] var new_state wallTextureState new_state.flip = wt.Flip new_state.rot = wt.Rot new_state.x = wt.X new_state.y = wt.Y new_state.room.x = room.X new_state.room.y = room.Y new_state.room.dx = room.Size.Dx new_state.room.dy = room.Size.Dy if new_state != state { wt.setupGlStuff(room.X, room.Y, room.Size.Dx, room.Size.Dy, &ids) room.wall_texture_gl_map[wt] = ids room.wall_texture_state_map[wt] = new_state } gl.LoadMatrixf((*gl.Float)(&floor[0])) if ids.vbuffer != 0 { wt.Texture.Data().Bind() R, G, B, A := wt.Color() gl.ClientActiveTexture(gl.TEXTURE0) gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(ids.vbuffer)) gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x))) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u))) gl.ClientActiveTexture(gl.TEXTURE1) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u))) gl.ClientActiveTexture(gl.TEXTURE0) if ids.floor_buffer != 0 { gl.StencilFunc(gl.ALWAYS, 2, 2) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(ids.floor_buffer)) gl.Color4ub(gl.Ubyte(R), gl.Ubyte(G), gl.Ubyte(B), gl.Ubyte(A)) gl.DrawElements(gl.TRIANGLES, ids.floor_count, gl.UNSIGNED_SHORT, nil) } if ids.left_buffer != 0 { gl.StencilFunc(gl.ALWAYS, 1, 1) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(ids.left_buffer)) do_color(R, G, B, alphaMult(A, room.far_left.wall_alpha)) gl.DrawElements(gl.TRIANGLES, ids.left_count, gl.UNSIGNED_SHORT, nil) } if ids.right_buffer != 0 { gl.StencilFunc(gl.ALWAYS, 1, 1) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(ids.right_buffer)) do_color(R, G, B, alphaMult(A, room.far_right.wall_alpha)) gl.DrawElements(gl.TRIANGLES, ids.right_count, gl.UNSIGNED_SHORT, nil) } } } base.EnableShader("marble") base.SetUniformI("marble", "tex2", 1) base.SetUniformF("marble", "room_x", float32(room.X)) base.SetUniformF("marble", "room_y", float32(room.Y)) for _, door := range room.Doors { door.setupGlStuff(room) if door.threshold_glids.vbuffer == 0 { continue } if door.AlwaysOpen() { continue } if door.highlight_threshold { gl.Color4ub(255, 255, 255, 255) } else { gl.Color4ub(128, 128, 128, 255) } gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(door.threshold_glids.vbuffer)) gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x))) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u))) gl.ClientActiveTexture(gl.TEXTURE1) gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u))) gl.ClientActiveTexture(gl.TEXTURE0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Uint(door.threshold_glids.floor_buffer)) gl.DrawElements(gl.TRIANGLES, door.threshold_glids.floor_count, gl.UNSIGNED_SHORT, nil) } base.EnableShader("") if los_tex != nil { base.EnableShader("") gl.ActiveTexture(gl.TEXTURE1) gl.Disable(gl.TEXTURE_2D) gl.ActiveTexture(gl.TEXTURE0) gl.ClientActiveTexture(gl.TEXTURE1) gl.DisableClientState(gl.TEXTURE_COORD_ARRAY) gl.ClientActiveTexture(gl.TEXTURE0) } run.Assign(&floor) mul.Translation(float32(-room.X), float32(-room.Y), 0) run.Multiply(&mul) gl.LoadMatrixf((*gl.Float)(&run[0])) gl.StencilFunc(gl.EQUAL, 2, 3) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) room_rect := image.Rect(room.X, room.Y, room.X+room.Size.Dx, room.Y+room.Size.Dy) for _, fd := range floor_drawers { x, y := fd.Pos() dx, dy := fd.Dims() if room_rect.Overlaps(image.Rect(x, y, x+dx, y+dy)) { fd.RenderOnFloor() } } do_color(255, 255, 255, 255) gl.LoadIdentity() gl.Disable(gl.STENCIL_TEST) room.renderFurniture(floor, 255, drawables, los_tex) gl.ClientActiveTexture(gl.TEXTURE1) gl.Disable(gl.TEXTURE_2D) gl.ClientActiveTexture(gl.TEXTURE0) base.EnableShader("") }
func (room *Room) renderFurniture(floor mathgl.Mat4, base_alpha byte, drawables []Drawable, los_tex *LosTexture) { board_to_window := func(mx, my float32) (x, y float32) { v := mathgl.Vec4{X: mx, Y: my, W: 1} v.Transform(&floor) x, y = v.X, v.Y return } var all []RectObject for _, d := range drawables { x, y := d.Pos() if x < room.X { continue } if y < room.Y { continue } if x >= room.X+room.Size.Dx { continue } if y >= room.Y+room.Size.Dy { continue } all = append(all, offsetDrawable{d, -room.X, -room.Y}) } // Do not include temporary objects in the ordering, since they will likely // overlap with other objects and make it difficult to determine the proper // ordering. Just draw the temporary ones last. var temps []RectObject for _, f := range room.Furniture { if f.temporary { temps = append(temps, f) } else { all = append(all, f) } } all = OrderRectObjects(all) for i := range all { temps = append(temps, all[i]) } for i := len(temps) - 1; i >= 0; i-- { d := temps[i].(Drawable) fx, fy := d.FPos() near_x, near_y := float32(fx), float32(fy) idx, idy := d.Dims() dx, dy := float32(idx), float32(idy) leftx, _ := board_to_window(near_x, near_y+dy) rightx, _ := board_to_window(near_x+dx, near_y) _, boty := board_to_window(near_x, near_y) vis := visibilityOfObject(room.X, room.Y, d, los_tex) r, g, b, a := d.Color() r = alphaMult(r, vis) g = alphaMult(g, vis) b = alphaMult(b, vis) a = alphaMult(a, vis) a = alphaMult(a, base_alpha) gl.Color4ub(gl.Ubyte(r), gl.Ubyte(g), gl.Ubyte(b), gl.Ubyte(a)) d.Render(mathgl.Vec2{leftx, boty}, rightx-leftx) } }