mirror of
https://github.com/libretro/go-nanoarch.git
synced 2024-11-27 02:20:35 +00:00
Initial commit
This commit is contained in:
commit
40ca48994c
2166
libretro.h
Normal file
2166
libretro.h
Normal file
File diff suppressed because it is too large
Load Diff
284
nanoarch.go
Normal file
284
nanoarch.go
Normal file
@ -0,0 +1,284 @@
|
||||
// Copyright 2014 The go-gl Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Renders a textured spinning cube using GLFW 3 and OpenGL 4.1 core forward-compatible profile.
|
||||
package main // import "github.com/go-gl/example/gl41core-cube"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/build"
|
||||
"image"
|
||||
"image/draw"
|
||||
_ "image/png"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
const windowWidth = 800
|
||||
const windowHeight = 600
|
||||
|
||||
func init() {
|
||||
// GLFW event handling must run on the main OS thread
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
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(90.0), 1.0, 0.1, 10.0)
|
||||
projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00"))
|
||||
gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0])
|
||||
|
||||
camera := mgl32.LookAtV(mgl32.Vec3{0, 0, 1}, 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])
|
||||
|
||||
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 {
|
||||
log.Fatalln(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(vertices)*4, gl.Ptr(vertices), 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, 0, 1.0)
|
||||
|
||||
for !window.ShouldClose() {
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
|
||||
// Render
|
||||
gl.UseProgram(program)
|
||||
|
||||
gl.BindVertexArray(vao)
|
||||
|
||||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
gl.BindTexture(gl.TEXTURE_2D, texture)
|
||||
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, 1*2*3)
|
||||
|
||||
// Maintenance
|
||||
window.SwapBuffers()
|
||||
glfw.PollEvents()
|
||||
}
|
||||
}
|
||||
|
||||
func newProgram(vertexShaderSource, fragmentShaderSource string) (uint32, error) {
|
||||
vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
program := gl.CreateProgram()
|
||||
|
||||
gl.AttachShader(program, vertexShader)
|
||||
gl.AttachShader(program, fragmentShader)
|
||||
gl.LinkProgram(program)
|
||||
|
||||
var status int32
|
||||
gl.GetProgramiv(program, gl.LINK_STATUS, &status)
|
||||
if status == gl.FALSE {
|
||||
var logLength int32
|
||||
gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength)
|
||||
|
||||
log := strings.Repeat("\x00", int(logLength+1))
|
||||
gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log))
|
||||
|
||||
return 0, fmt.Errorf("failed to link program: %v", log)
|
||||
}
|
||||
|
||||
gl.DeleteShader(vertexShader)
|
||||
gl.DeleteShader(fragmentShader)
|
||||
|
||||
return program, nil
|
||||
}
|
||||
|
||||
func compileShader(source string, shaderType uint32) (uint32, error) {
|
||||
shader := gl.CreateShader(shaderType)
|
||||
|
||||
csources, free := gl.Strs(source)
|
||||
gl.ShaderSource(shader, 1, csources, nil)
|
||||
free()
|
||||
gl.CompileShader(shader)
|
||||
|
||||
var status int32
|
||||
gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status)
|
||||
if status == gl.FALSE {
|
||||
var logLength int32
|
||||
gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)
|
||||
|
||||
log := strings.Repeat("\x00", int(logLength+1))
|
||||
gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))
|
||||
|
||||
return 0, fmt.Errorf("failed to compile %v: %v", source, log)
|
||||
}
|
||||
|
||||
return shader, nil
|
||||
}
|
||||
|
||||
func newTexture(file string) (uint32, error) {
|
||||
imgFile, err := os.Open(file)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("texture %q not found on disk: %v", file, 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, 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
|
||||
}
|
||||
|
||||
var vertexShader = `
|
||||
#version 330
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 camera;
|
||||
|
||||
in vec3 vert;
|
||||
in vec2 vertTexCoord;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
|
||||
void main() {
|
||||
fragTexCoord = vertTexCoord;
|
||||
gl_Position = projection * camera * vec4(vert, 1);
|
||||
}
|
||||
` + "\x00"
|
||||
|
||||
var fragmentShader = `
|
||||
#version 330
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 outputColor;
|
||||
|
||||
void main() {
|
||||
outputColor = texture(tex, fragTexCoord);
|
||||
}
|
||||
` + "\x00"
|
||||
|
||||
var vertices = []float32{
|
||||
// X, Y, Z, U, V
|
||||
-1.0, -1.0, 0.0, 1.0, 0.0,
|
||||
1.0, -1.0, 0.0, 0.0, 0.0,
|
||||
-1.0, 1.0, 0.0, 1.0, 1.0,
|
||||
1.0, -1.0, 0.0, 0.0, 0.0,
|
||||
1.0, 1.0, 0.0, 0.0, 1.0,
|
||||
-1.0, 1.0, 0.0, 1.0, 1.0,
|
||||
}
|
||||
|
||||
// Set the working directory to the root of Go package, so that its assets can be accessed.
|
||||
func init() {
|
||||
dir, err := importPathToDir("github.com/go-gl/example/gl41core-cube")
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to find Go package in your GOPATH, it's needed to load assets:", err)
|
||||
}
|
||||
err = os.Chdir(dir)
|
||||
if err != nil {
|
||||
log.Panicln("os.Chdir:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// importPathToDir resolves the absolute path from importPath.
|
||||
// There doesn't need to be a valid Go package inside that import path,
|
||||
// but the directory must exist.
|
||||
func importPathToDir(importPath string) (string, error) {
|
||||
p, err := build.Import(importPath, "", build.FindOnly)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return p.Dir, nil
|
||||
}
|
BIN
square.png
Normal file
BIN
square.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 352 KiB |
Loading…
Reference in New Issue
Block a user