func (r *EffectsRenderer) initFramebuffer(w, h int) (fb uint32, tex uint32, err error) { gl.GenFramebuffers(1, &fb) gl.BindFramebuffer(gl.FRAMEBUFFER, fb) gl.GenTextures(1, &tex) gl.BindTexture(gl.TEXTURE_2D, tex) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(w), int32(h), 0, gl.RGBA, gl.UNSIGNED_BYTE, nil) gl.FramebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) if err = r.GetError(); err != nil { return } buffers := []uint32{gl.COLOR_ATTACHMENT0} gl.DrawBuffers(1, &buffers[0]) var rb uint32 gl.GenRenderbuffers(1, &rb) gl.BindRenderbuffer(gl.RENDERBUFFER, rb) gl.RenderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, int32(w), int32(h)) gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb) gl.BindTexture(gl.TEXTURE_2D, 0) gl.BindFramebuffer(gl.FRAMEBUFFER, 0) gl.BindRenderbuffer(gl.RENDERBUFFER, 0) return }
func (r *GlowRenderer) Draw() (err error) { gl.UseProgram(r.shader) gl.Uniform1i(r.textureUnitLoc, 0) gl.BindBuffer(gl.ARRAY_BUFFER, r.coords) gl.EnableVertexAttribArray(r.positionLoc) gl.VertexAttribPointer(r.positionLoc, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(r.textureLoc) gl.VertexAttribPointer(r.textureLoc, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) gl.Uniform1i(r.blurAmountLoc, int32(r.blur)) gl.Uniform1f(r.blurScaleLoc, r.scale) gl.Uniform1f(r.blurStrengthLoc, r.strength) gl.Uniform2f(r.bufferDimensionsLoc, float32(r.width), float32(r.height)) gl.BindFramebuffer(gl.FRAMEBUFFER, r.BlurFb) gl.Viewport(0, 0, int32(r.width), int32(r.height)) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, r.GlowTex) gl.Uniform1i(r.orientationLoc, 0) gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) gl.BindFramebuffer(gl.FRAMEBUFFER, 0) gl.Viewport(0, 0, int32(r.oldwidth), int32(r.oldheight)) gl.BlendFunc(gl.ONE, gl.ONE) gl.BindTexture(gl.TEXTURE_2D, r.BlurTex) gl.Uniform1i(r.orientationLoc, 1) gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) return nil }
func getGLTexture(img image.Image, smoothing TextureSmoothing) (t uint32, err error) { var ( data *bytes.Buffer bounds image.Rectangle width int height int ) if data, err = imageBytes(img); err != nil { return } bounds = img.Bounds() width = bounds.Max.X - bounds.Min.X height = bounds.Max.Y - bounds.Min.Y gl.GenTextures(1, &t) gl.BindTexture(gl.TEXTURE_2D, t) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int32(smoothing)) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int32(smoothing)) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_INT_8_8_8_8, gl.Ptr(data.Bytes()), ) gl.GenerateMipmap(gl.TEXTURE_2D) gl.BindTexture(gl.TEXTURE_2D, 0) return }
func LoadText(f *Font) (t *Text) { t = new(Text) t.font = f // text hover values // "resting state" of a text object is the min scale t.ScaleMin = 1.0 t.ScaleMax = 1.1 t.SetScale(1) // size of glfloat glfloat_size := int32(4) // stride of the buffered data xy_count := int32(2) stride := xy_count + int32(2) gl.GenVertexArrays(1, &t.vao) gl.GenBuffers(1, &t.vbo) gl.GenBuffers(1, &t.ebo) // vao gl.BindVertexArray(t.vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, t.font.textureID) // vbo // specify the buffer for which the VertexAttribPointer calls apply gl.BindBuffer(gl.ARRAY_BUFFER, t.vbo) gl.EnableVertexAttribArray(t.font.centeredPosition) gl.VertexAttribPointer( t.font.centeredPosition, 2, gl.FLOAT, false, glfloat_size*stride, gl.PtrOffset(0), ) gl.EnableVertexAttribArray(t.font.uv) gl.VertexAttribPointer( t.font.uv, 2, gl.FLOAT, false, glfloat_size*stride, gl.PtrOffset(int(glfloat_size*xy_count)), ) // ebo gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, t.ebo) // i am guessing that order is important here gl.BindVertexArray(0) gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) return t }
func (t *Text) Draw() { if t.IsDebug { t.BoundingBox.Draw() } gl.UseProgram(t.font.program) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, t.font.textureID) // uniforms gl.Uniform1i(t.font.fragmentTextureUniform, 0) gl.Uniform4fv(t.font.colorUniform, 1, &t.color[0]) gl.Uniform2fv(t.font.finalPositionUniform, 1, &t.finalPosition[0]) gl.UniformMatrix4fv(t.font.orthographicMatrixUniform, 1, false, &t.font.OrthographicMatrix[0]) gl.UniformMatrix4fv(t.font.scaleMatrixUniform, 1, false, &t.scaleMatrix[0]) // draw drawCount := int32(t.RuneCount * 6) if drawCount > int32(t.eboIndexCount) { drawCount = int32(t.eboIndexCount) } if drawCount < 0 { drawCount = 0 } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.BindVertexArray(t.vao) gl.DrawElements(gl.TRIANGLES, drawCount, gl.UNSIGNED_INT, nil) gl.BindVertexArray(0) gl.Disable(gl.BLEND) }
func newTexture(file string, texNum uint32) (uint32, error) { imgFile, err := os.Open(file) if err != nil { return 0, err } img, _, err := image.Decode(imgFile) rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return 0, fmt.Errorf("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.ZP, draw.Src) var texture uint32 gl.GenTextures(1, &texture) gl.ActiveTexture(texNum) gl.BindTexture(gl.TEXTURE_2D, texture) 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 texture, nil }
func (t *Texture) Delete() { if t.id != 0 { gl.BindTexture(gl.TEXTURE_2D, 0) gl.DeleteTextures(1, &t.id) t.id = 0 } }
func (tr *TextRenderer) Draw(tex *Texture, x, y, scale float32) (err error) { gl.ActiveTexture(gl.TEXTURE0) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.BindTexture(gl.TEXTURE_2D, tex.Texture) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.Uniform3f(tr.ScaleLoc, float32(tex.Width)*scale, float32(tex.Height)*scale, 1) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.Uniform3f(tr.TransLoc, x, y, 0) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.BindBuffer(gl.ARRAY_BUFFER, 0) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } return nil }
func (texture Texture) Bind(textureSlot int) { if textureSlot > int(gl.TEXTURE31) { tlog.Panic("active texture slot too large: ", textureSlot) } gl.ActiveTexture(uint32(gl.TEXTURE0 + textureSlot)) Check() gl.BindTexture(gl.TEXTURE_2D, uint32(texture)) Check() }
func GetGLTexture(img image.Image, smoothing TextureSmoothing) (t uint32, err error) { var ( data *bytes.Buffer bounds image.Rectangle width int height int ) if data, err = imageBytes(img); err != nil { return } bounds = img.Bounds() width = bounds.Max.X - bounds.Min.X height = bounds.Max.Y - bounds.Min.Y gl.GenTextures(1, &t) if e := gl.GetError(); e != 0 { fmt.Printf("ggt1 ERROR: %s\n", e) } gl.BindTexture(gl.TEXTURE_2D, t) if e := gl.GetError(); e != 0 { fmt.Printf("ggt2 ERROR: %s\n", e) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int32(smoothing)) if e := gl.GetError(); e != 0 { fmt.Printf("ggt3 ERROR: %s\n", e) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int32(smoothing)) if e := gl.GetError(); e != 0 { fmt.Printf("ggt4 ERROR: %s\n", e) } gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_INT_8_8_8_8, gl.Ptr(data.Bytes())) if e := gl.GetError(); e != 0 { fmt.Printf("ggt5 ERROR: %s\n", e) } gl.GenerateMipmap(gl.TEXTURE_2D) if e := gl.GetError(); e != 0 { fmt.Printf("ggt6 ERROR: %s\n", e) } gl.BindTexture(gl.TEXTURE_2D, 0) if e := gl.GetError(); e != 0 { fmt.Printf("ggt7 ERROR: %s\n", e) } return }
func (r *EffectsRenderer) Delete() error { gl.BindTexture(gl.TEXTURE_2D, 0) gl.BindFramebuffer(gl.FRAMEBUFFER, 0) gl.BindRenderbuffer(gl.RENDERBUFFER, 0) gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.DeleteFramebuffers(1, &r.framebuffer) gl.DeleteTextures(1, &r.texture) gl.DeleteBuffers(1, &r.coords) return r.GetError() }
func (r *GlowRenderer) Delete() error { gl.BindTexture(gl.TEXTURE_2D, 0) gl.BindFramebuffer(gl.FRAMEBUFFER, 0) gl.BindRenderbuffer(gl.RENDERBUFFER, 0) gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.DeleteFramebuffers(1, &r.GlowFb) gl.DeleteTextures(1, &r.GlowTex) gl.DeleteFramebuffers(1, &r.BlurFb) gl.DeleteTextures(1, &r.BlurTex) gl.DeleteBuffers(1, &r.coords) return r.GetError() }
func (renderObject *RenderObject) Render() { gl.BindVertexArray(renderObject.vao) gl.BindBuffer(gl.ARRAY_BUFFER, renderObject.vbo) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderObject.ebo) gl.UseProgram(renderObject.shaderProgram) // Binding the texture. gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, renderObject.texture) gl.BindFragDataLocation(renderObject.shaderProgram, 0, gl.Str("outputColor\x00")) // Drawing the object. gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil) }
func createTexture(textureUnit uint32, rgba *image.RGBA) (uint32, error) { var texture uint32 gl.GenTextures(1, &texture) gl.ActiveTexture(textureUnit) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) 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 texture, nil }
// Attempting to load a Texture from a given location on the disk. func LoadTexture(path string) (Texture, error) { // Loading the image data. imgFile, err := os.Open(path) if err != nil { return 0, err } img, _, err := image.Decode(imgFile) if err != nil { return 0, err } rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return 0, errors.New("Unsupported stride.") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) // Generating and populating the texture. var texture uint32 gl.GenTextures(1, &texture) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) 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 Texture(texture), nil }
// RenderString must be called on the render thread. x and y are the initial position of the pen, // in screen coordinates, and height is the height of a full line of text, in screen coordinates. func (d *Dictionary) RenderString(str string, x, y, height float64) { if str == "" { return } // No synchronization necessary because everything is run serially on the render thread anyway. if d.strs == nil { d.strs = make(map[string]strData) } data, ok := d.strs[str] if !ok { data = d.bindString(str) d.strs[str] = data } render.EnableShader("glop.font") defer render.EnableShader("") gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, d.atlas.texture) location, _ := render.GetUniformLocation("glop.font", "tex") gl.Uniform1i(location, 0) gl.BindSampler(0, d.atlas.sampler) location, _ = render.GetUniformLocation("glop.font", "height") gl.Uniform1f(location, float32(height)) var viewport [4]int32 gl.GetIntegerv(gl.VIEWPORT, &viewport[0]) location, _ = render.GetUniformLocation("glop.font", "screen") gl.Uniform2f(location, float32(viewport[2]), float32(viewport[3])) location, _ = render.GetUniformLocation("glop.font", "pen") gl.Uniform2f(location, float32(x)+float32(viewport[0]), float32(y)+float32(viewport[1])) location, _ = render.GetUniformLocation("glop.font", "textColor") gl.Uniform3f(location, d.color[0], d.color[1], d.color[2]) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.BindVertexArray(data.varrays[0]) gl.DrawArrays(gl.TRIANGLES, 0, data.count) }
func LoadImageToTexture(filePath string) (glTex uint32, e error) { gl.GenTextures(1, &glTex) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, glTex) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) rgba_flipped, err := loadFile(filePath) if err != nil { return glTex, err } imageSize := int32(rgba_flipped.Bounds().Max.X) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, imageSize, imageSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba_flipped.Pix)) gl.GenerateMipmap(gl.TEXTURE_2D) return glTex, nil }
func (r *EffectsRenderer) Draw() (err error) { gl.UseProgram(r.shader) gl.Uniform1i(r.textureUnitLoc, 0) gl.Uniform3f(r.colorLoc, r.Color[0], r.Color[1], r.Color[2]) gl.BindBuffer(gl.ARRAY_BUFFER, r.coords) gl.EnableVertexAttribArray(r.positionLoc) gl.VertexAttribPointer(r.positionLoc, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(r.textureLoc) gl.VertexAttribPointer(r.textureLoc, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) gl.BindFramebuffer(gl.FRAMEBUFFER, 0) gl.Viewport(0, 0, int32(r.oldwidth), int32(r.oldheight)) gl.BlendFunc(gl.ONE, gl.ONE) gl.BindTexture(gl.TEXTURE_2D, r.texture) gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) return nil }
func CreateTexture(file string) (Texture, error) { imgFile, err := os.Open(file) if err != nil { return Texture{}, err } img, _, err := image.Decode(imgFile) if err != nil { return Texture{}, err } rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return Texture{}, fmt.Errorf("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) width, height := int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y) var texture uint32 gl.GenTextures(1, &texture) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix)) return Texture{Id: texture, Width: width, Height: height}, nil }
func bindAggregateImage(img image.Image, idx int) uint32 { newIdx := idx if rgba, ok := img.(*image.RGBA); ok { gl.GenTextures(1, &textures[newIdx]) gl.ActiveTexture(gl.TEXTURE0 + uint32(newIdx)) gl.BindTexture(gl.TEXTURE_2D, textures[newIdx]) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE) 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)) gl.GenerateMipmap(gl.TEXTURE_2D) idxS := strconv.Itoa(newIdx) fmt.Println("idx: ", int32(newIdx), "myTextureSampler["+idxS+"]\x00") gl.Uniform1i(gl.GetUniformLocation(program, gl.Str("myTextureSampler["+idxS+"]\x00")), int32(newIdx)) if ok := gl.GetError(); ok != gl.NO_ERROR { fmt.Println("1- Cannot load Image in location: ./: ", ok) os.Exit(-1) } return textures[newIdx] } else { fmt.Println("Image not RGBA at location: ./") os.Exit(-1) } return 0 }
func (t Texture) Bind() { gl.BindTexture(gl.TEXTURE_2D, t.Id) }
func loadFont(img *image.RGBA, config *FontConfig) (f *Font, err error) { f = new(Font) f.config = config // Resize image to next power-of-two. img = Pow2Image(img).(*image.RGBA) ib := img.Bounds() f.textureWidth = float32(ib.Dx()) f.textureHeight = float32(ib.Dy()) for _, glyph := range config.Glyphs { if glyph.Width > f.maxGlyphWidth { f.maxGlyphWidth = glyph.Width } if glyph.Height > f.maxGlyphHeight { f.maxGlyphHeight = glyph.Height } } // save to disk for testing if f.IsDebug { file, err := os.Create("out.png") if err != nil { panic(err) } defer file.Close() b := bufio.NewWriter(file) err = png.Encode(b, img) if err != nil { panic(err) } err = b.Flush() if err != nil { panic(err) } } // generate texture gl.GenTextures(1, &f.textureID) gl.BindTexture(gl.TEXTURE_2D, f.textureID) 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(ib.Dx()), int32(ib.Dy()), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(img.Pix), ) gl.BindTexture(gl.TEXTURE_2D, 0) // create shader program and define attributes and uniforms f.program, err = NewProgram(fontVertexShaderSource, fontFragmentShaderSource) if err != nil { return f, err } // attributes f.centeredPosition = uint32(gl.GetAttribLocation(f.program, gl.Str("centered_position\x00"))) f.uv = uint32(gl.GetAttribLocation(f.program, gl.Str("uv\x00"))) // uniforms f.finalPositionUniform = gl.GetUniformLocation(f.program, gl.Str("final_position\x00")) f.orthographicMatrixUniform = gl.GetUniformLocation(f.program, gl.Str("orthographic_matrix\x00")) f.scaleMatrixUniform = gl.GetUniformLocation(f.program, gl.Str("scale_matrix\x00")) f.fragmentTextureUniform = gl.GetUniformLocation(f.program, gl.Str("fragment_texture\x00")) f.colorUniform = gl.GetUniformLocation(f.program, gl.Str("fragment_color_adjustment\x00")) return f, nil }
// LoadDictionary reads a gobbed Dictionary object from r, registers its atlas texture with opengl, // and returns a Dictionary that is ready to render text. func LoadDictionary(r io.Reader) (*Dictionary, error) { errChan := make(chan error) initOnce.Do(func() { render.Queue(func() { // errChan <- render.RegisterShader("glop.font", []byte(font_vertex_shader), []byte(font_fragment_shader)) errChan <- render.RegisterShader("glop.font", []byte(font_vshader), []byte(font_fshader)) }) }) err := <-errChan if err != nil { return nil, err } var dict Dictionary dec := gob.NewDecoder(r) err = dec.Decode(&dict) if err != nil { return nil, err } render.Queue(func() { // Create the gl texture for the atlas gl.GenTextures(1, &dict.atlas.texture) glerr := gl.GetError() if glerr != 0 { errChan <- fmt.Errorf("Gl Error on gl.GenTextures: %v", glerr) return } // Send the atlas to opengl gl.BindTexture(gl.TEXTURE_2D, dict.atlas.texture) gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RED, dict.Dx, dict.Dy, 0, gl.RED, gl.UNSIGNED_BYTE, gl.Ptr(&dict.Pix[0])) glerr = gl.GetError() if glerr != 0 { errChan <- fmt.Errorf("Gl Error on creating texture: %v", glerr) return } // Create the atlas sampler and set the parameters we want for it gl.GenSamplers(1, &dict.atlas.sampler) gl.SamplerParameteri(dict.atlas.sampler, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.SamplerParameteri(dict.atlas.sampler, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.SamplerParameteri(dict.atlas.sampler, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.SamplerParameteri(dict.atlas.sampler, gl.TEXTURE_WRAP_T, gl.REPEAT) glerr = gl.GetError() if glerr != 0 { errChan <- fmt.Errorf("Gl Error on creating sampler: %v", glerr) return } errChan <- nil }) err = <-errChan if err != nil { return nil, err } return &dict, nil }
func (r *Renderable) Draw(perspective mgl.Mat4, view mgl.Mat4) { gl.UseProgram(r.Shader) gl.BindVertexArray(r.Vao) model := r.GetTransformMat4() var mvp mgl.Mat4 shaderMvp := getUniformLocation(r.Shader, "MVP_MATRIX") if shaderMvp >= 0 { mvp = perspective.Mul4(view).Mul4(model) gl.UniformMatrix4fv(shaderMvp, 1, false, &mvp[0]) } shaderMv := getUniformLocation(r.Shader, "MV_MATRIX") if shaderMv >= 0 { mv := view.Mul4(model) gl.UniformMatrix4fv(shaderMv, 1, false, &mv[0]) } shaderTex0 := getUniformLocation(r.Shader, "DIFFUSE_TEX") if shaderTex0 >= 0 { gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, r.Tex0) gl.Uniform1i(shaderTex0, 0) } shaderColor := getUniformLocation(r.Shader, "MATERIAL_DIFFUSE") if shaderColor >= 0 { gl.Uniform4f(shaderColor, r.Color[0], r.Color[1], r.Color[2], r.Color[3]) } shaderTex1 := getUniformLocation(r.Shader, "MATERIAL_TEX_0") if shaderTex1 >= 0 { gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, r.Tex0) gl.Uniform1i(shaderTex1, 0) } shaderCameraWorldPos := getUniformLocation(r.Shader, "CAMERA_WORLD_POSITION") if shaderCameraWorldPos >= 0 { gl.Uniform3f(shaderCameraWorldPos, -view[12], -view[13], -view[14]) } shaderPosition := getAttribLocation(r.Shader, "VERTEX_POSITION") if shaderPosition >= 0 { gl.BindBuffer(gl.ARRAY_BUFFER, r.VertVBO) gl.EnableVertexAttribArray(uint32(shaderPosition)) gl.VertexAttribPointer(uint32(shaderPosition), 3, gl.FLOAT, false, 0, gl.PtrOffset(0)) } shaderNormal := getAttribLocation(r.Shader, "VERTEX_NORMAL") if shaderNormal >= 0 { gl.BindBuffer(gl.ARRAY_BUFFER, r.NormsVBO) gl.EnableVertexAttribArray(uint32(shaderNormal)) gl.VertexAttribPointer(uint32(shaderNormal), 3, gl.FLOAT, false, 0, gl.PtrOffset(0)) } shaderVertUv := getAttribLocation(r.Shader, "VERTEX_UV_0") if shaderVertUv >= 0 { gl.BindBuffer(gl.ARRAY_BUFFER, r.UvVBO) gl.EnableVertexAttribArray(uint32(shaderVertUv)) gl.VertexAttribPointer(uint32(shaderVertUv), 2, gl.FLOAT, false, 0, gl.PtrOffset(0)) } gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.ElementsVBO) gl.DrawElements(gl.TRIANGLES, int32(r.FaceCount*3), gl.UNSIGNED_INT, gl.PtrOffset(0)) gl.BindVertexArray(0) }
func (t *Texture) Bind() { gl.BindTexture(gl.TEXTURE_2D, t.id) }
func (t *Texture) Unbind() { gl.BindTexture(gl.TEXTURE_2D, 0) }