go - GLFW/OpenGL - Texture created with different context has black border on WIndows -
i sorry, tried minify code still has 350 lines of code. know, opengl verbose, vertices coordinates, glue code , other stuff. decided better upload github. requires square.png
file being located nearby .exe
file. (just in case, modified example here)
here i'll try explain issue. doing multithreaded rendering. since glfw window-related staff must located in main thread, i've written code execute function other thread in main thread's context (runinmainthread(fn func())
). idea create hidden window on application startup , use shared context other windows. main thread used handling glfw events serving requests secondary threads window creation (and other staff in future)
when real window created, goroutine locked os thread created rendering loop of window (line 182: go func() {...
)
now, problem? problem when load texture before creation of real window (line 18) displays well: if try create window first , load texture shared context , use window's context (line 34) appears displayed strange black border! spent several hours trying understand reason of behavior without luck. hope tell me did mistake.
the strangest thing - see behavior on windows. however, on linux, can call windows creation secondary threads, seems restrictions weaker there in general.
update tried remove non-important 130 lines of code remains shaders, imports , other staff. here is:
package main import ( "github.com/go-gl/gl/v4.5-core/gl" "github.com/go-gl/glfw/v3.2/glfw" "github.com/go-gl/mathgl/mgl32" "golang.org/x/image/draw" "image" _ "image/png" "os" "runtime" ) func main() { runtime.lockosthread() var transformuniform, textureuniform int32 var program, vbo, texture, vertattrib, texcoordattrib uint32 var transform = mgl32.ident4() glfw.init() sharecontext, _ := glfw.createwindow(100, 100, "", nil, nil) sharecontext.makecontextcurrent() gl.init() //texture = loadtexture("square.png") // texture loads here without issue window, _ := glfw.createwindow(800, 600, "", nil, sharecontext) go func() { runtime.lockosthread() window.makecontextcurrent() var vao uint32 gl.genvertexarrays(1, &vao) gl.bindvertexarray(vao) gl.genbuffers(1, &vbo) gl.bindbuffer(gl.array_buffer, vbo) gl.bufferdata(gl.array_buffer, len(cubevertices)*4, gl.ptr(cubevertices), gl.static_draw) !window.shouldclose() { gl.clearcolor(0, 0.1, 0, 0) gl.clear(gl.color_buffer_bit | gl.depth_buffer_bit) gl.bindbuffer(gl.array_buffer, vbo) gl.useprogram(program) gl.enable(gl.depth_test) gl.depthfunc(gl.less) gl.uniform1i(textureuniform, 0) gl.enablevertexattribarray(vertattrib) gl.enablevertexattribarray(texcoordattrib) gl.vertexattribpointer(vertattrib, 3, gl.float, false, 5*4, gl.ptroffset(0)) gl.vertexattribpointer(texcoordattrib, 2, gl.float, false, 5*4, gl.ptroffset(3*4)) gl.uniformmatrix4fv(transformuniform, 1, false, &transform[0]) gl.bindtexture(gl.texture_2d, texture) gl.drawarrays(gl.triangles, 0, 6*2*3) window.swapbuffers() } }() texture = loadtexture("square.png") // texture loaded here causes black border vertexshader, fragmentshader := compileshader(vertexshader, gl.vertex_shader), compileshader(fragmentshader, gl.fragment_shader) program = gl.createprogram() gl.attachshader(program, vertexshader) gl.attachshader(program, fragmentshader) gl.linkprogram(program) transform = mgl32.perspective(mgl32.degtorad(45.0), float32(800)/600, 0.1, 10.0).mul4(mgl32.lookatv(mgl32.vec3{3, 3, 3}, mgl32.vec3{0, 0, 0}, mgl32.vec3{0, 1, 0})).mul4(mgl32.homogrotate3d(float32(2.0), mgl32.vec3{0, 1, 0})) transformuniform, textureuniform = gl.getuniformlocation(program, gl.str("transform\x00")), gl.getuniformlocation(program, gl.str("tex\x00")) vertattrib, texcoordattrib = uint32(gl.getattriblocation(program, gl.str("vert\x00"))), uint32(gl.getattriblocation(program, gl.str("verttexcoord\x00"))) { glfw.waitevents() } } func compileshader(source string, shadertype uint32) uint32 { shader := gl.createshader(shadertype) csources, _ := gl.strs(source) gl.shadersource(shader, 1, csources, nil) gl.compileshader(shader) return shader } func loadtexture(filename string) uint32 { var id uint32 file, err := os.open(filename) if err != nil { panic(err) } img, _, _ := image.decode(file) rgba := image.newrgba(img.bounds()) draw.draw(rgba, rgba.bounds(), img, image.point{0, 0}, draw.src) gl.gentextures(1, &id) gl.bindtexture(gl.texture_2d, id) gl.texparameteri(gl.texture_2d, gl.texture_min_filter, gl.linear) gl.texparameteri(gl.texture_2d, gl.texture_mag_filter, gl.linear) gl.teximage2d(gl.texture_2d, 0, gl.rgba, int32(rgba.rect.size().x), int32(rgba.rect.size().y), 0, gl.rgba, gl.unsigned_byte, gl.ptr(rgba.pix)) return id } var vertexshader = ` #version 330 uniform mat4 transform; in vec3 vert; in vec2 verttexcoord; out vec2 fragtexcoord; void main() { fragtexcoord = verttexcoord; gl_position = transform * vec4(vert, 1); } ` + "\x00" var fragmentshader = ` #version 330 uniform sampler2d tex; in vec2 fragtexcoord; out vec4 outputcolor; void main() { outputcolor = texture(tex, fragtexcoord); } ` + "\x00" var cubevertices = []float32{-1.0, -1.0, -1.0, 0.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, -1.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, -1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0}
update duplicate of sharing textures between opengl contexts glfw3 not working - missed glfinish()
call
Comments
Post a Comment