-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoffscreen.lua
142 lines (117 loc) · 3.35 KB
/
offscreen.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
local function add_package_path(path)
package.path = package.path
.. string.format(";%s/?.lua;%s/?/init.lua", path, path)
end
add_package_path "libs"
local ffi = require "ffi"
local glfw = require "glfw"
local gl = require "gl"
local stb_image = require "stb_image"
ffi.cdef [[
typedef struct {
float x, y;
float r, g, b;
} Vertex;
]]
local vertices = ffi.new(
"Vertex[3]",
{ -0.6, -0.4, 1., 0., 0. },
{ 0.6, -0.4, 0., 1., 0. },
{ 0., 0.6, 0., 0., 1. }
)
local vertex_shader_text = [[
#version 110
uniform mat4 MVP;
attribute vec3 vCol;
attribute vec2 vPos;
varying vec3 color;
void main()
{
gl_Position = MVP * vec4(vPos, 0.0, 1.0);
color = vCol;
}
]]
local fragment_shader_text = [[
#version 110
varying vec3 color;
void main()
{
gl_FragColor = vec4(color, 1.0);
};
]]
-- static void error_callback(int error, const char *description) {
-- fprintf(stderr, "Error: %s\n", description);
-- }
local function main()
-- glfwSetErrorCallback(error_callback);
-- glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
glfw.init()
glfw.hint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 2)
glfw.hint(glfw.GLFW_CONTEXT_VERSION_MINOR, 0)
glfw.hint(glfw.GLFW_VISIBLE, glfw.GLFW_FALSE)
local window = glfw.Window(640, 480, "Simple example", nil, nil)
if not window then
glfw.terminate()
os.exit(1)
end
window:makeContextCurrent()
gl.load(glfw)
local vertex_buffer = ffi.new "GLuint[1]"
gl.glGenBuffers(1, vertex_buffer)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vertex_buffer[0])
gl.glBufferData(
gl.GL_ARRAY_BUFFER,
ffi.sizeof(vertices),
vertices,
gl.GL_STATIC_DRAW
)
local array = ffi.new "const char*[1]"
array[0] = vertex_shader_text
local vertex_shader = gl.glCreateShader(gl.GL_VERTEX_SHADER)
gl.glShaderSource(vertex_shader, 1, array, nil)
gl.glCompileShader(vertex_shader)
local fragment_shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
array[0] = fragment_shader_text
gl.glShaderSource(fragment_shader, 1, array, nil)
gl.glCompileShader(fragment_shader)
local program = gl.glCreateProgram()
gl.glAttachShader(program, vertex_shader)
gl.glAttachShader(program, fragment_shader)
gl.glLinkProgram(program)
local mvp_location = gl.glGetUniformLocation(program, "MVP")
local vpos_location = gl.glGetAttribLocation(program, "vPos")
local vcol_location = gl.glGetAttribLocation(program, "vCol")
gl.glEnableVertexAttribArray(vpos_location)
gl.glVertexAttribPointer(
vpos_location,
2,
gl.GL_FLOAT,
gl.GL_FALSE,
ffi.sizeof(vertices[0]),
nil
)
gl.glEnableVertexAttribArray(vcol_location)
gl.glVertexAttribPointer(
vcol_location,
3,
gl.GL_FLOAT,
gl.GL_FALSE,
ffi.sizeof(vertices[0]),
ffi.cast("void*", (ffi.sizeof "float") * 2)
)
local width, height = window:getFramebufferSize()
local ratio = width / height
gl.glViewport(0, 0, width, height)
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
local mvp =
ffi.new("float[16]", 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
gl.glUseProgram(program)
gl.glUniformMatrix4fv(mvp_location, 1, gl.GL_FALSE, mvp)
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
gl.glFinish()
local buffer = ffi.new("char[?]", 4 * width * height)
gl.glReadPixels(0, 0, width, height, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, buffer)
stb_image.stbi_write_png("offscreen.png", width, height, 4, buffer, width * 4)
glfw.terminate()
end
main()