Go Lang OpenGL简单形状 – 空白屏幕

huangapple go评论142阅读模式
英文:

Go Lang OpenGL simple shape - blank screen

问题

我需要一些帮助,了解为什么这段代码会产生一个空白的绿色窗口。我通过结合来自https://github.com/Jragonmiris/mathgl/blob/master/examples/opengl-tutorial/tutorial02/main.go和https://github.com/veandco/go-sdl2/blob/master/examples/opengl3.go的示例来创建这段代码。我不确定这是GoLang sdl/gl框架的一个错误还是我对OpenGL的理解有问题。这段代码应该只会绘制一个立方体。

我的代码是:

package main

import (
	"fmt"
	"github.com/veandco/go-sdl2/sdl"
	"github.com/Jragonmiris/mathgl"
	"github.com/go-gl/gl"
	"runtime"
	"time"
)

func MakeProgram(vert, frag string) gl.Program {
	vertShader, fragShader := gl.CreateShader(gl.VERTEX_SHADER), gl.CreateShader(gl.FRAGMENT_SHADER)
	vertShader.Source(vert)
	fragShader.Source(frag)

	vertShader.Compile()
	fragShader.Compile()

	prog := gl.CreateProgram()

	prog.AttachShader(vertShader)
	prog.AttachShader(fragShader)
	prog.Link()
	prog.Validate()
	fmt.Println(prog.GetInfoLog())

	return prog
}

func main() {
	var window *sdl.Window
	var context sdl.GLContext
	var event sdl.Event
	var running bool
	var err error

	runtime.LockOSThread()

	if 0 != sdl.Init(sdl.INIT_EVERYTHING) {
		panic(sdl.GetError())
	}
	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		winWidth, winHeight, sdl.WINDOW_OPENGL)
	if err != nil {
		panic(err)
	}
	if window == nil {
		panic(sdl.GetError())
	}
	context = sdl.GL_CreateContext(window)
	if context == nil {
		panic(sdl.GetError())
	}

	if gl.Init() != 0 {
		panic("gl error")
	}

	gl.ClearColor(1.0, 1.0, 1.0, .5)
	gl.Viewport(0, 0, winWidth, winHeight)

	program := MakeProgram(vertexShaderSource, fragmentShaderSource)
	defer program.Delete()

	matrixID := program.GetUniformLocation("MVP")
	Projection := mathgl.Perspective(45.0, 4.0/3.0, 0.1, 100.0)
	View := mathgl.LookAt(4.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
	Model := mathgl.Ident4f()
	MVP := Projection.Mul4(View).Mul4(Model) 

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

	vertexArray := gl.GenVertexArray()
	defer vertexArray.Delete()
	vertexArray.Bind()

	buffer := gl.GenBuffer()
	defer buffer.Delete()
	buffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, &triangle_vertices, gl.STATIC_DRAW)

	running = true
	for running {
		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch t := event.(type) {
			case *sdl.QuitEvent:
				running = false
			case *sdl.MouseMotionEvent:
				fmt.Printf(string(t.Timestamp))
			}
		}

		gl.Clear(gl.COLOR_BUFFER_BIT)
		program.Use()
		matrixID.UniformMatrix4fv(false, MVP)
		attribLoc := gl.AttribLocation(0)
		attribLoc.EnableArray()
		buffer.Bind(gl.ARRAY_BUFFER)
		attribLoc.AttribPointer(3, gl.FLOAT, false, 0, nil)

		gl.DrawArrays(gl.TRIANGLES, 0, 3)

		attribLoc.DisableArray()

		time.Sleep(50 * time.Millisecond)

		sdl.GL_SwapWindow(window)
	}

	sdl.GL_DeleteContext(context)
	window.Destroy()
	sdl.Quit()
}

const (
	winTitle           = "OpenGL Shader"
	winWidth           = 640
	winHeight          = 480
	vertexShaderSource = `
	#version 330 core

	layout(location = 0) in vec3 vertexPosition_modelspace;
	uniform mat4 MVP;
	void main(){
	    gl_Position = MVP * vec4 (vertexPosition_modelspace,1.0);
	}
	`
	fragmentShaderSource = `
	#version 330 core

	out vec3 color;

	void main()
	{
	    color = vec3(1,0,0);
	}
	`
)

var triangle_vertices = []float32{
	-.5, -.5, -.5,
	.5, -.5, -.5,
	0.0, 0.5, -.5,
}

所以我仍然无法在屏幕上绘制一个简单的形状。我做了一些更改,比如简化了我的形状(一个三角形)。我创建了坐标,使它们更接近-z轴,以便我能够看到它们,但这没有起作用。然后,我设置了MVP矩阵(将相机后移一些)只是为了确保。我的着色器很简单,因为我只传入了一个vec3顶点位置和mat4 MVP矩阵,所以我认为着色器工作正常?对于所有的困惑,我想我可能漏掉了什么。

更新:
我还运行了OpenGL的版本命令:

fmt.Println(gl.GetString(gl.VERSION))
fmt.Println(gl.GetString(gl.VENDOR))
fmt.Println(gl.GetString(gl.RENDERER))

输出结果为:

4.5.0 NVIDIA 347.09
NVIDIA Corporation
GeForce GTX 650 Ti/PCIe/SSE2

不确定这是否有任何影响?

更新:
我查看了一些其他示例,并决定尝试添加一些sdl属性,但仍然没有运气:

sdl.GL_SetAttribute(sdl.GL_DOUBLEBUFFER, 1)
sdl.GL_SetAttribute(sdl.GL_RED_SIZE, 8)
sdl.GL_SetAttribute(sdl.GL_GREEN_SIZE, 8)
sdl.GL_SetAttribute(sdl.GL_BLUE_SIZE, 8)
sdl.GL_SetAttribute(sdl.GL_ALPHA_SIZE, 8)

更新:
我修改了这篇文章,只包含最近的代码,以免让人们对TLDR感到恐慌。

英文:

I need some assistance into why this piece of code produces a blank green window. I made this by combining examples from https://github.com/Jragonmiris/mathgl/blob/master/examples/opengl-tutorial/tutorial02/main.go and https://github.com/veandco/go-sdl2/blob/master/examples/opengl3.go. I guess i'm not sure if this is a bug with the GoLang sdl/gl framework or an issue with my OpenGL understanding. All this should draw is a cube.

My code is:

package main

import (
"fmt"
// gl "github.com/chsc/gogl/gl33"
"github.com/veandco/go-sdl2/sdl"
// "math"
"github.com/Jragonmiris/mathgl"
"github.com/go-gl/gl"
"runtime"
"time"
)
// var program gl.Program = 0
// var buffer gl.Buffer = 0
func MakeProgram(vert, frag string) gl.Program {
vertShader, fragShader := gl.CreateShader(gl.VERTEX_SHADER), gl.CreateShader(gl.FRAGMENT_SHADER)
vertShader.Source(vert)
fragShader.Source(frag)
vertShader.Compile()
fragShader.Compile()
prog := gl.CreateProgram()
prog.AttachShader(vertShader)
prog.AttachShader(fragShader)
prog.Link()
prog.Validate()
fmt.Println(prog.GetInfoLog())
return prog
}
func main() {
var window *sdl.Window
var context sdl.GLContext
var event sdl.Event
var running bool
var err error
runtime.LockOSThread()
if 0 != sdl.Init(sdl.INIT_EVERYTHING) {
panic(sdl.GetError())
}
window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED,
sdl.WINDOWPOS_UNDEFINED,
winWidth, winHeight, sdl.WINDOW_OPENGL)
if err != nil {
panic(err)
}
if window == nil {
panic(sdl.GetError())
}
context = sdl.GL_CreateContext(window)
if context == nil {
panic(sdl.GetError())
}
if gl.Init() != 0 {
panic("gl error")
}
gl.ClearColor(1.0, 1.0, 1.0, .5)
gl.Viewport(0, 0, winWidth, winHeight)
program := MakeProgram(vertexShaderSource, fragmentShaderSource)
defer program.Delete()
matrixID := program.GetUniformLocation("MVP")
Projection := mathgl.Perspective(45.0, 4.0/3.0, 0.1, 100.0)
View := mathgl.LookAt(4.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
Model := mathgl.Ident4f()
MVP := Projection.Mul4(View).Mul4(Model) 
gl.Enable(gl.DEPTH_TEST)
gl.DepthFunc(gl.LESS)
gl.Enable(gl.BLEND)
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
vertexArray := gl.GenVertexArray()
defer vertexArray.Delete()
vertexArray.Bind()
buffer := gl.GenBuffer()
defer buffer.Delete()
buffer.Bind(gl.ARRAY_BUFFER)
gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, &triangle_vertices, gl.STATIC_DRAW)
running = true
for running {
for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch t := event.(type) {
case *sdl.QuitEvent:
running = false
case *sdl.MouseMotionEvent:
fmt.Printf(string(t.Timestamp))
}
}
gl.Clear(gl.COLOR_BUFFER_BIT) // | gl.DEPTH_BUFFER_BIT)
program.Use()
matrixID.UniformMatrix4fv(false, MVP)
attribLoc := gl.AttribLocation(0)
attribLoc.EnableArray()
buffer.Bind(gl.ARRAY_BUFFER)
attribLoc.AttribPointer(3, gl.FLOAT, false, 0, nil)
gl.DrawArrays(gl.TRIANGLES, 0, 3)
attribLoc.DisableArray()
time.Sleep(50 * time.Millisecond)
sdl.GL_SwapWindow(window)
}
sdl.GL_DeleteContext(context)
window.Destroy()
sdl.Quit()
}
const (
winTitle           = "OpenGL Shader"
winWidth           = 640
winHeight          = 480
vertexShaderSource = `
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;
void main(){
gl_Position = MVP * vec4 (vertexPosition_modelspace,1.0);
}
`
fragmentShaderSource = `
#version 330 core
// Ouput data
out vec3 color;
void main()
{
// Output color = red 
color = vec3(1,0,0);
}
`
)
var triangle_vertices = []float32{
-.5, -.5, -.5,
.5, -.5, -.5,
0.0, 0.5, -.5,
}

So I'm still having trouble drawing a simple shape on the screen. I made a few changes such as simplifying my shape (a triangle). I created coordinates so they would be more towards the -z axis so I would be able to see them but that has not worked. I then set the MVP matrix (moving the camera back some) just to make sure. My shaders are simple as I am only passing in a vec3 vertex position and mat4 MVP matrix so believe shaders are working correctly? Sorry for all the confusion, i think i maybe missing something here.

Update:
I also ran the version commands for opengl:

fmt.Println(gl.GetString(gl.VERSION))
fmt.Println(gl.GetString(gl.VENDOR))
fmt.Println(gl.GetString(gl.RENDERER))

for which the output was:

4.5.0 NVIDIA 347.09
NVIDIA Corporation
GeForce GTX 650 Ti/PCIe/SSE2

Not sure if this has any impact?

Update:
I have looked at some more examples and decided to try and add some sdl attributes but still no luck:

sdl.GL_SetAttribute(sdl.GL_DOUBLEBUFFER, 1)
sdl.GL_SetAttribute(sdl.GL_RED_SIZE, 8)
sdl.GL_SetAttribute(sdl.GL_GREEN_SIZE, 8)
sdl.GL_SetAttribute(sdl.GL_BLUE_SIZE, 8)
sdl.GL_SetAttribute(sdl.GL_ALPHA_SIZE, 8)

Update:

I modified this post to just include more recent code to not scare people away from TLDR.

答案1

得分: 1

我终于弄清楚了这段代码中我的问题所在。

首先,我必须做的第一件事是为进入顶点着色器的所有输入变量执行以下操作:

positionAttrib := program.GetAttribLocation("vertexPosition_modelspace")

这是在绑定每个数组的VBO之后完成的。

接下来,

如果你注意到我上面的代码:

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, &triangle_vertices, gl.STATIC_DRAW)

我只是用了triangle_vertices数组来替换它,而不是地址:

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, triangle_vertices, gl.STATIC_DRAW)

这样做似乎修复了问题。

英文:

I finally figured out what my problem was in this code.

The first thing I had to do was

positionAttrib := program.GetAttribLocation("vertexPosition_modelspace")

for all the input variables going into the vertex shader. This was done after binding the VBO for each array.

Next,

If you notice my code above:

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, &triangle_vertices, gl.STATIC_DRAW)

I simply replaced it with triangle_vertices array, and not the address:

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, triangle_vertices, gl.STATIC_DRAW)

Doing this seemed to fix it.

答案2

得分: 0

我会将这段内容翻译为中文:

我想把这个作为评论发表,但是我还没有足够的声望。

提供的解决方案几乎解决了我类似的问题,但还不够完全。

提供的解决方案是:

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, triangle_vertices, gl.STATIC_DRAW)

实际解决我的问题的代码是:

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, gl.Ptr(triangle_vertices), gl.STATIC_DRAW)

我还用更详细的方式回答了一个类似的问题,可以在这里找到:
https://stackoverflow.com/questions/11284055/opengl-vertex-buffer-doesnt-draw-anything-in-golang/33408359#33408359

英文:

I would post this as a comment, but I do not yet have enough reputation.

The solution already provided nearly solved my similar issue, however not quite.

Where the provided solution was

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, triangle_vertices, gl.STATIC_DRAW)

The actual code which solved my issue is

gl.BufferData(gl.ARRAY_BUFFER, len(triangle_vertices)*4, gl.Ptr(triangle_vertices), gl.STATIC_DRAW)

I have also answered a similar question with this, but in more detail, which can be found here:
https://stackoverflow.com/questions/11284055/opengl-vertex-buffer-doesnt-draw-anything-in-golang/33408359#33408359

huangapple
  • 本文由 发表于 2015年1月13日 08:22:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/27913078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定