func createPlane(x0, y0, x1, y1 float32, verts [12]float32, indexes [6]uint32, uvs [8]float32, normals [12]float32) *Renderable { const floatSize = 4 const uintSize = 4 r := NewRenderable() gl.GenVertexArrays(1, &r.Vao) r.FaceCount = 2 // create a VBO to hold the vertex data gl.GenBuffers(1, &r.VertVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.VertVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(verts), gl.Ptr(&verts[0]), gl.STATIC_DRAW) // create a VBO to hold the uv data gl.GenBuffers(1, &r.UvVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.UvVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(uvs), gl.Ptr(&uvs[0]), gl.STATIC_DRAW) // create a VBO to hold the normals data gl.GenBuffers(1, &r.NormsVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.NormsVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(normals), gl.Ptr(&normals[0]), gl.STATIC_DRAW) // create a VBO to hold the face indexes gl.GenBuffers(1, &r.ElementsVBO) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.ElementsVBO) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, uintSize*len(indexes), gl.Ptr(&indexes[0]), gl.STATIC_DRAW) return r }
// Updating the list of Points that this LineRender should be rendering. func (lr *LineRender) UpdatePoints(points []Point) { // Determining the buffer mode. var mode uint32 if lr.static { mode = gl.STATIC_DRAW } else { mode = gl.DYNAMIC_DRAW } // Setting the number of points. lr.points = int32(len(points)) // Generating the buffer data. vboData := generateVBOData(points) eboData := generateEBOData(len(points)) // Filling the buffer data. gl.BindVertexArray(lr.vao) gl.BindBuffer(gl.ARRAY_BUFFER, lr.vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vboData)*4, gl.Ptr(vboData), mode) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, lr.ebo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(eboData)*4, gl.Ptr(eboData), mode) }
// Creating a RenderObject with a given shaderProgram, texture, and set of // vertices. func CreateRenderObject(shaderProgram ShaderProgram, texture Texture, vertices []float32) *RenderObject { renderObject := new(RenderObject) // Creating the basic information. renderObject.shaderProgram = uint32(shaderProgram) renderObject.texture = uint32(texture) gl.GenVertexArrays(1, &renderObject.vao) gl.GenBuffers(1, &renderObject.vbo) gl.GenBuffers(1, &renderObject.ebo) // Filling the RenderObject with information. gl.BindVertexArray(renderObject.vao) gl.BindBuffer(gl.ARRAY_BUFFER, renderObject.vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderObject.ebo) vertOrder := []uint32{ 0, 1, 2, 2, 3, 0, } gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertOrder)*4, gl.Ptr(vertOrder), gl.STATIC_DRAW) // Loading up vertex attributes. vertAttrib := uint32(gl.GetAttribLocation(renderObject.shaderProgram, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(0)) // Loading up texture attributes. texAttrib := uint32(gl.GetAttribLocation(renderObject.shaderProgram, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texAttrib) gl.VertexAttribPointer(texAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(2*4)) return renderObject }
func CreateSprite(t Texture) (s Sprite, err error) { s.texture = t s.shader, err = CreateShader(vertexShader, fragmentShader) if err != nil { return s, err } gl.GenBuffers(1, &s.ebo) gl.GenBuffers(1, &s.vbo) gl.GenVertexArrays(1, &s.vao) gl.BindVertexArray(s.vao) gl.BindBuffer(gl.ARRAY_BUFFER, s.vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, s.ebo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*4, gl.Ptr(indices), gl.STATIC_DRAW) err = s.shader.SetAttrib("vert", 2, gl.FLOAT, 4*4, 0) err = s.shader.SetAttrib("vertTexCoord", 2, gl.FLOAT, 4*4, 2*4) gl.BindVertexArray(0) return s, err }
func (lr *LinesRenderer) Draw(line *LineGeometry, mv mgl32.Mat4, style *LineStyle) (err error) { var ( dataBytes int = len(line.Vertices) * int(lr.stride) indexBytes int = len(line.Indices) * int(lr.stride) elementCount int32 = int32(len(line.Indices)) r, g, b, a = style.Color.RGBA() ) gl.Uniform1f(lr.thicknessLoc, style.Thickness) gl.Uniform1f(lr.innerLoc, style.Inner) gl.Uniform4f(lr.colorLoc, float32(r)/255.0, float32(g)/255.0, float32(b)/255.0, float32(a)/255.0) gl.UniformMatrix4fv(lr.modelviewLoc, 1, false, &mv[0]) if dataBytes > lr.bufferBytes { lr.bufferBytes = dataBytes gl.BufferData(gl.ARRAY_BUFFER, dataBytes, gl.Ptr(line.Vertices), gl.STREAM_DRAW) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, indexBytes, gl.Ptr(line.Indices), gl.STREAM_DRAW) } else { gl.BufferSubData(gl.ARRAY_BUFFER, 0, dataBytes, gl.Ptr(line.Vertices)) gl.BufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, indexBytes, gl.Ptr(line.Indices)) } gl.DrawElements(gl.TRIANGLES, elementCount, gl.UNSIGNED_INT, gl.PtrOffset(0)) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR: OpenGL error %X", e) } return }
func (t *Text) SetString(fs string, argv ...interface{}) { var indices []rune if len(argv) == 0 { indices = []rune(fs) } else { indices = []rune(fmt.Sprintf(fs, argv...)) } if len(indices) == 0 { return } if t.MaxRuneCount > 0 && len(indices) > t.MaxRuneCount+1 { indices = indices[0:t.MaxRuneCount] } t.String = string(indices) // ebo, vbo data glfloat_size := int32(4) t.vboIndexCount = len(indices) * 4 * 2 * 2 // 4 indexes per rune (containing 2 position + 2 texture) t.eboIndexCount = len(indices) * 6 // each rune requires 6 triangle indices for a quad t.RuneCount = len(indices) t.vboData = make([]float32, t.vboIndexCount, t.vboIndexCount) t.eboData = make([]int32, t.eboIndexCount, t.eboIndexCount) // generate the basic vbo data and bounding box t.X1 = Point{0, 0} t.X2 = Point{0, 0} t.makeBufferData(indices) // find the centered position of the bounding box lowerLeft := t.getLowerLeft() // reposition the vbo data so that it is centered at (0,0) // according to the orthographic projection being used t.setDataPosition(lowerLeft) if t.IsDebug { fmt.Printf("bounding box %v %v\n", t.X1, t.X2) fmt.Printf("lower left\n%v\n", lowerLeft) fmt.Printf("text vbo data\n%v\n", t.vboData) fmt.Printf("text ebo data\n%v\n", t.eboData) } gl.BindVertexArray(t.vao) gl.BindBuffer(gl.ARRAY_BUFFER, t.vbo) gl.BufferData( gl.ARRAY_BUFFER, int(glfloat_size)*t.vboIndexCount, gl.Ptr(t.vboData), gl.DYNAMIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, t.ebo) gl.BufferData( gl.ELEMENT_ARRAY_BUFFER, int(glfloat_size)*t.eboIndexCount, gl.Ptr(t.eboData), gl.DYNAMIC_DRAW) gl.BindVertexArray(0) // not necesssary, but i just want to better understand using vertex arrays gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) // SetString can be called at anytime. we want to make sure that if the user is updating the text, // the previous position will be maintained t.SetPosition(t.SetPositionX, t.SetPositionY) }
func (b *GLBuffer) Upload(data interface{}, size int) { b.Bind() if size > b.bufferBytes { b.bufferBytes = size gl.BufferData(b.target, size, gl.Ptr(data), gl.STREAM_DRAW) } else { gl.BufferSubData(b.target, 0, size, gl.Ptr(data)) } }
//Call this function once to enable debug print message (to stdout). Will not crash if your machine does not support GL_ARB_debug_output func EnableGLDebugLogging() { if lux.Extensions["GL_ARB_debug_output"] { log.Print("debugging enabled") gl.Enable(gl.DEBUG_OUTPUT_SYNCHRONOUS_ARB) gl.DebugMessageCallbackARB(gl.DebugProc(glDebugCallback), gl.Ptr(nil)) } }
func getGLTexture(img image.Image, smoothing TextureSmoothing) (t uint32, err error) { var ( data *bytes.Buffer bounds image.Rectangle width int height int ) if data, err = imageBytes(img); err != nil { return } bounds = img.Bounds() width = bounds.Max.X - bounds.Min.X height = bounds.Max.Y - bounds.Min.Y gl.GenTextures(1, &t) gl.BindTexture(gl.TEXTURE_2D, t) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int32(smoothing)) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int32(smoothing)) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_INT_8_8_8_8, gl.Ptr(data.Bytes()), ) gl.GenerateMipmap(gl.TEXTURE_2D) gl.BindTexture(gl.TEXTURE_2D, 0) return }
func newTexture(file string, texNum uint32) (uint32, error) { imgFile, err := os.Open(file) if err != nil { return 0, err } img, _, err := image.Decode(imgFile) 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.ZP, draw.Src) var texture uint32 gl.GenTextures(1, &texture) gl.ActiveTexture(texNum) 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.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 }
func createArrayBuffer(data []float32) uint32 { var name uint32 gl.GenBuffers(1, &name) gl.BindBuffer(gl.ARRAY_BUFFER, name) gl.BufferData(gl.ARRAY_BUFFER, len(data)*4 /* total bytes */, gl.Ptr(data), gl.STATIC_DRAW) gl.BindBuffer(gl.ARRAY_BUFFER, 0) return name }
func createElementArrayBuffer(data []uint16) uint32 { var name uint32 gl.GenBuffers(1, &name) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, name) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(data)*2 /* total bytes */, gl.Ptr(data), gl.STATIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) return name }
//CreateVertexArray is a "constructor" of vertex array, hence returns a opengl //mesh, specifically a cube for testing func CreateVertexArray() VertexArray { var vertexArray VertexArray cubeVertices := vertexArray.PosData() gl.GenVertexArrays(1, &vertexArray.handleVAO) gl.BindVertexArray(vertexArray.handleVAO) gl.GenBuffers(1, &vertexArray.handleVBO) gl.BindBuffer(gl.ARRAY_BUFFER, vertexArray.handleVBO) gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW) return vertexArray }
func Draw() { // if len(layers) == 0 { // fmt.Println("layers empty!!!") // return // } // for _, layer := range layers { // vertexData := textureHash[layer] vertexData := &vertexDataTest // check to see if there are any vertices at all to draw if len(vertexData.vertexData) == 0 { return } // vertexData.Print() // vertexData := vertexDataTest //vertexData.Print() // BindBuffers(vertexData) // vertexData.Print() //gl.BufferSubData(gl.ARRAY_BUFFER, 0, len(vertexData.VertexData)*4, gl.Ptr(vertexData.VertexData)) // gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vertexData.vertexData)*4, gl.Ptr(vertexData.vertexData), gl.DYNAMIC_DRAW) // gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementvbo) // gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertexData.Elements)*4, gl.Ptr(vertexData.Elements), gl.DYNAMIC_DRAW) MVP := projectionM.Mul4(viewM) //.Mul4(Model) gl.UniformMatrix4fv(MVPid, 1, false, &MVP[0]) lightPos := mathgl.Vec3{0, 3, 10} lightintensities := mathgl.Vec3{1, .4, .2} gl.Uniform3f(lightpositionID, lightPos[0], lightPos[1], lightPos[2]) gl.Uniform3f(lightintensitiesID, lightintensities[0], lightintensities[1], lightintensities[2]) gl.Uniform3f(cameraPositionID, 0.0, 1.0, -1.0) // vertexData.Print() // gl.DrawElements(gl.TRIANGLES, int32(len(vertexData.Elements)), gl.UNSIGNED_INT, nil) // } numTriVerts := int32((len(vertexData.vertexData) / (int(NUM_ATTRIBUTES) * 2)) * 3) gl.DrawArrays(gl.TRIANGLES, 0, numTriVerts) ClearVertexData() }
func (r *Framerate) Render(camera *core.Camera) (err error) { r.data.Sample() var ( modelView = mgl32.Ident4() dataBytes int = int(r.data.Count) * int(r.stride) ) gl.Uniform4f(r.locColor, 255.0/255.0, 0, 0, 255.0/255.0) gl.UniformMatrix4fv(r.locModelView, 1, false, &modelView[0]) gl.UniformMatrix4fv(r.locProjection, 1, false, &camera.Projection[0]) if dataBytes > r.vboBytes { r.vboBytes = dataBytes gl.BufferData(gl.ARRAY_BUFFER, dataBytes, gl.Ptr(r.data.Points), gl.STREAM_DRAW) } else { gl.BufferSubData(gl.ARRAY_BUFFER, 0, dataBytes, gl.Ptr(r.data.Points)) } gl.DrawArrays(gl.POINTS, 0, r.data.Count) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR: OpenGL error %X", e) } return }
func BindBuffers() { //vertexData *OpenGLVertexInfo) { vertexData := &vertexDataTest // check to see if there are any vertices at all to bind if len(vertexData.vertexData) == 0 { return } gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vertexData.vertexData)*4, gl.Ptr(vertexData.vertexData), gl.DYNAMIC_DRAW) positionAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertexPosition_modelspace\x00"))) gl.EnableVertexAttribArray(positionAttrib) gl.VertexAttribPointer(positionAttrib, 3, gl.FLOAT, false, 4*NUM_ATTRIBUTES, gl.PtrOffset(0)) colorAttrib := uint32(gl.GetAttribLocation(program, gl.Str("diffuse\x00"))) gl.EnableVertexAttribArray(colorAttrib) gl.VertexAttribPointer(colorAttrib, 4, gl.FLOAT, false, 4*NUM_ATTRIBUTES, gl.PtrOffset(3*4)) uvAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertexUV\x00"))) gl.EnableVertexAttribArray(uvAttrib) gl.VertexAttribPointer(uvAttrib, 2, gl.FLOAT, false, 4*NUM_ATTRIBUTES, gl.PtrOffset(7*4)) mNormAttrib := uint32(gl.GetAttribLocation(program, gl.Str("mNorm\x00"))) gl.EnableVertexAttribArray(mNormAttrib) gl.VertexAttribPointer(mNormAttrib, 3, gl.FLOAT, false, 4*NUM_ATTRIBUTES, gl.PtrOffset(9*4)) wNormAttrib := uint32(gl.GetAttribLocation(program, gl.Str("wNorm\x00"))) gl.EnableVertexAttribArray(wNormAttrib) gl.VertexAttribPointer(wNormAttrib, 3, gl.FLOAT, false, 4*NUM_ATTRIBUTES, gl.PtrOffset(12*4)) shaderMode := uint32(gl.GetAttribLocation(program, gl.Str("mode\x00"))) gl.EnableVertexAttribArray(shaderMode) gl.VertexAttribPointer(shaderMode, 1, gl.FLOAT, false, 4*NUM_ATTRIBUTES, gl.PtrOffset(15*4)) samplerIdx := uint32(gl.GetAttribLocation(program, gl.Str("samplerIdx\x00"))) gl.EnableVertexAttribArray(samplerIdx) gl.VertexAttribPointer(samplerIdx, 1, gl.FLOAT, false, 4*NUM_ATTRIBUTES, gl.PtrOffset(16*4)) // gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementvbo) // gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertexData.Elements)*4, gl.Ptr(vertexData.Elements), gl.STATIC_DRAW) // gl.ActiveTexture(gl.TEXTURE0) // gl.BindTexture(gl.TEXTURE_2D, 1) }
// Attempting to load a Texture from a given location on the disk. func LoadTexture(path string) (Texture, error) { // Loading the image data. imgFile, err := os.Open(path) if err != nil { return 0, 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, errors.New("Unsupported stride.") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) // Generating and populating the texture. 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(texture), nil }
func MakeRandomTexture(textureSlot int) (Texture, error) { texture := NewTexture() texture.Bind(textureSlot) // gl.Enable(gl.TEXTURE_2D) // for some ATI drivers, for mipmap gen gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) Check() var anisotropy float32 gl.GetFloatv(MaxTextureMaxAnisotropyExt, &anisotropy) Check() gl.TexParameterf(gl.TEXTURE_2D, TextureMaxAnisotropyExt, anisotropy) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 0) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0) Check() var pix [3 * 700 * 700]byte for i := 0; i < 3*700*700; i++ { pix[i] = byte(128 + i/16) } gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGB, 700, 700, 0, gl.RGB, gl.UNSIGNED_BYTE, gl.Ptr(&pix[0])) Check() return texture, nil }
func CreateTexture(file string) (Texture, error) { imgFile, err := os.Open(file) if err != nil { return Texture{}, err } img, _, err := image.Decode(imgFile) if err != nil { return Texture{}, err } rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return Texture{}, fmt.Errorf("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) width, height := int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y) 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, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix)) return Texture{Id: texture, Width: width, Height: height}, nil }
func CreateVBO(size int, data interface{}, usage uint32) (buffer uint32, err error) { gl.GenBuffers(1, &buffer) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR gl.GenBuffer %X", e) return } gl.BindBuffer(gl.ARRAY_BUFFER, buffer) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR buffer.Bind %X", e) return } gl.BufferData(gl.ARRAY_BUFFER, size, gl.Ptr(data), usage) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR gl.BufferData %X", e) return } gl.BindBuffer(gl.ARRAY_BUFFER, 0) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR buffer.Unbind %X", e) return } return }
func (texture Texture) Load(textureSlot int, rgba *image.RGBA) { texture.Bind(textureSlot) // gl.Enable(gl.TEXTURE_2D) // for some ATI drivers, for mipmap gen gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) Check() var anisotropy float32 gl.GetFloatv(MaxTextureMaxAnisotropyExt, &anisotropy) Check() gl.TexParameterf(gl.TEXTURE_2D, TextureMaxAnisotropyExt, anisotropy) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 0) Check() gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0) Check() 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)) Check() }
func (tr *SpriteRenderer) Draw(instances []SpriteConfig) error { var ( bytesNeeded int byteoffset int count int32 data unsafe.Pointer float float32 = 0 floatSize uint32 i uint32 offset unsafe.Pointer sprite SpriteConfig stride int32 ) floatSize = uint32(unsafe.Sizeof(float)) stride = int32(unsafe.Sizeof(sprite)) gl.UseProgram(tr.program) gl.Uniform1i(tr.textureUnitLoc, 0) // Instance data binding gl.BindBuffer(gl.ARRAY_BUFFER, tr.instanceVBO) count = int32(len(instances)) bytesNeeded = int(stride * count) data = gl.Ptr(instances) if bytesNeeded > tr.instanceBytes { gl.BufferData(gl.ARRAY_BUFFER, bytesNeeded, data, gl.STREAM_DRAW) tr.instanceBytes = bytesNeeded } else { gl.BufferSubData(gl.ARRAY_BUFFER, 0, bytesNeeded, data) } gl.EnableVertexAttribArray(tr.translationLoc) gl.VertexAttribPointer(tr.translationLoc, 3, gl.FLOAT, false, stride, tr.offAttrX) gl.VertexAttribDivisor(tr.translationLoc, 1) gl.EnableVertexAttribArray(tr.rotationLoc) gl.VertexAttribPointer(tr.rotationLoc, 3, gl.FLOAT, false, stride, tr.offAttrRotationX) gl.VertexAttribDivisor(tr.rotationLoc, 1) gl.EnableVertexAttribArray(tr.scaleLoc) gl.VertexAttribPointer(tr.scaleLoc, 3, gl.FLOAT, false, stride, tr.offAttrScaleX) gl.VertexAttribDivisor(tr.scaleLoc, 1) gl.EnableVertexAttribArray(tr.colorLoc) gl.VertexAttribPointer(tr.colorLoc, 4, gl.FLOAT, false, stride, tr.offAttrColor) gl.VertexAttribDivisor(tr.colorLoc, 1) for i = 0; i < 4; i++ { byteoffset = int(i * 4 * floatSize) offset = gl.PtrOffset(tr.offAttrPointAdj + byteoffset) gl.EnableVertexAttribArray(tr.pointAdjLoc + i) gl.VertexAttribPointer(tr.pointAdjLoc+i, 4, gl.FLOAT, false, stride, offset) gl.VertexAttribDivisor(tr.pointAdjLoc+i, 1) offset = gl.PtrOffset(tr.offAttrTextureAdj + byteoffset) gl.EnableVertexAttribArray(tr.textureAdjLoc + i) gl.VertexAttribPointer(tr.textureAdjLoc+i, 4, gl.FLOAT, false, stride, offset) gl.VertexAttribDivisor(tr.textureAdjLoc+i, 1) } // Projection gl.UniformMatrix4fv(tr.projectionLoc, 1, false, &tr.Renderer.Camera.Projection[0]) // Actually draw. gl.DrawArraysInstanced(gl.TRIANGLES, 0, 6, int32(len(instances))) // Undo instance attr repetition. gl.VertexAttribDivisor(tr.translationLoc, 0) gl.VertexAttribDivisor(tr.rotationLoc, 0) gl.VertexAttribDivisor(tr.scaleLoc, 0) gl.VertexAttribDivisor(tr.colorLoc, 0) for i = 0; i < 4; i++ { gl.VertexAttribDivisor(tr.pointAdjLoc+i, 0) gl.VertexAttribDivisor(tr.textureAdjLoc+i, 0) } gl.BindBuffer(gl.ARRAY_BUFFER, 0) return nil }
func CreateContext(width, height int) Context { vertexShader := ` #version 330 uniform mat4 projection; uniform mat4 camera; uniform mat4 model; in vec3 vert; void main() { gl_Position = projection * camera * model * vec4(vert, 1); } ` + "\x00" fragmentShader := ` #version 330 uniform vec4 color; out vec4 outputColor; void main() { outputColor = color; } ` + "\x00" vertices := []float32{ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, } 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, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(width, height, "OpenGL", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() if err := gl.Init(); err != nil { panic(err) } program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Ortho2D(0, 800, 0, 600) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV(mgl32.Vec3{0, 0, 0.5}, 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]) 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, 3*4, gl.PtrOffset(0)) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) return Context{Window: window, program: program} }
func main() { vertices, normals := obj.Parse(os.Args[1]) // initialize GLFW if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() // set opengl core profile 3.3 glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(640, 480, "GOpenGL", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // initialise OpenGL library if err := gl.Init(); err != nil { panic(err) } // link program from shaders program, err := newProgram("vertex.glsl", "fragment.glsl") if err != nil { panic(err) } gl.UseProgram(program) // vertex attribute object holds links between attributes and vbo var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) // vertex buffer with per-vertex data var vbo [2]uint32 gl.GenBuffers(2, &vbo[0]) // position data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[0]) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) // set up position attribute with layout of vertices posAttrib := uint32(gl.GetAttribLocation(program, gl.Str("position\x00"))) gl.VertexAttribPointer(posAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(posAttrib) // normal data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[1]) gl.BufferData(gl.ARRAY_BUFFER, len(normals)*4, gl.Ptr(normals), gl.STATIC_DRAW) normAttrib := uint32(gl.GetAttribLocation(program, gl.Str("normal\x00"))) gl.VertexAttribPointer(normAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(normAttrib) uniModel := gl.GetUniformLocation(program, gl.Str("model\x00")) uniView := gl.GetUniformLocation(program, gl.Str("view\x00")) uniProj := gl.GetUniformLocation(program, gl.Str("proj\x00")) matView := mgl32.LookAt(2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0) gl.UniformMatrix4fv(uniView, 1, false, &matView[0]) matProj := mgl32.Perspective(mgl32.DegToRad(45.0), 640.0/480.0, 1.0, 10.0) gl.UniformMatrix4fv(uniProj, 1, false, &matProj[0]) uniLightDir := gl.GetUniformLocation(program, gl.Str("lightDir\x00")) uniLightCol := gl.GetUniformLocation(program, gl.Str("lightCol\x00")) gl.Uniform3f(uniLightDir, -0.5, 0.0, -1.0) gl.Uniform3f(uniLightCol, 0.0, 0.5, 0.5) startTime := glfw.GetTime() gl.Enable(gl.DEPTH_TEST) gl.ClearColor(1.0, 1.0, 1.0, 1.0) for !window.ShouldClose() { // clear buffer gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) matRot := mgl32.HomogRotate3DZ(float32(glfw.GetTime() - startTime)) gl.UniformMatrix4fv(uniModel, 1, false, &matRot[0]) gl.DrawArrays(gl.TRIANGLES, 0, int32(len(vertices))) window.SwapBuffers() glfw.PollEvents() } }
func (m *mesh) drawElements() { gl.BindVertexArray(m.vao) gl.DrawElements(gl.TRIANGLES, m.count, gl.UNSIGNED_SHORT, gl.Ptr(nil)) gl.BindVertexArray(0) }
func GetGLTexture(img image.Image, smoothing TextureSmoothing) (t uint32, err error) { var ( data *bytes.Buffer bounds image.Rectangle width int height int ) if data, err = imageBytes(img); err != nil { return } bounds = img.Bounds() width = bounds.Max.X - bounds.Min.X height = bounds.Max.Y - bounds.Min.Y gl.GenTextures(1, &t) if e := gl.GetError(); e != 0 { fmt.Printf("ggt1 ERROR: %s\n", e) } gl.BindTexture(gl.TEXTURE_2D, t) if e := gl.GetError(); e != 0 { fmt.Printf("ggt2 ERROR: %s\n", e) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int32(smoothing)) if e := gl.GetError(); e != 0 { fmt.Printf("ggt3 ERROR: %s\n", e) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int32(smoothing)) if e := gl.GetError(); e != 0 { fmt.Printf("ggt4 ERROR: %s\n", e) } gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_INT_8_8_8_8, gl.Ptr(data.Bytes())) if e := gl.GetError(); e != 0 { fmt.Printf("ggt5 ERROR: %s\n", e) } gl.GenerateMipmap(gl.TEXTURE_2D) if e := gl.GetError(); e != 0 { fmt.Printf("ggt6 ERROR: %s\n", e) } gl.BindTexture(gl.TEXTURE_2D, 0) if e := gl.GetError(); e != 0 { fmt.Printf("ggt7 ERROR: %s\n", e) } return }
func (c *Chunk) buildLandscapeRenderable() *fizzle.Renderable { var xmax, ymax, zmax float32 = 1.0, 1.0, 1.0 var xmin, ymin, zmin float32 = 0.0, 0.0, 0.0 /* Cube vertices are layed out like this: +--------+ 6 5 / | /| +--------+ | 1 0 +Y | | | | |___ +X | +------|-+ 7 4 / |/ |/ +Z +--------+ 2 3 */ verts := [...]float32{ xmax, ymax, zmax, xmin, ymax, zmax, xmin, ymin, zmax, xmax, ymin, zmax, // v0,v1,v2,v3 (front) xmax, ymax, zmin, xmax, ymax, zmax, xmax, ymin, zmax, xmax, ymin, zmin, // v5,v0,v3,v4 (right) xmax, ymax, zmin, xmin, ymax, zmin, xmin, ymax, zmax, xmax, ymax, zmax, // v5,v6,v1,v0 (top) xmin, ymax, zmax, xmin, ymax, zmin, xmin, ymin, zmin, xmin, ymin, zmax, // v1,v6,v7,v2 (left) xmax, ymin, zmax, xmin, ymin, zmax, xmin, ymin, zmin, xmax, ymin, zmin, // v3,v2,v7,v4 (bottom) xmin, ymax, zmin, xmax, ymax, zmin, xmax, ymin, zmin, xmin, ymin, zmin, // v6,v5,v4,v7 (back) } indexes := [...]uint32{ 0, 1, 2, 2, 3, 0, } uvs := [...]float32{ 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, } normals := [...]float32{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front) 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v5,v0,v3,v4 (right) 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v5,v6,v1,v0 (top) -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left) 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v3,v2,v7,v4 (bottom) 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, // v6,v5,v4,v7 (back) } sectorVerts := make([]float32, 0, len(verts)*ChunkSize3) sectorNormals := make([]float32, 0, len(verts)*ChunkSize3) sectorIndexes := make([]uint32, 0, len(indexes)*ChunkSize3) sectorUVs := make([]float32, 0, len(uvs)*ChunkSize3) const comboFloatsPerGrid int = len(verts) sectorCombo := make([]float32, 0, comboFloatsPerGrid*ChunkSize3) var faceCount uint32 // create some temporary buffers instVerts := make([]float32, 12) instIndexes := make([]uint32, 6) instNorms := make([]float32, 12) instCombo := make([]float32, 12) // loop through each block for y := 0; y < ChunkSize; y++ { for x := 0; x < ChunkSize; x++ { for z := 0; z < ChunkSize; z++ { worldX := c.X*ChunkSize + x worldY := c.Y*ChunkSize + y worldZ := c.Z*ChunkSize + z // if the block itself is not visible, then just move on if c.IsBlockVisible(x, y, z) == false { continue } // get the block block := c.BlockAt(x, y, z) // process each face on the block separately currentFaceCount := 0 for face := 0; face < 6; face++ { // do we need this face? check to see if there's an obstructing block. // NOTE: this is done with a lame implementation right now, because // going back to the manager isn't efficient. switch { case face == 0: b, _ := c.Owner.GetBlockAt(worldX, worldY, worldZ+1) if b != nil && b.Type > 0 { continue } case face == 1: b, _ := c.Owner.GetBlockAt(worldX+1, worldY, worldZ) if b != nil && b.Type > 0 { continue } case face == 2: b, _ := c.Owner.GetBlockAt(worldX, worldY+1, worldZ) if b != nil && b.Type > 0 { continue } case face == 3: b, _ := c.Owner.GetBlockAt(worldX-1, worldY, worldZ) if b != nil && b.Type > 0 { continue } case face == 4: b, _ := c.Owner.GetBlockAt(worldX, worldY-1, worldZ) if b != nil && b.Type > 0 { continue } case face == 5: b, _ := c.Owner.GetBlockAt(worldX, worldY, worldZ-1) if b != nil && b.Type > 0 { continue } } // time to make the vertices baseV := face * 12 for iv := 0; iv < 4; iv++ { iv3 := iv * 3 instVerts[iv3] = verts[baseV+iv3] + float32(x) instVerts[iv3+1] = verts[baseV+iv3+1] + float32(y) instVerts[iv3+2] = verts[baseV+iv3+2] + float32(z) // add the normals too instNorms[iv3] = normals[baseV+iv3] instNorms[iv3+1] = normals[baseV+iv3+1] instNorms[iv3+2] = normals[baseV+iv3+2] // add the combo, per-vertex data as well instCombo[iv3] = float32(block.Color[0]) / 256.0 instCombo[iv3+1] = float32(block.Color[1]) / 256.0 instCombo[iv3+2] = float32(block.Color[2]) / 256.0 } // time to make the element indeces for iv := 0; iv < 6; iv++ { instIndexes[iv] = indexes[iv] + uint32(currentFaceCount*4) + uint32(faceCount*2) } sectorVerts = append(sectorVerts, instVerts...) sectorIndexes = append(sectorIndexes, instIndexes...) sectorUVs = append(sectorUVs, uvs[:]...) sectorNormals = append(sectorNormals, instNorms...) sectorCombo = append(sectorCombo, instCombo...) // we're not skiping the face, so lets boost the count currentFaceCount += 1 } faceCount += uint32(currentFaceCount) * 2 } // z } // x } // y // if we didn't make any faces, just stop here and return an empty renderable r := fizzle.NewRenderable() r.Core = fizzle.NewRenderableCore() if faceCount < 1 { return r } r.ShaderName = "landscape" r.FaceCount = faceCount r.BoundingRect.Top[0] = ChunkSize r.BoundingRect.Top[1] = ChunkSize r.BoundingRect.Top[2] = ChunkSize r.Location[0] = float32(c.X * ChunkSize) r.Location[1] = float32(c.Y * ChunkSize) r.Location[2] = float32(c.Z * ChunkSize) r.Core.DiffuseColor[0] = 1.0 r.Core.DiffuseColor[1] = 1.0 r.Core.DiffuseColor[2] = 1.0 r.Core.DiffuseColor[3] = 1.0 r.Core.SpecularColor[0] = 1.0 r.Core.SpecularColor[1] = 1.0 r.Core.SpecularColor[2] = 1.0 r.Core.SpecularColor[3] = 1.0 r.Core.Shininess = 0.00 // calculate the memory size of floats used to calculate total memory size of float arrays const floatSize = 4 const uintSize = 4 //groggy.Logsf("DEBUG", "buildLandscapeRenderable() v:%d, uv:%d, n:%d, elem:%d, faces:%d", len(sectorVerts), len(sectorUVs), len(sectorNormals), len(sectorIndexes), faceCount) // create a VBO to hold the vertex data gl.GenBuffers(1, &r.Core.VertVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.VertVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorVerts), gl.Ptr(§orVerts[0]), gl.STATIC_DRAW) // create a VBO to hold the uv data gl.GenBuffers(1, &r.Core.UvVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.UvVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorUVs), gl.Ptr(§orUVs[0]), gl.STATIC_DRAW) // create a VBO to hold the normals data gl.GenBuffers(1, &r.Core.NormsVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.NormsVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorNormals), gl.Ptr(§orNormals[0]), gl.STATIC_DRAW) // create a VBO to hold the combo data gl.GenBuffers(1, &r.Core.ComboVBO1) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.ComboVBO1) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorCombo), gl.Ptr(§orCombo[0]), gl.STATIC_DRAW) // create a VBO to hold the face indexes gl.GenBuffers(1, &r.Core.ElementsVBO) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.Core.ElementsVBO) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, uintSize*len(sectorIndexes), gl.Ptr(§orIndexes[0]), gl.STATIC_DRAW) return r }
func main() { // init glfw if err := glfw.Init(); err != nil { panic(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) // make an application window window, err := glfw.CreateWindow(windowWidth, windowHeight, "Hello", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // init gl if err := gl.Init(); err != nil { panic(err) } fmt.Println("OpenGL version", gl.GoStr(gl.GetString(gl.VERSION))) // create vertex & fragment shader program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) gl.BindFragDataLocation(program, 0, gl.Str("fc\x00")) points := []float32{ -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, } vertices := []uint32{ 0, 2, 1, 3, } // configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) defer gl.BindVertexArray(0) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(points)*4, gl.Ptr(points), gl.STATIC_DRAW) var ibo uint32 gl.GenBuffers(1, &ibo) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("pv\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 2, gl.FLOAT, false, 2*4, gl.PtrOffset(0)) // global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.UseProgram(program) gl.BindVertexArray(vao) gl.DrawElements(gl.LINE_LOOP, 4, gl.UNSIGNED_INT, gl.PtrOffset(0)) window.SwapBuffers() glfw.PollEvents() } }
func bindAggregateImage(img image.Image, idx int) uint32 { newIdx := idx if rgba, ok := img.(*image.RGBA); ok { gl.GenTextures(1, &textures[newIdx]) gl.ActiveTexture(gl.TEXTURE0 + uint32(newIdx)) gl.BindTexture(gl.TEXTURE_2D, textures[newIdx]) 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.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, 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)) gl.GenerateMipmap(gl.TEXTURE_2D) idxS := strconv.Itoa(newIdx) fmt.Println("idx: ", int32(newIdx), "myTextureSampler["+idxS+"]\x00") gl.Uniform1i(gl.GetUniformLocation(program, gl.Str("myTextureSampler["+idxS+"]\x00")), int32(newIdx)) if ok := gl.GetError(); ok != gl.NO_ERROR { fmt.Println("1- Cannot load Image in location: ./: ", ok) os.Exit(-1) } return textures[newIdx] } else { fmt.Println("Image not RGBA at location: ./") os.Exit(-1) } return 0 }
//LoadPng tries to load a png file from hard drive and upload it to the GPU. func LoadPng(file string) (gl2.Texture2D, error) { imgFile, err := os.Open(file) if err != nil { return 0, nil } defer imgFile.Close() img, _, err := image.Decode(imgFile) if err != nil { return 0, nil } 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) texture := gl2.GenTexture2D() gl.ActiveTexture(gl2.TEXTURE0) texture.Bind() defer texture.Unbind() texture.MinFilter(gl2.LINEAR) texture.MagFilter(gl2.LINEAR) texture.WrapS(gl2.CLAMP_TO_EDGE) texture.WrapT(gl2.CLAMP_TO_EDGE) texture.TexImage2D(0, gl2.RGBA, int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y), 0, gl2.RGBA, gl2.UNSIGNED_BYTE, gl.Ptr(rgba.Pix)) return texture, nil }