3 #include <GL/freeglut.h>
16 float color[4] = {0, 1, 0, 1};
20 static void cleanup();
22 static void display();
23 static void keydown(unsigned char key, int x, int y);
24 static unsigned int load_shader(const char *fname, int type);
25 static unsigned int create_program(const char *vfname, const char *pfname);
26 static bool link_program(unsigned int prog);
28 static const char *vs_path = "data/spirv/vertex.spv";
29 static const char *fs_path = "data/spirv/pixel.spv";
31 static unsigned int sprog;
32 static unsigned int vbo;
33 static unsigned int vao;
35 static float vertices[] = {
45 static int num_vertices = 6;
47 static unsigned int ubo;
49 int main(int argc, char **argv)
51 glutInitContextProfile(GLUT_CORE_PROFILE);
52 glutInitContextVersion(4, 5);
54 glutInit(&argc, argv);
56 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
57 glutInitWindowSize(800, 600);
58 glutCreateWindow("gltest");
61 glClear(GL_COLOR_BUFFER_BIT);
63 glutDisplayFunc(display);
64 glutKeyboardFunc(keydown);
77 glClearColor(0.0, 0.0, 1.0, 1.0);
79 glGenBuffers(1, &ubo);
80 glBindBuffer(GL_UNIFORM_BUFFER, ubo);
81 glBufferData(GL_UNIFORM_BUFFER, sizeof test_ubo, &test_ubo, GL_STREAM_DRAW);
83 glGenVertexArrays(1, &vao);
84 glBindVertexArray(vao);
86 glGenBuffers(1, &vbo);
87 glBindBuffer(GL_ARRAY_BUFFER, vbo);
88 glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
89 glBindBuffer(GL_ARRAY_BUFFER, 0);
91 if(!(sprog = create_program(vs_path, fs_path))) {
92 fprintf(stderr, "Failed to create shader program.\n");
98 assert(glGetError() == GL_NO_ERROR);
102 static void display()
104 glEnableVertexAttribArray(VERTEX_LOC);
105 glBindBuffer(GL_ARRAY_BUFFER, vbo);
107 glVertexAttribPointer(VERTEX_LOC, 2, GL_FLOAT, GL_FALSE, 0, 0);
109 glBindBuffer(GL_ARRAY_BUFFER, 0);
111 glBindBuffer(GL_UNIFORM_BUFFER, ubo);
112 glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof test_ubo, &test_ubo);
113 glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);
115 glDrawArrays(GL_TRIANGLES, 0, num_vertices);
117 assert(glGetError() == GL_NO_ERROR);
122 static void keydown(unsigned char key, int /*x*/, int /*y*/)
130 static unsigned int create_program(const char *vfname, const char *pfname)
135 if(!(vs = load_shader(vfname, GL_VERTEX_SHADER)))
137 if(!(ps = load_shader(pfname, GL_FRAGMENT_SHADER))) {
142 prog = glCreateProgram();
143 glAttachShader(prog, vs);
144 glAttachShader(prog, ps);
146 if(!link_program(prog)) {
149 glDeleteProgram(prog);
153 glDetachShader(prog, vs);
154 glDetachShader(prog, ps);
159 static bool link_program(unsigned int prog)
166 glGetProgramiv(prog, GL_LINK_STATUS, &status);
168 printf("successfully linked shader program\n");
170 printf("failed to link shader program\n");
173 glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &loglen);
174 if(loglen > 0 && (buf = (char*)malloc(loglen + 1))) {
175 glGetProgramInfoLog(prog, loglen, 0, buf);
181 return status ? true : false;
184 unsigned int load_shader(const char *fname, int type)
192 if(!(fp = fopen(fname, "rb"))) {
193 fprintf(stderr, "failed to open shader: %s\n", fname);
196 fseek(fp, 0, SEEK_END);
200 if(!(buf = (char*)malloc(fsz + 1))) {
201 fprintf(stderr, "failed to allocate %d bytes\n", fsz + 1);
205 if(fread(buf, 1, fsz, fp) < fsz) {
206 fprintf(stderr, "failed to read shader: %s\n", fname);
214 sdr = glCreateShader(type);
216 glShaderBinary(1, &sdr, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, buf, fsz);
217 glSpecializeShaderARB(sdr, "main", 0, 0, 0);
221 glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
223 printf("successfully compiled shader: %s\n", fname);
225 printf("failed to compile shader: %s\n", fname);
228 glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &loglen);
229 if(loglen > 0 && (buf = (char*)malloc(loglen + 1))) {
230 glGetShaderInfoLog(sdr, loglen, 0, buf);
244 static void cleanup()
246 glDeleteVertexArrays(1, &vao);
247 glDeleteBuffers(1, &vbo);
248 glDeleteBuffers(1, &ubo);