func (glRenderer *OpenglRenderer) loadTexture(img image.Image, textureUnit uint32, lod bool) uint32 { rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { log.Fatal("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) var texId uint32 gl.GenTextures(1, &texId) gl.ActiveTexture(textureUnit) gl.BindTexture(gl.TEXTURE_2D, texId) if rgba.Rect.Size().X == 0 || rgba.Rect.Size().Y == 0 { return texId } 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.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) if lod { gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.GenerateMipmap(gl.TEXTURE_2D) } else { gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) } return texId }
// Render renders the model func (m *Model) Render() { gl.UseProgram(m.currentProgram) gl.UniformMatrix4fv(m.modelUniform, 1, false, &m.model[0]) gl.BindVertexArray(m.vao) gl.ActiveTexture(gl.TEXTURE0) texture, isLoaded := m.textures.GetTexture(m.data.TextureFile) if isLoaded { gl.BindTexture(gl.TEXTURE_2D, texture) } else { if m.data.TextureFile != "" { go fmt.Printf("Unable to load texture %s", m.data.TextureFile) } } if m.data.Indexed { gl.DrawElements(gl.TRIANGLE_FAN, int32(len(m.data.Indices)), gl.UNSIGNED_INT, gl.PtrOffset(0)) } else { gl.DrawArrays(gl.TRIANGLES, 0, int32(len(m.data.Verts))/m.data.VertSize) } gl.BindVertexArray(0) }
func (me *GlObj) Draw(c *Core) { gl.UseProgram(c.Progs[me.Prog]) gl.BindVertexArray(c.Vao[me.Vao]) // shoud check if texture has been set for current object gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, c.Textures[me.Texture]) gl.DrawArrays(gl.TRIANGLES, 0, me.nbTriangles) }
func (glRenderer *OpenglRenderer) loadCubeMap(right, left, top, bottom, back, front image.Image, textureUnit uint32, lod bool) uint32 { var texId uint32 gl.GenTextures(1, &texId) gl.ActiveTexture(textureUnit) gl.BindTexture(gl.TEXTURE_CUBE_MAP, texId) for i := 0; i < 6; i++ { img := right var texIndex uint32 = gl.TEXTURE_CUBE_MAP_POSITIVE_X switch i { case 1: img = left texIndex = gl.TEXTURE_CUBE_MAP_NEGATIVE_X case 2: img = top texIndex = gl.TEXTURE_CUBE_MAP_NEGATIVE_Y case 3: img = bottom texIndex = gl.TEXTURE_CUBE_MAP_POSITIVE_Y case 4: img = back texIndex = gl.TEXTURE_CUBE_MAP_NEGATIVE_Z case 5: img = front texIndex = gl.TEXTURE_CUBE_MAP_POSITIVE_Z } img = imaging.FlipV(img) rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { log.Fatal("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) gl.TexImage2D( texIndex, 0, gl.RGBA, int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix), ) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE) if lod { gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.GenerateMipmap(gl.TEXTURE_CUBE_MAP) } else { gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR) } } return texId }
func (me *GlObj) Draw(c *Core) { gl.UseProgram(c.Progs[me.Prog]) gl.BindVertexArray(c.Vao[me.Vao]) // shoud check if texture has been set for current object // no need to be set again, if only one texture has been loaded // already binded/actived in new texture gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, c.Textures[me.Texture]) gl.DrawArrays(gl.TRIANGLES, 0, me.nbTriangles) }
/* Set current shader and activate textures */ func (mat *Material) Use() { mat.Shader.Use() var i uint32 = 0 //for name, tex := range mat.Textures { for _, name := range mat.tex_slots { tex := mat.Textures[name] tex.Use(i) mat.Shader.Int32(name, int32(i)) i++ } gl.ActiveTexture(gl.TEXTURE0) }
func (font *Font) createTexture(text string, width int, height int, size float64, dpi float64, rgba color.Color) (uint32, int, int) { context := freetype.NewContext() context.SetFont(font.ttf) img := image.NewRGBA(image.Rect(0, 0, width, height)) r, g, b, _ := rgba.RGBA() draw.Draw(img, img.Bounds(), image.NewUniform(color.RGBA{uint8(r), uint8(g), uint8(b), 0}), image.ZP, draw.Src) context.SetDst(img) context.SetClip(img.Bounds()) context.SetSrc(image.NewUniform(rgba)) context.SetFontSize(size) context.SetDPI(dpi) pixelBounds, _ := context.DrawString(text, freetype.Pt(0, height/2)) var tex uint32 gl.GenTextures(1, &tex) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, tex) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) 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.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, tex) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, int32(img.Rect.Size().X), int32(img.Rect.Size().Y), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(img.Pix)) return tex, int26_6Ceiling(pixelBounds.X + 0x3f), int26_6Ceiling(pixelBounds.Y + 0x3f) }
func (glRenderer *OpenglRenderer) enableCubeMap() { if glRenderer.cubeMap == glRenderer.activeCubeMap { return } glRenderer.activeCubeMap = glRenderer.cubeMap cubeMap := glRenderer.activeCubeMap // setup cubeMap if glRenderer.activeShader != nil && cubeMap != nil { gl.ActiveTexture(gl.TEXTURE10) gl.BindTexture(gl.TEXTURE_CUBE_MAP, cubeMap.Id) glRenderer.activeShader.Uniforms[cubeMap.Name] = int32(10) } }
// Draw will draw the billvboard in the x,y and z func (billboard *Billboard) Draw(x float32, y float32, z float32) { model := mgl32.Translate3D(x, y, z) if shader := shader.GetActive(); shader != nil { gl.UniformMatrix4fv(shader.Model, 1, false, &model[0]) } gl.BindVertexArray(billboard.vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, billboard.image) gl.DrawArrays(gl.TRIANGLES, 0, 1*2*3) }
func (glRenderer *OpenglRenderer) renderPostEffect(pe postEffect) { gl.UseProgram(pe.program) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, pe.textureId) gl.Disable(gl.CULL_FACE) gl.BindBuffer(gl.ARRAY_BUFFER, glRenderer.postEffectVbo) setupUniforms(pe.shader) vertAttrib := uint32(gl.GetAttribLocation(pe.program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(0)) texCoordAttrib := uint32(gl.GetAttribLocation(pe.program, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(2*4)) gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) gl.DisableVertexAttribArray(texCoordAttrib) }
func (me *Core) AddTexture(file string) int { imgFile, err := os.Open(file) if err != nil { fmt.Println("Could not open file:", file) panic(err) } img, _, err := image.Decode(imgFile) if err != nil { fmt.Println("Could not decode file:", file) panic(err) } rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*FloatSize { fmt.Println("Stride unsupported, file:", file) panic(err) } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) 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)) n := me.nbTexture me.Textures[n] = texture me.nbTexture++ return n }
func (glRenderer *OpenglRenderer) enableMaterial() { if glRenderer.material == glRenderer.activeMaterial { return } glRenderer.activeMaterial = glRenderer.material glRenderer.useTextures = (glRenderer.activeMaterial != nil && len(glRenderer.activeMaterial.Textures) > 0) // setup material if glRenderer.activeShader != nil && glRenderer.activeMaterial != nil { textures := glRenderer.activeMaterial.Textures for i, tex := range textures { textureUnit := gl.TEXTURE0 + uint32(i) glRenderer.activeShader.Uniforms[tex.TextureName] = int32(i) gl.ActiveTexture(textureUnit) gl.BindTexture(gl.TEXTURE_2D, tex.TextureId) } } }
func (glRenderer *OpenglRenderer) CreatePostEffect(shader *renderer.Shader) { //Create program glRenderer.CreateShader(shader) gl.UseProgram(shader.Program) //Create Texture var fbo_texture uint32 gl.ActiveTexture(gl.TEXTURE0) gl.GenTextures(1, &fbo_texture) gl.BindTexture(gl.TEXTURE_2D, fbo_texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_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(glRenderer.WindowWidth), int32(glRenderer.WindowHeight), 0, gl.RGBA, gl.UNSIGNED_BYTE, nil) //Create depth buffer var dbo uint32 gl.GenRenderbuffers(1, &dbo) gl.BindRenderbuffer(gl.RENDERBUFFER, dbo) gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, int32(glRenderer.WindowWidth), int32(glRenderer.WindowHeight)) gl.BindRenderbuffer(gl.RENDERBUFFER, 0) //Create frame buffer var fbo uint32 gl.GenFramebuffers(1, &fbo) gl.BindFramebuffer(gl.FRAMEBUFFER, fbo) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbo_texture, 0) gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, dbo) //add new postEffect to the queue newPe := postEffect{ program: shader.Program, textureId: fbo_texture, dboId: dbo, fboId: fbo, shader: shader, } glRenderer.postEffects = append(glRenderer.postEffects, newPe) }
func (t *Texture) create(file string) error { imgFile, err := os.Open(file) if err != nil { return fmt.Errorf("texture %q not found on disk: %v", file, err) } img, _, err := image.Decode(imgFile) if err != nil { return err } rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return fmt.Errorf("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) var tex uint32 gl.GenTextures(1, &tex) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, tex) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) 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)) t.id = tex t.Width = rgba.Rect.Size().X t.Height = rgba.Rect.Size().Y return nil }
func NewTexture(assetName string) (uint32, error) { data, err := Asset(assetName) if err != nil { return 0, err } img, _, err := image.Decode(bytes.NewReader(data)) if err != nil { return 0, err } 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.Point{0, 0}, draw.Src) 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, nil }
func main() { if err := glfw.Init(); err != nil { log.Fatalln("failed to initialize glfw:", err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) 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(windowWidth, windowHeight, "Cube", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // Initialize Glow if err := gl.Init(); err != nil { panic(err) } version := gl.GoStr(gl.GetString(gl.VERSION)) fmt.Println("OpenGL version", version) // Configure the vertex and fragment shaders program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model := mgl32.Ident4() modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00")) gl.Uniform1i(textureUniform, 0) gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00")) // Load the texture texture, err := newTexture("square.png") if err != nil { panic(err) } // Configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) // Configure global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) angle := 0.0 previousTime := glfw.GetTime() for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time angle += elapsed model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0}) // Render gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3) // Maintenance window.SwapBuffers() glfw.PollEvents() } }
/** Binds this texture to the given texture slot */ func (tx *Texture) Use(slot uint32) { gl.ActiveTexture(gl.TEXTURE0 + slot) gl.Enable(gl.TEXTURE_2D) tx.Bind() }
func (tex *Texture) Bind(texUnit uint32) { gl.ActiveTexture(texUnit) gl.BindTexture(tex.target, tex.handle) tex.texUnit = texUnit }
// Bind will set the current texture to the active texture func (t *Texture) Bind() { gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, t.id) }
func (t *Texture) BindTexture(unit uint32) { gl.ActiveTexture(gl.TEXTURE0 + unit) gl.BindTexture(gl.TEXTURE_2D, t.texture) }
func (t *Texture) UnbindTexture(unit uint32) { gl.ActiveTexture(gl.TEXTURE0 + unit) gl.BindTexture(gl.TEXTURE_2D, 0) }
func (font *Font) updateTexture(texture uint32, text string, width int, height int, size float64, dpi float64, rgba color.Color) (int, int) { context := freetype.NewContext() context.SetFont(font.ttf) img := image.NewRGBA(image.Rect(0, 0, width, height)) r, g, b, _ := rgba.RGBA() draw.Draw(img, img.Bounds(), image.NewUniform(color.RGBA{uint8(r), uint8(g), uint8(b), 0}), image.ZP, draw.Src) context.SetDst(img) context.SetClip(img.Bounds()) context.SetSrc(image.NewUniform(rgba)) context.SetFontSize(size) context.SetDPI(dpi) pixelBounds, _ := context.DrawString(text, freetype.Pt(0, height/2)) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexSubImage2D( gl.TEXTURE_2D, 0, 0, 0, int32(img.Rect.Size().X), int32(img.Rect.Size().Y), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(img.Pix)) return int26_6Ceiling(pixelBounds.X + 0x3f), int26_6Ceiling(pixelBounds.Y + 0x3f) }