Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
package levels
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
mgl "github.com/go-gl/mathgl/mgl32"
|
||||
|
||||
"github.com/inkyblackness/hacked/editor/graphics"
|
||||
"github.com/inkyblackness/hacked/editor/render"
|
||||
"github.com/inkyblackness/hacked/ss1/content/archive/level"
|
||||
"github.com/inkyblackness/hacked/ui/opengl"
|
||||
)
|
||||
|
||||
var mapTexturesVertexShaderSource = `
|
||||
#version 150
|
||||
precision mediump float;
|
||||
|
||||
in vec3 vertexPosition;
|
||||
|
||||
uniform mat4 modelMatrix;
|
||||
uniform mat4 viewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 uvMatrix;
|
||||
|
||||
out vec2 uv;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(vertexPosition, 1.0);
|
||||
|
||||
uv = (uvMatrix * vec4(vertexPosition, 1.0)).xy;
|
||||
}
|
||||
`
|
||||
|
||||
var mapTexturesFragmentShaderSource = `
|
||||
#version 150
|
||||
precision mediump float;
|
||||
|
||||
in vec2 uv;
|
||||
|
||||
uniform sampler2D palette;
|
||||
uniform sampler2D bitmap;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 pixel = texture(bitmap, uv);
|
||||
|
||||
fragColor = texture(palette, vec2(pixel.r, 0.5));
|
||||
}
|
||||
`
|
||||
|
||||
// TextureQuery is a getter function to retrieve the texture for the given
|
||||
// level texture index.
|
||||
type TextureQuery func(index level.TextureIndex) (*graphics.BitmapTexture, error)
|
||||
|
||||
// TileTextureQuery is a getter function to retrieve properties for rendering a texture of a tile.
|
||||
type TileTextureQuery func(pos level.TilePosition) (tileType level.TileType, textureIndex level.TextureIndex, textureRotations int)
|
||||
|
||||
// MapTextures is a renderable for textures.
|
||||
type MapTextures struct {
|
||||
context *render.Context
|
||||
|
||||
program uint32
|
||||
vao *opengl.VertexArrayObject
|
||||
vertexPositionBuffer uint32
|
||||
vertexPositionAttrib int32
|
||||
modelMatrixUniform opengl.Matrix4Uniform
|
||||
viewMatrixUniform opengl.Matrix4Uniform
|
||||
projectionMatrixUniform opengl.Matrix4Uniform
|
||||
uvMatrixUniform opengl.Matrix4Uniform
|
||||
|
||||
paletteUniform int32
|
||||
bitmapUniform int32
|
||||
|
||||
textureQuery TextureQuery
|
||||
|
||||
lastTileType level.TileType
|
||||
}
|
||||
|
||||
type tileTypeVertices struct {
|
||||
vertices []float32
|
||||
equivalentType level.TileType
|
||||
}
|
||||
|
||||
var tileTypeVerticesLookup []tileTypeVertices
|
||||
var uvRotations [4]*mgl.Mat4
|
||||
|
||||
func init() {
|
||||
for i := 0; i < 4; i++ {
|
||||
matrix := mgl.Translate3D(0.5, 0.5, 0.0).
|
||||
Mul4(mgl.HomogRotate3DZ(math.Pi * float32(i) / -2.0)).
|
||||
Mul4(mgl.Translate3D(-0.5, -0.5, 0.0)).
|
||||
Mul4(mgl.Scale3D(1.0, -1.0, 1.0))
|
||||
uvRotations[i] = &matrix
|
||||
}
|
||||
|
||||
for _, tileType := range level.TileTypes() {
|
||||
for int(tileType) >= len(tileTypeVerticesLookup) {
|
||||
tileTypeVerticesLookup = append(tileTypeVerticesLookup, tileTypeVertices{equivalentType: level.TileTypeSolid})
|
||||
}
|
||||
switch tileType {
|
||||
case level.TileTypeSolid:
|
||||
case level.TileTypeDiagonalOpenNorthEast:
|
||||
tileTypeVerticesLookup[int(tileType)] = tileTypeVertices{
|
||||
vertices: []float32{
|
||||
0.0, 1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
},
|
||||
equivalentType: level.TileTypeDiagonalOpenNorthEast,
|
||||
}
|
||||
case level.TileTypeDiagonalOpenNorthWest:
|
||||
tileTypeVerticesLookup[int(tileType)] = tileTypeVertices{
|
||||
vertices: []float32{
|
||||
0.0, 1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
},
|
||||
equivalentType: level.TileTypeDiagonalOpenNorthWest,
|
||||
}
|
||||
case level.TileTypeDiagonalOpenSouthEast:
|
||||
tileTypeVerticesLookup[int(tileType)] = tileTypeVertices{
|
||||
vertices: []float32{
|
||||
1.0, 1.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
},
|
||||
equivalentType: level.TileTypeDiagonalOpenSouthEast,
|
||||
}
|
||||
case level.TileTypeDiagonalOpenSouthWest:
|
||||
tileTypeVerticesLookup[int(tileType)] = tileTypeVertices{
|
||||
vertices: []float32{
|
||||
0.0, 1.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
},
|
||||
equivalentType: level.TileTypeDiagonalOpenSouthWest,
|
||||
}
|
||||
default:
|
||||
tileTypeVerticesLookup[int(tileType)] = tileTypeVertices{
|
||||
vertices: []float32{
|
||||
0.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
|
||||
1.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
},
|
||||
equivalentType: level.TileTypeOpen,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NewMapTextures returns a new instance of a renderable for tile map textures.
|
||||
func NewMapTextures(context *render.Context, textureQuery TextureQuery) *MapTextures {
|
||||
gl := context.OpenGL
|
||||
program, programErr := opengl.LinkNewStandardProgram(gl, mapTexturesVertexShaderSource, mapTexturesFragmentShaderSource)
|
||||
if programErr != nil {
|
||||
panic(opengl.NamedShaderError{Name: "MapTexturesShader", Nested: programErr})
|
||||
}
|
||||
renderable := &MapTextures{
|
||||
context: context,
|
||||
program: program,
|
||||
|
||||
vao: opengl.NewVertexArrayObject(gl, program),
|
||||
vertexPositionBuffer: gl.GenBuffers(1)[0],
|
||||
vertexPositionAttrib: gl.GetAttribLocation(program, "vertexPosition"),
|
||||
modelMatrixUniform: opengl.Matrix4Uniform(gl.GetUniformLocation(program, "modelMatrix")),
|
||||
viewMatrixUniform: opengl.Matrix4Uniform(gl.GetUniformLocation(program, "viewMatrix")),
|
||||
projectionMatrixUniform: opengl.Matrix4Uniform(gl.GetUniformLocation(program, "projectionMatrix")),
|
||||
uvMatrixUniform: opengl.Matrix4Uniform(gl.GetUniformLocation(program, "uvMatrix")),
|
||||
paletteUniform: gl.GetUniformLocation(program, "palette"),
|
||||
bitmapUniform: gl.GetUniformLocation(program, "bitmap"),
|
||||
textureQuery: textureQuery,
|
||||
lastTileType: level.TileTypeSolid,
|
||||
}
|
||||
|
||||
renderable.vao.WithSetter(func(gl opengl.OpenGL) {
|
||||
gl.EnableVertexAttribArray(uint32(renderable.vertexPositionAttrib))
|
||||
gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.vertexPositionBuffer)
|
||||
gl.VertexAttribOffset(uint32(renderable.vertexPositionAttrib), 3, opengl.FLOAT, false, 0, 0)
|
||||
gl.BindBuffer(opengl.ARRAY_BUFFER, 0)
|
||||
})
|
||||
|
||||
return renderable
|
||||
}
|
||||
|
||||
// Dispose releases any internal resources.
|
||||
func (renderable *MapTextures) Dispose() {
|
||||
gl := renderable.context.OpenGL
|
||||
|
||||
renderable.vao.Dispose()
|
||||
gl.DeleteProgram(renderable.program)
|
||||
gl.DeleteBuffers([]uint32{renderable.vertexPositionBuffer})
|
||||
}
|
||||
|
||||
// Render renders the textures.
|
||||
func (renderable *MapTextures) Render(columns, rows int, tileTextureQuery TileTextureQuery, paletteTexture *graphics.PaletteTexture) {
|
||||
gl := renderable.context.OpenGL
|
||||
|
||||
renderable.vao.OnShader(func() {
|
||||
renderable.viewMatrixUniform.Set(gl, renderable.context.ViewMatrix)
|
||||
renderable.projectionMatrixUniform.Set(gl, &renderable.context.ProjectionMatrix)
|
||||
|
||||
textureUnit := int32(0)
|
||||
gl.ActiveTexture(opengl.TEXTURE0 + uint32(textureUnit))
|
||||
gl.BindTexture(opengl.TEXTURE_2D, paletteTexture.Handle())
|
||||
gl.Uniform1i(renderable.paletteUniform, textureUnit)
|
||||
|
||||
textureUnit = 1
|
||||
gl.ActiveTexture(opengl.TEXTURE0 + uint32(textureUnit))
|
||||
gl.Uniform1i(renderable.bitmapUniform, textureUnit)
|
||||
|
||||
scaling := mgl.Scale3D(level.FineCoordinatesPerTileSide, level.FineCoordinatesPerTileSide, 1.0)
|
||||
for y := 0; y < rows; y++ {
|
||||
for x := 0; x < columns; x++ {
|
||||
tileType, textureIndex, textureRotations := tileTextureQuery(level.TilePosition{X: byte(x), Y: byte(y)})
|
||||
if tileType == level.TileTypeSolid {
|
||||
continue
|
||||
}
|
||||
texture, _ := renderable.textureQuery(textureIndex)
|
||||
if texture == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
modelMatrix := mgl.Translate3D(float32(x)*level.FineCoordinatesPerTileSide, float32(y)*level.FineCoordinatesPerTileSide, 0.0).
|
||||
Mul4(scaling)
|
||||
|
||||
uvMatrix := uvRotations[textureRotations]
|
||||
renderable.uvMatrixUniform.Set(gl, uvMatrix)
|
||||
renderable.modelMatrixUniform.Set(gl, &modelMatrix)
|
||||
gl.BindTexture(opengl.TEXTURE_2D, texture.Handle())
|
||||
renderable.renderTileType(tileType)
|
||||
}
|
||||
}
|
||||
|
||||
gl.BindTexture(opengl.TEXTURE_2D, 0)
|
||||
})
|
||||
}
|
||||
|
||||
func (renderable *MapTextures) renderTileType(tileType level.TileType) {
|
||||
info := tileTypeVerticesLookup[int(tileType)]
|
||||
vertexCount := len(info.vertices) / 3
|
||||
gl := renderable.context.OpenGL
|
||||
if info.equivalentType != renderable.lastTileType {
|
||||
renderable.lastTileType = info.equivalentType
|
||||
|
||||
gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.vertexPositionBuffer)
|
||||
gl.BufferData(opengl.ARRAY_BUFFER, len(info.vertices)*4, info.vertices, opengl.STATIC_DRAW)
|
||||
gl.BindBuffer(opengl.ARRAY_BUFFER, 0)
|
||||
}
|
||||
gl.DrawArrays(opengl.TRIANGLES, 0, int32(vertexCount))
|
||||
}
|
||||
Reference in New Issue
Block a user