Пример #1
0
func main() {
	var parser = flags.NewParser(&gOpts, flags.Default)

	var err error
	var args []string
	if args, err = parser.Parse(); err != nil {
		os.Exit(1)
	}

	if len(args) < 1 || len(args) > 2 {
		panic(fmt.Errorf("Too many or not enough arguments"))
	}

	gDiffFlag = len(args) == 2

	// make sure that we display any errors that are encountered
	//glfw.SetErrorCallback(errorCallback)

	// the GLFW library has to be initialized before any of the methods
	// can be invoked
	if err = glfw.Init(); err != nil {
		panic(err)
	}

	// to be tidy, make sure glfw.Terminate() is called at the end of
	// the program to clean things up by using `defer`
	defer glfw.Terminate()

	// hints are the way you configure the features requested for the
	// window and are required to be set before calling glfw.CreateWindow().

	// desired number of samples to use for mulitsampling
	//glfw.WindowHint(glfw.Samples, 4)

	// request a OpenGL 4.1 core context
	if runtime.GOOS == "darwin" {
		glfw.WindowHint(glfw.ContextVersionMajor, 3)
		glfw.WindowHint(glfw.ContextVersionMinor, 3)
	} else {
		glfw.WindowHint(glfw.ContextVersionMajor, 4)
		glfw.WindowHint(glfw.ContextVersionMinor, 1)
	}
	glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)

	// do the actual window creation
	var window *glfw.Window
	window, err = glfw.CreateWindow(1024, 768, "goicmpgl", nil, nil)
	if err != nil {
		// we legitimately cannot recover from a failure to create
		// the window in this sample, so just bail out
		panic(err)
	}

	// set the callback function to get all of the key input from the user
	window.SetKeyCallback(keyCallback)
	window.SetMouseButtonCallback(mouseDownCallback)
	window.SetScrollCallback(mouseWheelCallback)
	window.SetCursorPosCallback(mouseMoveCallback)

	// GLFW3 can work with more than one window, so make sure we set our
	// new window as the current context to operate on
	window.MakeContextCurrent()

	// disable v-sync for max FPS if the driver allows it
	//glfw.SwapInterval(0)

	// make sure that GLEW initializes all of the GL functions
	if err = gl.Init(); err != nil {
		panic(err)
	}

	var attribs []string = []string{
		"position",
		"uvs",
	}

	// compile our shaders
	var progTex0 *Program
	if progTex0, err = LoadShaderProgram(vertShader, fragShaderTex0, attribs); err != nil {
		panic(err)
	}
	defer progTex0.DeleteProgram()

	var progGrid *Program
	if progGrid, err = LoadShaderProgram(vertShader, S_FragmentShader_Grid, attribs); err != nil {
		panic(err)
	}
	defer progGrid.DeleteProgram()

	var diffProg2 *Program
	if diffProg2, err = LoadShaderProgram(vertShader, sProgram2Src, attribs); err != nil {
		panic(err)
	}
	defer diffProg2.DeleteProgram()

	var diffProg3 *Program
	if diffProg3, err = LoadShaderProgram(vertShader, sProgram3Src, attribs); err != nil {
		panic(err)
	}
	defer diffProg3.DeleteProgram()

	var diffProg4 *Program
	if diffProg4, err = LoadShaderProgram(vertShader, sProgram4Src, attribs); err != nil {
		panic(err)
	}
	defer diffProg4.DeleteProgram()

	var diffProg5 *Program
	if diffProg5, err = LoadShaderProgram(vertShader, sProgram5Src, attribs); err != nil {
		panic(err)
	}
	defer diffProg5.DeleteProgram()

	var image1_path string = args[0]
	if strings.HasPrefix(image1_path, "http") {
		if err, image1_path = downloadImage(image1_path); err != nil {
			panic(err)
		}
	}

	var texture *Texture
	if err, texture, gImage1 = NewTexture(image1_path, false); err != nil {
		panic(err)
	}
	defer texture.DeleteTexture()

	var texture2 *Texture
	if gDiffFlag {
		var image2_path string = args[1]
		if strings.HasPrefix(image2_path, "http") {
			if err, image2_path = downloadImage(image2_path); err != nil {
				panic(err)
			}
		}

		if err, texture2, gImage2 = NewTexture(image2_path, false); err != nil {
			panic(err)
		}
		defer texture2.DeleteTexture()

		if texture.Size.X != texture2.Size.X || texture.Size.Y != texture2.Size.Y {
			fmt.Println("WARNING: image dimensions differ!")
		} else {
			fmt.Printf("image dimensions: %dx%d\n", texture.Size.X, texture.Size.Y)
		}
	} else {
		fmt.Printf("image dimensions: %dx%d\n", texture.Size.X, texture.Size.Y)
	}

	var font *Font
	if err, font = NewFont("Font.png", 16); err != nil {
		panic(err)
	}
	defer font.DeleteFont()

	var help1 *String = font.NewString("1: show only A")
	defer help1.DeleteString()
	var help2 *String = font.NewString("2: show only B")
	defer help2.DeleteString()
	var help3 *String = font.NewString("3: show diff A&B")
	defer help3.DeleteString()
	var helph *String = font.NewString("h: toggle this help")
	defer helph.DeleteString()
	var helparrows *String = font.NewString("<up>,<down>: go from A to B")
	defer helparrows.DeleteString()
	var helpzoom *String = font.NewString("[]: zoom in/out (also mouse wheel)")
	defer helpzoom.DeleteString()
	var helpclear *String = font.NewString("Z: reset zoom/view")
	defer helpclear.DeleteString()
	var helpescape *String = font.NewString("ESC: quit")
	defer helpescape.DeleteString()

	var vbo *VBO
	if vbo, err = NewVBOQuad(0, 0, float32(texture.Size.X), float32(texture.Size.Y)); err != nil {
		panic(err)
	}
	defer vbo.DeleteVBO()

	var cnt float32 = 0

	// while there's no request to close the window
	for !window.ShouldClose() {
		cnt += 1

		// get the texture of the window because it may have changed since creation
		width, height := window.GetFramebufferSize()
		wwidth, _ := window.GetSize()
		gRetinaScale = float32(width) / float32(wwidth)

		//fmt.Printf("x=%d y=%d wx=%d wy=%d\n", width, height, wwidth, wheight)

		if cnt >= float32(width) {
			cnt = 0
		}

		var matrix Matrix2x3 = IdentityMatrix2x3()
		matrix = matrix.Translate(-1.0, 1.0)
		matrix = matrix.Scale(2.0/float32(width), -2.0/float32(height))

		// clear it all out
		gl.Viewport(0, 0, int32(width), int32(height))
		gl.ClearColor(0.0, 0.0, 0.0, 1.0)
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		gl.Enable(gl.BLEND)
		gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
		gl.BlendEquation(gl.FUNC_ADD)

		var matrix3 Matrix2x3 = matrix.Scale(gZoom, gZoom)
		matrix3 = matrix3.Translate(gOffX, gOffY)

		// draw the grid
		if true {
			vbo.Bind()
			progGrid.UseProgram()

			color1 := [4]float32{.4, .4, .4, 1}
			color2 := [4]float32{.9, .9, .9, 1}
			grid := [3]float32{float32(texture.Size.X), float32(texture.Size.Y), 8 / gZoom}
			//fmt.Printf("%.2f %.2f %.2f %.2f\n", grid[0], grid[1], grid[2], grid[3])
			progGrid.ProgramUniformMatrix4fv("ModelviewMatrix", matrix3.Array())
			progGrid.ProgramUniform4fv("color1", color1)
			progGrid.ProgramUniform4fv("color2", color2)
			progGrid.ProgramUniform3fv("grid", grid)

			if err = progGrid.ValidateProgram(); err != nil {
				panic(err)
			}

			vbo.Draw()

			vbo.Unbind()
			progGrid.UnuseProgram()
		}

		// draw the texture
		if !gDiffFlag {
			vbo.Bind()
			progTex0.UseProgram()
			texture.BindTexture(0)

			progTex0.ProgramUniformMatrix4fv("ModelviewMatrix", matrix3.Array())
			progTex0.ProgramUniform1i("tex1", 0)
			progTex0.ProgramUniform1f("blend", gBlend)

			if err = progTex0.ValidateProgram(); err != nil {
				panic(err)
			}

			vbo.Draw()

			vbo.Unbind()
			progTex0.UnuseProgram()
			texture.UnbindTexture(0)
		} else {
			var diffBlend float32 = gBlend

			var diffProg *Program

			if diffBlend < 0.25 {
				diffBlend *= 4
				diffProg = diffProg2
			} else if diffBlend < 0.5 { // 0.25 -> 0.5
				diffBlend = 4*diffBlend - 1
				diffProg = diffProg4
			} else if diffBlend < 0.75 { // 0.5 -> 0.75
				diffBlend = 4*diffBlend - 2
				diffProg = diffProg5
			} else { // 0.75 -> 1.0=
				diffBlend = 4*diffBlend - 3
				diffProg = diffProg3
			}

			vbo.Bind()
			diffProg.UseProgram()
			texture.BindTexture(0)
			texture2.BindTexture(1)

			diffProg.ProgramUniformMatrix4fv("ModelviewMatrix", matrix3.Array())
			diffProg.ProgramUniform1i("decalA", 0)
			diffProg.ProgramUniform1i("decalB", 1)
			diffProg.ProgramUniform1f("diffBlend", diffBlend)

			if err = diffProg.ValidateProgram(); err != nil {
				panic(err)
			}

			vbo.Draw()

			vbo.Unbind()
			diffProg.UnuseProgram()
			texture.UnbindTexture(0)
			texture2.UnbindTexture(1)
		}

		// font
		if gHelp {
			color := [...]float32{0, 0, 1, 1}
			bg := [...]float32{0.5, 0.5, 0.5, 0.5}
			var line float32 = 0
			if err = helph.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128); err != nil {
				panic(err)
			}
			line += 1
			help1.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128)
			line += 1
			help2.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128)
			line += 1
			help3.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128)
			line += 1
			helparrows.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128)
			line += 1
			helpzoom.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128)
			line += 1
			helpclear.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128)
			line += 1
			helpescape.Draw(font, color, bg, matrix, 0.5, 20, 100+line*128)
			line += 1
		}

		// swapping OpenGL buffers and polling events has been decoupled
		// in GLFW3, so make sure to invoke both here
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Пример #2
0
func Main() {
	err := glfw.Init()
	if err != nil {
		panic(err)
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 2)
	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
	glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
	window, err := glfw.CreateWindow(WindowWidth, WindowHeight, "Cube", nil, nil)
	Window = window
	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("SimpleVertexShader.vertexshader", "SimpleFragmentShader.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"))
	// 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()

	width, height := window.GetSize()
	window.SetCursorPos(float64(width/2), float64(height/2))
	window.SetKeyCallback(input.OnKey)
	window.SetCursorPosCallback(input.OnCursor)
	window.SetMouseButtonCallback(input.OnMouse)

	meshes.LoadColladaCube("cube.dae")

	for !player.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])
		player.MainPlayer.Draw(program)
		for _, element := range game.Universe {
			(element).Draw(program)
		}

		// Maintenance
		window.SwapBuffers()
		glfw.PollEvents()
	}
}