Skip to content

Commit d1ee0e4

Browse files
author
rui.zheng
committed
textures and exercises
1 parent 020b5dd commit d1ee0e4

File tree

12 files changed

+544
-6
lines changed

12 files changed

+544
-6
lines changed

Diff for: 1.getting_started/4.1.textures/textures.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"log"
5+
"runtime"
56

67
"github.com/ginuerzh/learnopengl/utils/shader"
78
"github.com/ginuerzh/learnopengl/utils/texture"
@@ -25,6 +26,7 @@ var (
2526
)
2627

2728
func init() {
29+
runtime.LockOSThread()
2830
log.SetFlags(log.Lshortfile | log.LstdFlags)
2931
}
3032

@@ -106,11 +108,11 @@ func main() {
106108
texture.SetParameter(gl.TEXTURE_MIN_FILTER, gl.LINEAR)
107109
texture.SetParameter(gl.TEXTURE_MAG_FILTER, gl.LINEAR)
108110
// load image, create texture and generate mipmaps
109-
image, err := texture.Load("../../resources/textures/container.jpg")
111+
image, err := texture.Load("../../resources/textures/container.jpg", false, false)
110112
if err != nil {
111113
log.Fatal(err)
112114
}
113-
log.Println(image.Rect, image.Stride)
115+
log.Println(image.Rect, image.Stride, len(image.Pix))
114116

115117
// note that this is allowed,
116118
// the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#version 330 core
2+
3+
out vec4 FragColor;
4+
5+
in vec3 ourColor;
6+
in vec2 TexCoord;
7+
8+
// texture sampler
9+
uniform sampler2D texture1;
10+
uniform sampler2D texture2;
11+
12+
void main()
13+
{
14+
// linearly interpolate between both textures (80% container, 20% awesomeface)
15+
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
16+
// exercise1
17+
// FragColor = mix(texture(texture1, TexCoord), texture(texture2, vec2(1.0-TexCoord.x, TexCoord.y)), 0.2);
18+
// or
19+
// FragColor = mix(texture(texture1, TexCoord), texture(texture2, vec2(-TexCoord.x, TexCoord.y)), 0.2);
20+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#version 330 core
2+
layout (location = 0) in vec3 aPos;
3+
layout (location = 1) in vec3 aColor;
4+
layout (location = 2) in vec2 aTexCoord;
5+
6+
out vec3 ourColor;
7+
out vec2 TexCoord;
8+
9+
void main()
10+
{
11+
gl_Position = vec4(aPos, 1.0);
12+
ourColor = aColor;
13+
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"runtime"
6+
7+
"github.com/ginuerzh/learnopengl/utils/shader"
8+
"github.com/ginuerzh/learnopengl/utils/texture"
9+
10+
"github.com/go-gl/gl/v3.3-core/gl"
11+
"github.com/go-gl/glfw/v3.2/glfw"
12+
)
13+
14+
var (
15+
vertices = []float32{
16+
// top right
17+
0.5, 0.5, 0.0, // positions
18+
1.0, 0.0, 0.0, // colors
19+
1.0, 1.0, // texture coords
20+
// bottom right
21+
0.5, -0.5, 0.0,
22+
0.0, 1.0, 0.0,
23+
1.0, 0.0,
24+
// bottom left
25+
-0.5, -0.5, 0.0,
26+
0.0, 0.0, 1.0,
27+
0.0, 0.0,
28+
// top left
29+
-0.5, 0.5, 0.0,
30+
1.0, 1.0, 0.0,
31+
0.0, 1.0,
32+
}
33+
indices = []uint32{
34+
0, 1, 3, // first triangle
35+
1, 2, 3, // second triangle
36+
}
37+
)
38+
39+
func init() {
40+
runtime.LockOSThread()
41+
log.SetFlags(log.Lshortfile | log.LstdFlags)
42+
}
43+
44+
func main() {
45+
// glfw: initialize
46+
if err := glfw.Init(); err != nil {
47+
log.Fatal(err)
48+
}
49+
// glfw: terminate, clearing all previously allocated GLFW resources.
50+
defer glfw.Terminate()
51+
52+
// glfw: configure
53+
glfw.WindowHint(glfw.ContextVersionMajor, 3)
54+
glfw.WindowHint(glfw.ContextVersionMinor, 3)
55+
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
56+
// there is no need to explicitly create and bind a VAO when using the compatibility profile
57+
// see https://www.opengl.org/discussion_boards/showthread.php/199916-vertex-array-and-buffer-objects?p=1288280&viewfull=1#post1288280
58+
// glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCompatProfile)
59+
60+
// glfw window creation
61+
window, err := glfw.CreateWindow(800, 600, "LearnOpenGL", nil, nil)
62+
if err != nil {
63+
log.Fatal(err)
64+
}
65+
defer window.Destroy()
66+
67+
window.MakeContextCurrent()
68+
window.SetFramebufferSizeCallback(frameBufferSizeCallback)
69+
70+
// gl: initializes the OpenGL bindings by loading the function pointers
71+
// (for each OpenGL function) from the active OpenGL context.
72+
if err := gl.Init(); err != nil {
73+
log.Fatal(err)
74+
}
75+
76+
shader, err := shader.NewShader("4.2.texture.vs", "4.2.texture.fs")
77+
if err != nil {
78+
log.Fatal(err)
79+
}
80+
81+
var vao, vbo, ebo uint32
82+
gl.GenVertexArrays(1, &vao)
83+
defer gl.DeleteVertexArrays(1, &vao)
84+
85+
gl.GenBuffers(1, &vbo)
86+
defer gl.DeleteBuffers(1, &vbo)
87+
88+
gl.GenBuffers(1, &ebo)
89+
defer gl.DeleteBuffers(1, &ebo)
90+
91+
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
92+
gl.BindVertexArray(vao)
93+
94+
gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
95+
gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW)
96+
97+
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
98+
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*4, gl.Ptr(indices), gl.STATIC_DRAW)
99+
100+
// position attribute
101+
gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 8*4, gl.PtrOffset(0))
102+
gl.EnableVertexAttribArray(0)
103+
104+
// color attribute
105+
gl.VertexAttribPointer(1, 3, gl.FLOAT, false, 8*4, gl.PtrOffset(3*4)) // note that the offset is 12 in BYTEs.
106+
gl.EnableVertexAttribArray(1)
107+
108+
// texture coord attribute
109+
gl.VertexAttribPointer(2, 2, gl.FLOAT, false, 8*4, gl.PtrOffset(6*4))
110+
gl.EnableVertexAttribArray(2)
111+
112+
// texture 1
113+
texture1 := texture.NewTexture2D()
114+
texture1.Use()
115+
// set the texture wrapping parameters
116+
texture1.SetParameter(gl.TEXTURE_WRAP_S, gl.REPEAT)
117+
texture1.SetParameter(gl.TEXTURE_WRAP_T, gl.REPEAT)
118+
// set texture filtering parameters
119+
texture1.SetParameter(gl.TEXTURE_MIN_FILTER, gl.LINEAR)
120+
texture1.SetParameter(gl.TEXTURE_MAG_FILTER, gl.LINEAR)
121+
// load image, create texture and generate mipmaps
122+
image, err := texture1.Load("../../resources/textures/container.jpg", false, false)
123+
if err != nil {
124+
log.Fatal(err)
125+
}
126+
log.Println("container.jpg", image.Rect, image.Stride, len(image.Pix))
127+
128+
texture2 := texture.NewTexture2D()
129+
texture2.Use()
130+
texture2.SetParameter(gl.TEXTURE_WRAP_S, gl.REPEAT)
131+
texture2.SetParameter(gl.TEXTURE_WRAP_T, gl.REPEAT)
132+
texture2.SetParameter(gl.TEXTURE_MIN_FILTER, gl.LINEAR)
133+
texture2.SetParameter(gl.TEXTURE_MAG_FILTER, gl.LINEAR)
134+
image, err = texture2.Load("../../resources/textures/awesomeface.jpg", false, true)
135+
if err != nil {
136+
log.Fatal(err)
137+
}
138+
log.Println("awesomeface.jpg", image.Rect, image.Stride, len(image.Pix))
139+
140+
// note that this is allowed,
141+
// the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object
142+
// so afterwards we can safely unbind
143+
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
144+
145+
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
146+
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
147+
// gl.BindVertexArray(0)
148+
149+
shader.Use()
150+
if err := shader.SetUniformName("texture1", 0); err != nil {
151+
log.Fatal(err)
152+
}
153+
if err := shader.SetUniformName("texture2", 1); err != nil {
154+
log.Fatal(err)
155+
}
156+
157+
// render loop
158+
for !window.ShouldClose() {
159+
// input
160+
processInput(window)
161+
162+
// render
163+
gl.ClearColor(0.2, 0.3, 0.3, 1.0)
164+
gl.Clear(gl.COLOR_BUFFER_BIT)
165+
166+
// bind textures on corresponding texture units
167+
gl.ActiveTexture(gl.TEXTURE0)
168+
texture1.Use()
169+
gl.ActiveTexture(gl.TEXTURE1)
170+
texture2.Use()
171+
172+
// seeing as we only have a single VAO there's no need to bind it every time.
173+
// gl.BindVertexArray(vao)
174+
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, gl.PtrOffset(0))
175+
// no need to unbind it every time
176+
// gl.BindVertexArray(0);
177+
178+
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
179+
window.SwapBuffers()
180+
glfw.PollEvents()
181+
}
182+
}
183+
184+
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
185+
func processInput(w *glfw.Window) {
186+
if w.GetKey(glfw.KeyEscape) == glfw.Press {
187+
w.SetShouldClose(true)
188+
}
189+
}
190+
191+
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
192+
func frameBufferSizeCallback(w *glfw.Window, width int, height int) {
193+
// make sure the viewport matches the new window dimensions; note that width and
194+
// height will be significantly larger than specified on retina displays.
195+
gl.Viewport(0, 0, int32(width), int32(height))
196+
// log.Printf("frameBufferSizeCallback (%d, %d)", width, height)
197+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#version 330 core
2+
3+
out vec4 FragColor;
4+
5+
in vec3 ourColor;
6+
in vec2 TexCoord;
7+
8+
// texture sampler
9+
uniform sampler2D texture1;
10+
uniform sampler2D texture2;
11+
12+
void main()
13+
{
14+
// linearly interpolate between both textures (80% container, 20% awesomeface)
15+
FragColor = mix(texture(texture1, TexCoord), texture(texture2, vec2(1.0-TexCoord.x, TexCoord.y)), 0.2);
16+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#version 330 core
2+
layout (location = 0) in vec3 aPos;
3+
layout (location = 1) in vec3 aColor;
4+
layout (location = 2) in vec2 aTexCoord;
5+
6+
out vec3 ourColor;
7+
out vec2 TexCoord;
8+
9+
void main()
10+
{
11+
gl_Position = vec4(aPos, 1.0);
12+
ourColor = aColor;
13+
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
14+
}

0 commit comments

Comments
 (0)