func HeightMapUpdate(loc *renderstuff.RenderLocations, entity renderstuff.IRenderEntity, etc interface{}) { heightMap := entity.(*gamestate.HeightMap) if heightMap.HasChanges { min_h, max_h := heightMap.Bounds() loc.LowerBound.Uniform3f(0, 0, min_h) loc.UpperBound.Uniform3f(float32(heightMap.W), float32(heightMap.H), max_h) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureHeightMap) gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, heightMap.W, heightMap.H, gl.RED, gl.FLOAT, heightMap.TexturePixels()) gl.ActiveTexture(gl.TEXTURE0) heightMap.HasChanges = false } }
func (this *WorldRenderer) Render(ww *gamestate.World, options *settings.BoolOptions, window *sdl.Window) { camera := ww.Player.Camera p0 := camera.Pos4f() w, h := window.GetSize() camera.MoveRelative(mgl.Vec4{-0.1, 0, 0, 0}) this.View = (ww.PortalTransform(p0, camera.Pos4f()).Mul4(camera.Model())).Inv() viewport := Viewport{0, 0, w / 2, h} viewport.Activate() this.render(ww, options, viewport, 0, nil) camera.MoveRelative(mgl.Vec4{+0.2, 0, 0, 0}) this.View = (ww.PortalTransform(p0, camera.Pos4f()).Mul4(camera.Model())).Inv() viewport.X = w / 2 viewport.Activate() this.render(ww, options, viewport, 0, nil) gl.Viewport(0, 0, w, h) gl.ActiveTexture(gl.TEXTURE0) this.Framebuffer[0].RenderTexture.Bind(gl.TEXTURE_RECTANGLE) this.ScreenQuadRenderer.Render(this.ScreenQuad, this.Proj, this.View, this.ClippingPlane_ws, nil) if this.screenShot { this.screenShot = false helpers.SaveTexture(gl.TEXTURE_RECTANGLE, 0, "screenshot.png") } }
func TexturesTest() { out := make([]int32, 1) gl.GetIntegerv(gl.MAX_TEXTURE_IMAGE_UNITS, out) maxUnits := int(out[0]) for i := 0; i < maxUnits; i++ { gl.ActiveTexture(gl.GLenum(gl.TEXTURE0 + i)) gl.GetIntegerv(gl.TEXTURE_BINDING_1D, out) texture := gl.Texture(out[0]) if texture != 0 { fmt.Println("unit: ", i, " texture1d: ", texture) } gl.GetIntegerv(gl.TEXTURE_BINDING_2D, out) texture = gl.Texture(out[0]) if texture != 0 { fmt.Println("unit: ", i, " texture2d: ", texture) } gl.GetIntegerv(gl.TEXTURE_BINDING_RECTANGLE, out) texture = gl.Texture(out[0]) if texture != 0 { fmt.Println("unit: ", i, " textureRect: ", texture) } gl.GetIntegerv(gl.TEXTURE_BINDING_CUBE_MAP, out) texture = gl.Texture(out[0]) if texture != 0 { fmt.Println("unit: ", i, " textureCube: ", texture) } gl.GetIntegerv(gl.TEXTURE_BINDING_3D, out) texture = gl.Texture(out[0]) if texture != 0 { fmt.Println("unit: ", i, " texture3d: ", texture) } } gl.ActiveTexture(gl.TEXTURE0) }
func (sp *Sprite) DrawScreen() { if sp.Texture != nil && sp.Render { camera := GetScene().SceneBase().Camera pos := sp.Transform().WorldPosition() scale := sp.Transform().WorldScale() TextureMaterial.Begin(sp.GameObject()) mp := TextureMaterial.ProjMatrix mv := TextureMaterial.ViewMatrix mm := TextureMaterial.ModelMatrix tx := TextureMaterial.Texture ac := TextureMaterial.AddColor ti := TextureMaterial.Tiling of := TextureMaterial.Offset defaultBuffer.Bind(gl.ARRAY_BUFFER) TextureMaterial.Verts.EnableArray() TextureMaterial.Verts.AttribPointer(3, gl.FLOAT, false, 0, uintptr(0)) TextureMaterial.UV.EnableArray() TextureMaterial.UV.AttribPointer(2, gl.FLOAT, false, 0, uintptr(12*4)) currentUV := sp.UVs[int(sp.animation)] view := Identity() model := Identity() model.Scale(scale.X*currentUV.Ratio, scale.Y, 1) model.Translate((float32(Width)/2)+pos.X+0.75, (float32(Height)/2)+pos.Y+0.75, 1) mv.UniformMatrix4fv(false, view) mp.UniformMatrix4f(false, (*[16]float32)(camera.Projection)) mm.UniformMatrix4fv(false, model) ti.Uniform2f((currentUV.U2-currentUV.U1)*sp.Tiling.X, (currentUV.V2-currentUV.V1)*sp.Tiling.Y) of.Uniform2f(currentUV.U1, currentUV.V1) sp.Bind() gl.ActiveTexture(gl.TEXTURE0) tx.Uniform1i(0) //ac.Uniform4f(1, 1, 1, 0) ac.Uniform4f(sp.Color.R, sp.Color.G, sp.Color.B, sp.Color.A) gl.DrawArrays(gl.QUADS, 0, 4) TextureMaterial.End(sp.GameObject()) } }
func (v *Video) initGL() { if gl.Init() != 0 { panic(sdl.GetError()) } gl.ClearColor(0.0, 0.0, 0.0, 1.0) gl.Enable(gl.CULL_FACE) gl.Enable(gl.DEPTH_TEST) v.prog = createProgram(vertShaderSrcDef, fragShaderSrcDef) posAttrib := v.prog.GetAttribLocation("vPosition") texCoordAttr := v.prog.GetAttribLocation("vTexCoord") v.textureUni = v.prog.GetAttribLocation("texture") v.texture = gl.GenTexture() gl.ActiveTexture(gl.TEXTURE0) v.texture.Bind(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) v.prog.Use() posAttrib.EnableArray() texCoordAttr.EnableArray() vertVBO := gl.GenBuffer() vertVBO.Bind(gl.ARRAY_BUFFER) verts := []float32{-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0} gl.BufferData(gl.ARRAY_BUFFER, len(verts)*int(unsafe.Sizeof(verts[0])), &verts[0], gl.STATIC_DRAW) textCoorBuf := gl.GenBuffer() textCoorBuf.Bind(gl.ARRAY_BUFFER) texVerts := []float32{0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0} gl.BufferData(gl.ARRAY_BUFFER, len(texVerts)*int(unsafe.Sizeof(texVerts[0])), &texVerts[0], gl.STATIC_DRAW) posAttrib.AttribPointer(2, gl.FLOAT, false, 0, uintptr(0)) texCoordAttr.AttribPointer(2, gl.FLOAT, false, 0, uintptr(0)) }
func (this *WorldRenderer) render(ww *gamestate.World, options *settings.BoolOptions, viewport Viewport, recursion int, srcPortal *gamestate.Portal) { this.Framebuffer[recursion].Bind() defer this.Framebuffer[recursion].Unbind() gl.Clear(gl.DEPTH_BUFFER_BIT) camera := gamestate.NewCameraFromMat4(this.View) Rot2D := camera.Rotation2D() gl.CullFace(gl.BACK) time := float64(sdl.GetTicks()) / 1000 if options.Wireframe { gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) } else { gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } if options.Skybox { gl.Disable(gl.DEPTH_TEST) this.SkyboxRenderer.Render(this.Skybox, this.Proj, this.View, this.ClippingPlane_ws, nil) gl.Enable(gl.DEPTH_TEST) } gl.Enable(gl.CULL_FACE) if recursion != 0 { gl.Enable(gl.CLIP_DISTANCE0) defer gl.Disable(gl.CLIP_DISTANCE0) } for _, entity := range ww.ExampleObjects { this.MeshRenderer.Render(entity, this.Proj, this.View, this.ClippingPlane_ws, nil) } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Disable(gl.CULL_FACE) if options.WorldRender { this.HeightMapRenderer.Render(ww.HeightMap, this.Proj, this.View, this.ClippingPlane_ws, nil) } PlayerPos := ww.Player.Position() ww.Water.Height = PlayerPos[2] - 15 if options.WaterRender { this.WaterRendererA.Render(ww.Water, this.Proj, this.View, this.ClippingPlane_ws, WaterRenderUniforms{time, PlayerPos}) } if options.WaterNormals { this.WaterRendererB.Render(ww.Water, this.Proj, this.View, this.ClippingPlane_ws, WaterRenderUniforms{time, PlayerPos}) } gl.Disable(gl.CULL_FACE) gl.Disable(gl.BLEND) if options.TreeRender { this.TreeRenderer.Render(ww.Trees, this.Proj, this.View, this.ClippingPlane_ws, Rot2D) } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE) if options.ParticleRender { this.ParticleSystem.Render(this.Proj, this.View, this.ClippingPlane_ws) } gl.Disable(gl.BLEND) boxVertices := (*gamestate.TriangleMesh)(gamestate.QuadMesh()).MakeBoxVertices() pv := this.Proj.Mul4(this.View) // calculating nearest portal pos4f := this.View.Inv().Mul4x1(mgl.Vec4{0, 0, 0, 1}) nearestPortal := ww.NearestPortal(pos4f) // draw all portals except the nearest and the portal that we are looking throug for _, portal := range ww.Portals { // do not draw the nearest portal or the portal behind the source portal if available if (nearestPortal != portal) && (srcPortal == nil || srcPortal.Target != portal) { gl.Enable(gl.DEPTH_CLAMP) additionalUniforms := map[string]int{"Image": 7} this.PortalRenderer.Render(portal, this.Proj, this.View, this.ClippingPlane_ws, additionalUniforms) } } gl.Disable(gl.BLEND) gl.Disable(gl.CULL_FACE) if options.DebugLines { if options.DepthTestDebugLines { gl.Disable(gl.DEPTH_TEST) } this.DebugRenderer.Render(this.Proj, this.View) gl.Enable(gl.DEPTH_TEST) } // draw if recursion < this.MaxRecursion { portal := nearestPortal pos := portal.Position rotation := portal.Orientation.Mat4() Model := mgl.Translate3D(pos[0], pos[1], pos[2]).Mul4(rotation) pvm := pv.Mul4(Model) meshMin := mgl.Vec4{math.MaxFloat32, math.MaxFloat32, math.MaxFloat32, math.MaxFloat32} meshMax := mgl.Vec4{-math.MaxFloat32, -math.MaxFloat32, -math.MaxFloat32, -math.MaxFloat32} for _, v := range boxVertices { v = pvm.Mul4x1(v) v = v.Mul(1 / v[3]) meshMin = gamestate.Min(meshMin, v) meshMax = gamestate.Max(meshMax, v) } // at least partially visible if -1 < meshMax[0] && meshMin[0] < 1 && -1 < meshMax[1] && meshMin[1] < 1 && -1 < meshMax[2] && meshMin[2] < 1 { p1x, p1y := viewport.ToPixel(meshMin.Vec2()) p2x, p2y := viewport.ToPixel(meshMax.Vec2()) pw, ph := p2x-p1x, p2y-p1y // do scissoring only when all vertices are in front of the camera scissor := meshMax[2] < 1 scissor = scissor && (p1x != 0 || p1y != 0 || pw != viewport.W-1 || ph != viewport.H-1) if scissor { gl.Enable(gl.SCISSOR_TEST) gl.Scissor(p1x, p1y, pw, ph) } // omit rendering when portal is not in frustum at all // calculation View matrix that shows the target portal from the same angle as view shows the source portal //pos2 := portal.Target.Position Model2 := portal.Target.Model() // model matrix, so that portal 1 in camera 1 looks identical to portal 2 in camera oldView := this.View this.View = this.View.Mul4(Model).Mul4(Model2.Inv()) normal_os := portal.Target.Normal normal_ws := Model.Mul4x1(normal_os) view_dir := helpers.HomogenDiff(portal.Position, camera.Position) sign := view_dir.Dot(normal_ws) oldClippingPlane := this.ClippingPlane_ws this.ClippingPlane_ws = portal.Target.ClippingPlane(sign > 0) this.render(ww, options, viewport, recursion+1, nearestPortal) this.ClippingPlane_ws = oldClippingPlane this.View = oldView gl.ActiveTexture(gl.TEXTURE0) this.Framebuffer[recursion+1].RenderTexture.Bind(gl.TEXTURE_RECTANGLE) if scissor { //gl.Scissor(0, 0, w, h) gl.Disable(gl.SCISSOR_TEST) } this.Framebuffer[recursion].Bind() gl.Enable(gl.DEPTH_CLAMP) additionalUniforms := map[string]int{"Image": 0} this.PortalRenderer.Render(nearestPortal, this.Proj, this.View, this.ClippingPlane_ws, additionalUniforms) } } }
func NewTextures(heightMap *gamestate.HeightMap) *Textures { textures := make([]gl.Texture, 10) gl.GenTextures(textures) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureGround) textures[1].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/GravelCobbleS.jpg") gl.GenerateMipmap(gl.TEXTURE_2D) 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_R, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureCliffs) textures[2].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/Cliffs0149_18_S.png") gl.GenerateMipmap(gl.TEXTURE_2D) 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_R, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureColorBand) textures[3].Bind(gl.TEXTURE_1D) helpers.LoadTexture1DWatched("textures/gradient.png") gl.TexParameteri(gl.TEXTURE_1D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_1D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureHeightMap) textures[4].Bind(gl.TEXTURE_2D) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.R16, heightMap.W, heightMap.H, 0, gl.RED, gl.FLOAT, heightMap.TexturePixels()) 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.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureTree) textures[5].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/palme.png") gl.GenerateMipmap(gl.TEXTURE_2D) 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.ActiveTexture(gl.TEXTURE0 + constants.TextureFireBall) textures[6].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/fireball.png") gl.GenerateMipmap(gl.TEXTURE_2D) 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.ActiveTexture(gl.TEXTURE0 + constants.TextureSkybox) textures[7].Bind(gl.TEXTURE_CUBE_MAP) helpers.LoadTextureCubeWatched("textures/Above_The_Sea.jpg") gl.GenerateMipmap(gl.TEXTURE_CUBE_MAP) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR) //gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE) 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.Enable(gl.TEXTURE_CUBE_MAP_SEAMLESS) ttf.Init() defer ttf.Quit() font, _ := ttf.OpenFont("fonts/Symbola.ttf", 64) color := sdl.Color{255, 255, 255, 255} surface, _ := font.RenderUTF8_Blended("Bla", color) defer surface.Free() gl.ActiveTexture(gl.TEXTURE0 + constants.TextureFont) textures[8].Bind(gl.TEXTURE_2D) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int(surface.W), int(surface.H), 0, gl.RGBA, gl.UNSIGNED_BYTE, uintptr(surface.Data())) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.ActiveTexture(gl.TEXTURE0) return &Textures{textures} }
func (v *Video) Render() { for running { select { case buf := <-v.videoTick: gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) v.prog.Use() gl.ActiveTexture(gl.TEXTURE0) v.texture.Bind(gl.TEXTURE_2D) gl.TexImage2D(gl.TEXTURE_2D, 0, 3, 240, 224, 0, gl.RGBA, gl.UNSIGNED_INT_8_8_8_8, buf) gl.DrawArrays(gl.TRIANGLES, 0, 6) if v.screen != nil { sdl.GL_SwapBuffers() v.fpsmanager.FramerateDelay() } case ev := <-sdl.Events: switch e := ev.(type) { case sdl.ResizeEvent: v.ResizeEvent(int(e.W), int(e.H)) case sdl.QuitEvent: os.Exit(0) case sdl.KeyboardEvent: switch e.Keysym.Sym { case sdl.K_ESCAPE: running = false case sdl.K_r: // Trigger reset interrupt if e.Type == sdl.KEYDOWN { // cpu.RequestInterrupt(InterruptReset) } case sdl.K_l: if e.Type == sdl.KEYDOWN { nes.LoadGameState() } case sdl.K_s: if e.Type == sdl.KEYDOWN { nes.SaveGameState() } case sdl.K_i: if e.Type == sdl.KEYDOWN { nes.AudioEnabled = !nes.AudioEnabled } case sdl.K_p: if e.Type == sdl.KEYDOWN { nes.TogglePause() } case sdl.K_d: if e.Type == sdl.KEYDOWN { jsHandler.ReloadFile(debugfile) } case sdl.K_m: if e.Type == sdl.KEYDOWN { nes.Handler.Handle("debug-mode") } case sdl.K_BACKSLASH: if e.Type == sdl.KEYDOWN { nes.Pause() nes.StepFrame() } case sdl.K_1: if e.Type == sdl.KEYDOWN { v.ResizeEvent(256, 240) } case sdl.K_2: if e.Type == sdl.KEYDOWN { v.ResizeEvent(512, 480) } case sdl.K_3: if e.Type == sdl.KEYDOWN { v.ResizeEvent(768, 720) } case sdl.K_4: if e.Type == sdl.KEYDOWN { v.ResizeEvent(1024, 960) } } switch e.Type { case sdl.KEYDOWN: nes.Pads[0].KeyDown(e, 0) case sdl.KEYUP: nes.Pads[0].KeyUp(e, 0) } } } } }