func (vb *VertexBuffer) Render(position Point3) { gl.PushMatrix() gl.Translated( gl.Double(position.X), gl.Double(position.Y), gl.Double(position.Z)) gl.VertexPointer( gl.Int(3), gl.DOUBLE, 0, gl.Pointer(&vb.VertexData[0])) gl.ColorPointer( gl.Int(4), gl.DOUBLE, 0, gl.Pointer(&vb.ColorData[0])) gl.TexCoordPointer( gl.Int(2), gl.DOUBLE, 0, gl.Pointer(&vb.TexCoordData[0])) for i := range vb.RenderSteps { rs := &vb.RenderSteps[i] gl.DrawElements( rs.Mode, gl.Sizei(len(rs.Indices)), gl.UNSIGNED_INT, gl.Pointer(&rs.Indices[0])) } gl.PopMatrix() }
func (m *Model) draw() { m.shader.use() gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, m.texture_id) gl.Uniform1i(m.shader.uniform_texture, 0) //texcoord if m.has_uv { gl.BindBuffer(gl.ARRAY_BUFFER, m.texcoord) gl.EnableVertexAttribArray(m.shader.attribute_texcoord) gl.VertexAttribPointer( m.shader.attribute_texcoord, 2, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil)) } gl.BindBuffer(gl.ARRAY_BUFFER, m.buffer) gl.EnableVertexAttribArray(m.shader.attribute_vertex) gl.VertexAttribPointer( m.shader.attribute_vertex, 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil)) gl.BindBuffer(gl.ARRAY_BUFFER, m.normal_buf) gl.EnableVertexAttribArray(m.shader.attribute_normal) gl.VertexAttribPointer( m.shader.attribute_normal, 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, m.index) gl.DrawElements(gl.TRIANGLES, gl.Sizei(len(m.indices)), gl.UNSIGNED_INT, gl.Pointer(nil)) gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) gl.DisableVertexAttribArray(m.shader.attribute_vertex) gl.DisableVertexAttribArray(m.shader.attribute_normal) if m.has_uv { gl.DisableVertexAttribArray(m.shader.attribute_texcoord) } }
// 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(alphaMult(R, r), alphaMult(G, g), alphaMult(B, b), 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(&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, 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(&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, 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, 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, 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, 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, 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, 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(&floor[0]) plane.texture.Data().Bind() gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 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(R, G, 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(&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, 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, ids.floor_buffer) gl.Color4ub(R, G, B, 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, 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, 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, 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, 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(&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 (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 }