Example #1
0
//SaveTexture2D take a Texture2D and a filename and saves it as a png image.
func SaveTexture2D(t gl2.Texture2D, filename string) error {
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, 0666)
	defer file.Close()
	if err != nil {
		return err
	}
	lasttex := GetCurrentTexture2D()
	defer lasttex.Bind()

	t.Bind()
	width, height := int(t.Width(0)), int(t.Height(0))
	nrgba := image.NewRGBA(image.Rect(0, 0, width, height))

	D(width, height)
	var pixels []byte

	internalformat := t.InternalFormat(0)
	if internalformat == gl.RGBA8 {
		pixels = make([]byte, width*height*4)
		t.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&pixels[0]))
		for x := 0; x < len(pixels); x += 4 {
			nrgba.SetRGBA((x/4)%width, height-(x/4)/width, color.RGBA{pixels[x], pixels[x+1], pixels[x+2], 255})
		}
	} else {
		fmt.Errorf("unsupported texture type")
	}
	png.Encode(file, nrgba)
	return nil
}
Example #2
0
//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()
}
Example #3
0
//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)
	}
}
Example #4
0
//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()
}