//Aggregate performs the lighting calculation per pixel. This is essentially a special post process pass. func (gb *GBuffer) Aggregate(cam *Camera, plights []*PointLight, shadowmat glm.Mat4, tex gl2.Texture2D, f1, f2, f3 float32) { gb.AggregateFramebuffer.framebuffer.Bind(gl2.FRAMEBUFFER) gb.AggregateFramebuffer.program.Use() gb.CookRoughnessValue.Uniform1f(f1) gb.CookF0.Uniform1f(f2) gb.CookK.Uniform1f(f3) gl.ActiveTexture(gl2.TEXTURE0) gb.DiffuseTex.Bind() gb.AggregateFramebuffer.DiffUni.Uniform1i(0) gl.ActiveTexture(gl2.TEXTURE1) gb.NormalTex.Bind() gb.AggregateFramebuffer.NormalUni.Uniform1i(1) gl.ActiveTexture(gl2.TEXTURE2) gb.PositionTex.Bind() gb.AggregateFramebuffer.PosUni.Uniform1i(2) gl.ActiveTexture(gl2.TEXTURE3) gb.DepthTex.Bind() gb.AggregateFramebuffer.DepthUni.Uniform1i(3) //point lights gb.NumPointLightUni.Uniform1i(int32(len(plights))) plightpos := make([]float32, len(plights)*3) plightcol := make([]float32, len(plights)*3) for i, light := range plights { plightpos[i] = light.X plightpos[i+1] = light.Y plightpos[i+2] = light.Z plightcol[i] = light.R plightcol[i] = light.G plightcol[i] = light.B } if len(plights) != 0 { gb.PointLightPosUni.Uniform3fv(int32(len(plights)), &plightpos[0]) gb.PointLightColUni.Uniform3fv(int32(len(plights)), &plightcol[0]) } gb.CamPosUni.Uniform3fv(1, &cam.Pos[0]) //=====shadow=====// gl.ActiveTexture(gl2.TEXTURE4) tex.Bind() gb.ShadowMapUni.Uniform1i(4) gb.ShadowMatUni.UniformMatrix4fv(1, false, &shadowmat[0]) //================// Fstri() }
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 (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 }
//LoadPng tries to load a png file from hard drive and upload it to the GPU. func LoadPng(file string) (gl2.Texture2D, error) { imgFile, err := os.Open(file) if err != nil { return 0, nil } defer imgFile.Close() img, _, err := image.Decode(imgFile) if err != nil { return 0, nil } 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) texture := gl2.GenTexture2D() gl.ActiveTexture(gl2.TEXTURE0) texture.Bind() defer texture.Unbind() texture.MinFilter(gl2.LINEAR) texture.MagFilter(gl2.LINEAR) texture.WrapS(gl2.CLAMP_TO_EDGE) texture.WrapT(gl2.CLAMP_TO_EDGE) texture.TexImage2D(0, gl2.RGBA, int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y), 0, gl2.RGBA, gl2.UNSIGNED_BYTE, gl.Ptr(rgba.Pix)) return texture, nil }
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 (r *BatchRenderer) Bind() error { gl.UseProgram(r.Program) gl.ActiveTexture(gl.TEXTURE0) gl.Uniform1i(r.TextureUnitLoc, 0) gl.UniformMatrix4fv(r.ProjectionLoc, 1, false, &r.Camera.Projection[0]) return nil }
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 (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() }
//Render takes a texture and feed it to the fragment shader as a fullscreen texture. It will call the next post process pass if there is one. func (ppfb *PostProcessFramebuffer) Render(t gl2.Texture2D) { ppfb.Prog.Use() ppfb.time.Uniform1f(float32(glfw.GetTime())) gl.ActiveTexture(gl2.TEXTURE0) t.Bind() ppfb.source.Uniform1i(0) Fstri() if ppfb.next != nil { ppfb.next.PreRender() ppfb.next.Render(ppfb.Tex) } }
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 }
//Render will render the mesh in the different textures. No lighting calculation is performed here. func (gb *GBuffer) Render(cam *Camera, mesh Mesh, tex gl2.Texture2D, t *Transform) { model := t.Mat4() mvp := gb.vp.Mul4(model) gb.MVPUni.UniformMatrix4fv(1, false, &mvp[0]) gb.MUni.UniformMatrix4fv(1, false, &model[0]) normal := model.Inv() gb.NUni.UniformMatrix4fv(1, true, &normal[0]) gl.ActiveTexture(gl2.TEXTURE0) tex.Bind() gb.DiffuseUni.Uniform1i(0) mesh.Bind() mesh.DrawCall() }
// 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 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 (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) }