Недавно я играл с open-gl, в конце концов я решил сам попробовать и написать свой собственный простой движок для 2D-игр, к сожалению, по какой-то причине при попытке рендеринга нескольких анимируемых спрайтов я получаю нарушение доступаИсключение 0xc0000005, которое, похоже, происходит из-за привязок open-gl Cgo. Я предоставляю весь код, необходимый для воспроизведения проблемы ниже. Я старался комментировать как можно больше, чтобы было легче разобрать. Я был бы более чем счастлив получить любую форму руководства, потому что я, честно говоря, не понимаю, почему это происходит, и, похоже, не могу найти какие-либо ресурсы в Интернете для решения этой проблемы.
более важные сторонние операции импорта;
"github.com/go-gl/glfw/v3.1/glfw"
"github.com/go-gl/mathgl/mgl32"
"github.com/go-gl/gl/v4.1-core/gl"
основной цикл;
func main() {
window := new(Window)
window.NewWindow(wsize, wheight)
}
функция window.NewWindow;
func (w *Window) NewWindow(width, height int) {
if err := glfw.Init(); err != nil {
log.Fatalln("failed to inifitialize glfw:", err)
}
defer glfw.Terminate()
glfw.WindowHint(glfw.ContextVersionMajor, 4)
glfw.WindowHint(glfw.ContextVersionMinor, 1)
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
window, err := glfw.CreateWindow(width, height, "Primitive renderer", nil, nil)
if err != nil {
panic(err)
}
window.MakeContextCurrent()
if err := gl.Init(); err != nil {
panic(err)
}
w.Handle = window
vs, err := NewShaderFromFile("./shaders/basic.vert", gl.VERTEX_SHADER)
if err != nil {
panic(err)
}
fs, err := NewShaderFromFile("./shaders/basic.frag", gl.FRAGMENT_SHADER)
if err != nil {
panic(err)
}
p, err = NewProgram(vs, fs)
if err != nil {
panic(err)
}
p.Use()
gl.Disable(gl.DEPTH_TEST)
gl.Enable(gl.BLEND)
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
// set orthographic projection:
projection := mgl32.Ortho2D(0, float32(wsize), float32(wheight), 0)
prUniformLocation := p.GetUniformLocation("projection")
gl.UniformMatrix4fv(prUniformLocation, 1, false, &projection[0])
// 2d sampler:
spUniformLocation:= gl.GetUniformLocation(p.handle, gl.Str("tsampler\x00"))
gl.Uniform1i(spUniformLocation, gl.TEXTURE0)
// generate a quad (generates vao, vbo, ebo):
quad := NewBuffer(quad, indices)
// load textures for a given object;
t1, err := NewTextureFromFile("./textures/x.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE)
if err != nil {
panic(err)
}
trUniformLocation := p.GetUniformLocation("transformation")
for !window.ShouldClose() {
glfw.PollEvents()
// background color;
gl.ClearColor(1.0, 1.0, 1.0, 1.0)
gl.Clear(gl.COLOR_BUFFER_BIT)
// bind the quad buffer;
gl.BindVertexArray(quad.vao)
// paint 5000 quads:
for i := 0; i < 5000; i++ {
transformation := mgl32.Translate3D(32, 32, 1)
transformation = transformation.Mul4(mgl32.Scale3D(32, 32, 1))
gl.UniformMatrix4fv(trUniformLocation, 1, false, &transformation[0])
gl.BindTexture(gl.TEXTURE_2D, t1[0].handle)
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, gl.PtrOffset(0))
}
gl.BindVertexArray(0)
window.SwapBuffers()
}
}
функция NewTextureFromFile
func NewTexture(img image.Image, wrapR, wrapS int32) []*Texture {
rgba := image.NewRGBA(img.Bounds())
draw.Draw(rgba, rgba.Bounds(), img, image.Pt(0, 0), draw.Src)
if rgba.Stride != rgba.Rect.Size().X*4 {
fmt.Printf("Unsupported stride\n")
}
// number of textures generated;
h := make([]uint32, 5)
gl.GenTextures(5, &h[0])
target := uint32(gl.TEXTURE_2D)
internalFmt := int32(gl.SRGB_ALPHA)
format := uint32(gl.RGBA)
pixType := uint32(gl.UNSIGNED_BYTE)
dataPtr := gl.Ptr(rgba.Pix)
var rtextures = make([]*Texture, 0)
for i := 0; i < 5; i++ {
gl.BindTexture(gl.TEXTURE_2D, h[i])
defer gl.BindTexture(gl.TEXTURE_2D, 0)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, wrapR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
row, column := i%12, int(math.Floor(float64(i/12)))
gl.PixelStorei(gl.UNPACK_ROW_LENGTH, int32(rgba.Rect.Size().X))
gl.PixelStorei(gl.UNPACK_SKIP_PIXELS, int32(32*row))
gl.PixelStorei(gl.UNPACK_SKIP_ROWS, int32(32*column))
gl.TexImage2D(target, 0, internalFmt, 32, 32, 0, format, pixType, dataPtr)
gl.PixelStorei(gl.UNPACK_ROW_LENGTH, 0)
gl.PixelStorei(gl.UNPACK_SKIP_PIXELS, 0)
gl.PixelStorei(gl.UNPACK_SKIP_ROWS, 0)
gl.GenerateMipmap(h[i])
t := &Texture{
handle: h[i],
}
rtextures = append(rtextures, t)
}
return rtextures
}
шейдеры;
vs:
#version 410 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 text_coord_in;
uniform mat4 projection;
uniform mat4 transformation;
uniform vec3 colors;
out vec2 text_coord;
out vec3 colors_fs;
void main() {
colors_fs = colors;
text_coord = text_coord_in;
gl_Position = projection * transformation * vec4(position, 1.0);
}
fs:
#version 410 core
out vec4 color;
in vec2 text_coord;
in vec3 colors_fs;
uniform sampler2D tsampler;
void main() {
color = texture(tsampler, text_coord);
}
Exception 0xc0000005 0x0 0x12d8 0x5d37c839
PC=0x5d37c839
runtime: unknown pc 0x5d37c839
stack: frame={sp:0x388fe28, fp:0x0} stack=[0x0,0x388fe80)
000000000388fd28: 000000000388fd80 0000000000428310
[...]
callstack:
goroutine 1 [syscall]:
github.com/go-gl/gl/v4.1-core/gl._Cfunc_glowUniformMatrix4fv(0x5d37c830, 0x100000001, 0x3f80000000000000, 0xc0003f4040)
_cgo_gotypes.go:21291 +0x4c
github.com/go-gl/gl/v4.1-core/gl.UniformMatrix4fv(...)
C:/Users/x/go/src/github.com/go-gl/gl/v4.1-core/gl/package.go:12659
main.(*Window).NewWindow(0xc000081f78, 0x12c, 0x12c)
C:/Users/x/go/src/github.com/a/index.go:216 +0xa6f
main.main()
C:/Users/x/go/src/github.com/a/index.go:44 +0x5b
rax 0x0
rbx 0xc000425c48
rcx 0x1
rdi 0xc000425c48
[...]