Advertisement
efplaya

golang opengl3

Aug 7th, 2015
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 10.53 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     // gl "github.com/chsc/gogl/gl33"
  6.     "github.com/go-gl/gl/v3.2-core/gl"
  7.     "github.com/veandco/go-sdl2/sdl"
  8.     // "math"
  9.     // "github.com/Jragonmiris/mathgl"
  10.     mathgl "github.com/go-gl/mathgl/mgl32"
  11.  
  12.     "runtime"
  13.     // "time"
  14.     "errors"
  15.     "github.com/davecheney/profile"
  16.     Image "image"
  17.     _ "image/jpeg"
  18.     _ "image/png"
  19.     "os"
  20.     "strings"
  21. )
  22.  
  23. type attribute struct {
  24.     vertices []float32
  25.     colors   []float32
  26.     uvs      []float32
  27. }
  28.  
  29. var attributes []attribute
  30.  
  31. func BindTexture(path string) uint32 {
  32.     f, e := os.Open(path)
  33.     if e != nil {
  34.         panic("file open error:" + e.Error())
  35.     }
  36.  
  37.     img, _, e := Image.Decode(f)
  38.  
  39.     if e != nil {
  40.         panic("file decode error:" + e.Error())
  41.     }
  42.  
  43.     rgbaImg, ok := img.(*Image.NRGBA)
  44.     if !ok {
  45.         panic("texture must be an NRGBA image")
  46.     }
  47.  
  48.     // taken from github.com/chsc/gogl/examples
  49.     // flip image: first pixel is lower left corner
  50.     imgWidth, imgHeight := img.Bounds().Dx(), img.Bounds().Dy()
  51.     data := make([]byte, imgWidth*imgHeight*4)
  52.     lineLen := imgWidth * 4
  53.     dest := len(data) - lineLen
  54.     for src := 0; src < len(rgbaImg.Pix); src += rgbaImg.Stride {
  55.         copy(data[dest:dest+lineLen], rgbaImg.Pix[src:src+rgbaImg.Stride])
  56.         dest -= lineLen
  57.     }
  58.  
  59.     var texture uint32
  60.     gl.ActiveTexture(gl.TEXTURE0)
  61.     gl.BindTexture(gl.TEXTURE_2D, texture)
  62.     gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  63.     gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
  64.     gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
  65.     gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
  66.     gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE)
  67.     gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(imgWidth), int32(imgHeight), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(data))
  68.  
  69.     if gl.GetError() != gl.NO_ERROR {
  70.  
  71.         panic("Failed to load a texture")
  72.         return 0
  73.     }
  74.  
  75.     return texture
  76. }
  77.  
  78. func compileShader(source string, shaderType uint32) (uint32, error) {
  79.     shader := gl.CreateShader(shaderType)
  80.  
  81.     csource := gl.Str(source)
  82.     gl.ShaderSource(shader, 1, &csource, nil)
  83.     gl.CompileShader(shader)
  84.  
  85.     var status int32
  86.     gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status)
  87.     if status == gl.FALSE {
  88.         var logLength int32
  89.         gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)
  90.  
  91.         log := strings.Repeat("\x00", int(logLength+1))
  92.         gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))
  93.  
  94.         return 0, fmt.Errorf("failed to compile %v: %v", source, log)
  95.     }
  96.  
  97.     return shader, nil
  98. }
  99.  
  100. func MakeProgram(vert, frag string) (uint32, error) {
  101.     vertexShader, err := compileShader(vert, gl.VERTEX_SHADER)
  102.     if err != nil {
  103.         return 0, err
  104.     }
  105.  
  106.     fragmentShader, err := compileShader(frag, gl.FRAGMENT_SHADER)
  107.     if err != nil {
  108.         return 0, err
  109.     }
  110.  
  111.     program := gl.CreateProgram()
  112.  
  113.     gl.AttachShader(program, vertexShader)
  114.     gl.AttachShader(program, fragmentShader)
  115.     gl.LinkProgram(program)
  116.  
  117.     var status int32
  118.     gl.GetProgramiv(program, gl.LINK_STATUS, &status)
  119.     if status == gl.FALSE {
  120.         var logLength int32
  121.         gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength)
  122.  
  123.         log := strings.Repeat("\x00", int(logLength+1))
  124.         gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log))
  125.  
  126.         return 0, errors.New(fmt.Sprintf("failed to link program: %v", log))
  127.     }
  128.  
  129.     gl.DeleteShader(vertexShader)
  130.     gl.DeleteShader(fragmentShader)
  131.  
  132.     return program, nil
  133. }
  134.  
  135. func main() {
  136.     defer profile.Start(profile.CPUProfile).Stop()
  137.     var window *sdl.Window
  138.     var context sdl.GLContext
  139.     var event sdl.Event
  140.     var running bool
  141.     var err error
  142.  
  143.     runtime.LockOSThread()
  144.  
  145.     // if 0 != sdl.Init(sdl.INIT_EVERYTHING) {
  146.     //  panic(sdl.GetError())
  147.     // }
  148.     window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED,
  149.         sdl.WINDOWPOS_UNDEFINED,
  150.         winWidth, winHeight, sdl.WINDOW_OPENGL)
  151.  
  152.     if err != nil {
  153.         panic(err)
  154.     }
  155.     if window == nil {
  156.         panic(sdl.GetError())
  157.     }
  158.  
  159.     sdl.GL_SetAttribute(sdl.GL_DOUBLEBUFFER, 1)
  160.     sdl.GL_SetAttribute(sdl.GL_RED_SIZE, 8)
  161.     sdl.GL_SetAttribute(sdl.GL_GREEN_SIZE, 8)
  162.     sdl.GL_SetAttribute(sdl.GL_BLUE_SIZE, 8)
  163.     sdl.GL_SetAttribute(sdl.GL_ALPHA_SIZE, 8)
  164.  
  165.     context, _ = sdl.GL_CreateContext(window)
  166.     sdl.GL_MakeCurrent(window, context)
  167.  
  168.     if context == nil {
  169.         panic(sdl.GetError())
  170.     }
  171.  
  172.     if err := gl.Init(); err != nil {
  173.         panic("gl error: " + err.Error())
  174.     }
  175.  
  176.     fmt.Println(gl.GetString(gl.VERSION))
  177.     fmt.Println(gl.GetString(gl.VENDOR))
  178.     fmt.Println(gl.GetString(gl.RENDERER))
  179.  
  180.     gl.ClearColor(.7, .7, .7, .5)
  181.     gl.Viewport(0, 0, winWidth, winHeight)
  182.  
  183.     program, err := MakeProgram(vertexShaderSource, fragmentShaderSource)
  184.     // defer program.Delete()
  185.  
  186.     if err != nil {
  187.         fmt.Println("Error loading shaders: " + err.Error())
  188.     }
  189.  
  190.     gl.BindFragDataLocation(program, 0, gl.Str("color\x00"))
  191.     // texSampler := program.GetUniformLocation("myTextureSampler")
  192.     gl.GetUniformLocation(program, gl.Str("myTextureSampler\x00"))
  193.  
  194.     matrixID := gl.GetUniformLocation(program, gl.Str("MVP\x00"))
  195.     // Projection := mathgl.Perspective(45.0, winWidth/winHeight, 0.1, 100.0)
  196.     // Projection := mathgl.Ortho2D(0.0, winWidth, winHeight, 0.0)
  197.     Projection := mathgl.Ortho(0.0, winWidth, winHeight, 0.0, -5.0, 5.0)
  198.  
  199.     View := mathgl.LookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
  200.     Model := mathgl.Ident4()
  201.  
  202.     gl.Enable(gl.DEPTH_TEST)
  203.     gl.DepthFunc(gl.LESS)
  204.     gl.Enable(gl.BLEND)
  205.     gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
  206.  
  207.     for i := 0; i < 10000; i++ {
  208.         attributes = append(attributes, attribute{vertices: triangle_vertices, colors: triangle_colours, uvs: triangle_uvs})
  209.         //attributes = append(attributes, attribute{vertices: triangle_vertices2, colors: triangle_colours, uvs: triangle_uvs})
  210.     }
  211.     running = true
  212.  
  213.     var vao uint32
  214.     gl.GenVertexArrays(1, &vao)
  215.     // defer vertexArray.Delete()
  216.     gl.BindVertexArray(vao)
  217.  
  218.     var vbo uint32
  219.     gl.GenBuffers(1, &vbo)
  220.     gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
  221.  
  222.     var colorvbo uint32
  223.     gl.GenBuffers(1, &colorvbo)
  224.     gl.BindBuffer(gl.ARRAY_BUFFER, colorvbo)
  225.  
  226.     var uvvbo uint32
  227.     gl.GenBuffers(1, &uvvbo)
  228.     gl.BindBuffer(gl.ARRAY_BUFFER, uvvbo)
  229.  
  230.     // element buffer
  231.     var elementvbo uint32
  232.     gl.GenBuffers(1, &elementvbo)
  233.     // defer elementBuffer.Delete()
  234.     gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementvbo)
  235.     gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(elements)*2, gl.Ptr(elements), gl.STATIC_DRAW)
  236.  
  237.     texId := BindTexture("smiley.png")
  238.     // texId2 := BindTexture("test.png")
  239.  
  240.     move := 1
  241.     for running {
  242.         for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
  243.             switch t := event.(type) {
  244.             case *sdl.QuitEvent:
  245.                 running = false
  246.             case *sdl.MouseMotionEvent:
  247.  
  248.                 fmt.Println(string(t.Timestamp))
  249.             }
  250.         }
  251.  
  252.         gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
  253.  
  254.         // range of values
  255.         for _, attr := range attributes {
  256.  
  257.             gl.UseProgram(program)
  258.  
  259.             gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
  260.             gl.BufferData(gl.ARRAY_BUFFER, len(attr.vertices)*4, gl.Ptr(attr.vertices), gl.DYNAMIC_DRAW)
  261.  
  262.             positionAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertexPosition_modelspace\x00")))
  263.             gl.EnableVertexAttribArray(positionAttrib)
  264.             gl.VertexAttribPointer(positionAttrib, 3, gl.FLOAT, false, 0, nil)
  265.             // defer positionAttrib.DisableArray()
  266.  
  267.             gl.BindBuffer(gl.ARRAY_BUFFER, colorvbo)
  268.             gl.BufferData(gl.ARRAY_BUFFER, len(attr.colors)*4, gl.Ptr(attr.colors), gl.DYNAMIC_DRAW)
  269.  
  270.             colorAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertexColor\x00")))
  271.             gl.EnableVertexAttribArray(colorAttrib)
  272.             gl.VertexAttribPointer(colorAttrib, 3, gl.FLOAT, false, 0, nil)
  273.  
  274.             // defer colorAttrib.DisableArray()
  275.  
  276.             gl.BindBuffer(gl.ARRAY_BUFFER, uvvbo)
  277.             gl.BufferData(gl.ARRAY_BUFFER, len(attr.uvs)*4, gl.Ptr(attr.uvs), gl.DYNAMIC_DRAW)
  278.  
  279.             uvAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertexUV\x00")))
  280.             gl.EnableVertexAttribArray(uvAttrib)
  281.             gl.VertexAttribPointer(uvAttrib, 2, gl.FLOAT, false, 0, nil)
  282.             // defer uvAttrib.DisableArray()
  283.  
  284.             // fmt.Println(texId)
  285.             // fmt.Println(texId2)
  286.             // gl.ActiveTexture(gl.TEXTURE0)
  287.             gl.BindBuffer(gl.TEXTURE_2D, texId)
  288.             // texSampler.Uniform1i(0)
  289.  
  290.             // rot := mathgl.HomogRotate3DZ(float32(idx * 60))
  291.             Model = mathgl.Ident4()
  292.             Model = Model.Mul4(mathgl.Translate3D(float32(move), float32(100.0), float32(0.0)))
  293.             Model = Model.Mul4(mathgl.Scale3D(float32(50), float32(50), float32(1)))
  294.  
  295.             MVP := Projection.Mul4(View).Mul4(Model)
  296.  
  297.             gl.UniformMatrix4fv(matrixID, 1, false, &MVP[0])
  298.  
  299.             // use array buffer
  300.             gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementvbo)
  301.             // defer elementBuffer.Unbind(gl.ELEMENT_ARRAY_BUFFER)
  302.  
  303.             // gl.DrawArrays(gl.TRIANGLES, 0, 3)
  304.             gl.DrawElements(gl.TRIANGLES, int32(len(elements)), gl.UNSIGNED_SHORT, nil)
  305.  
  306.         }
  307.         move += 1
  308.  
  309.         sdl.Delay(10)
  310.  
  311.         sdl.GL_SwapWindow(window)
  312.  
  313.     }
  314.  
  315.     sdl.GL_DeleteContext(context)
  316.     window.Destroy()
  317.     sdl.Quit()
  318. }
  319.  
  320. const (
  321.     winTitle           = "OpenGL Shader"
  322.     winWidth           = 640
  323.     winHeight          = 480
  324.     vertexShaderSource = `
  325. #version 330 core
  326.  
  327. // Input vertex data, different for all executions of this shader.
  328. in vec3 vertexPosition_modelspace;
  329.  
  330. in vec3 vertexColor;
  331.  
  332. in vec2 vertexUV;
  333.  
  334. // Output data ; will be interpolated for each fragment.
  335. out vec2 UV;
  336.  
  337. // Output data ; will be interpolated for each fragment.
  338. out vec3 fragmentColor;
  339.  
  340.  
  341. // Values that stay constant for the whole mesh.
  342. uniform mat4 MVP;
  343. void main(){
  344.  
  345.     gl_Position = MVP * vec4 (vertexPosition_modelspace,.5); //* MVP;
  346.  
  347.     // The color of each vertex will be interpolated
  348.     // to produce the color of each fragment
  349.     fragmentColor = vertexColor;
  350.  
  351.     // UV of the vertex. No special space for this one.
  352.     UV = vertexUV;
  353. }
  354. ` + "\x00"
  355.     fragmentShaderSource = `
  356. #version 330 core
  357.  
  358. // Interpolated values from the vertex shaders
  359. in vec3 fragmentColor;
  360.  
  361. // Interpolated values from the vertex shaders
  362. in vec2 UV;
  363.  
  364. // Ouput data
  365. out vec4 color;
  366.  
  367. // Values that stay constant for the whole mesh.
  368. uniform sampler2D myTextureSampler;
  369.  
  370. void main()
  371. {
  372.  
  373.     // // Output color = red
  374.     // color = vec4(fragmentColor,1.0);
  375.  
  376.     // Output color = color of the texture at the specified UV
  377.     color = texture2D( myTextureSampler, UV ).rgba;
  378.  
  379. }
  380. ` + "\x00"
  381. )
  382.  
  383. var triangle_vertices = []float32{
  384.     -0.5, 0.5, 1.0, // Top-left
  385.     0.5, 0.5, 1.0, // Top-right
  386.     0.5, -0.5, 1.0, // Bottom-right
  387.     -0.5, -0.5, 1.0, // Bottom-left
  388. }
  389.  
  390. var triangle_vertices2 = []float32{
  391.     -.8, -.8, -.8,
  392.     .2, -.8, -.8,
  393.     -3, 0.2, -.8,
  394. }
  395.  
  396. var elements = []uint16{
  397.     0, 1, 2,
  398.     2, 3, 0,
  399. }
  400.  
  401. var triangle_uvs = []float32{
  402.     0.0, 0.0,
  403.     1.0, 0.0,
  404.     1.0, 1.0,
  405.     0.0, 1.0,
  406. }
  407.  
  408. var triangle_colours = []float32{
  409.     0.583, 0.771, 0.014,
  410.     0.609, 0.115, 0.436,
  411.     0.327, 0.483, 0.844,
  412. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement