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
|
#include <stdlib.h>
#include <stdio.h>
#include <complex.h>
#include <unistd.h>
#include <GL/glxew.h>
#include <GLFW/glfw3.h>
extern char _binary_vertex_glsl_start[];
extern char _binary_vertex_glsl_end[];
extern char _binary_fragment_glsl_start[];
extern char _binary_fragment_glsl_end[];
void error_callback (int error, const char * description) {
fprintf(stderr, "error_callback: %s, error == %d\n", description, error);
}
void key_callback (GLFWwindow * okno, int tipka, int koda, int dejanje, int modifikatorji) {
fprintf(stderr, "tipka %d, koda %d, dejanje %d, modifikatorji %d, okno %p\n",
tipka, koda, dejanje, modifikatorji, (void *) okno);
}
int main (void) {
GLint vertex_len = _binary_vertex_glsl_end - _binary_vertex_glsl_start;
GLint fragment_len = _binary_fragment_glsl_end - _binary_fragment_glsl_start;
if (!glfwInit()) {
fprintf(stderr, "glfwInit failed\n");
return 1;
}
glfwSetErrorCallback(error_callback);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // forward compat is ogl 3.0+
GLFWwindow * okno = glfwCreateWindow(800, 600, "okno", NULL, NULL);
if (!okno) {
fprintf(stderr, "glfwCreateWindow failed\n");
glfwTerminate();
return 2;
}
glfwMakeContextCurrent(okno);
GLenum err = glewInit();
if (err != GLEW_OK) {
fprintf(stderr, "glewInit failed: %s\n", glewGetErrorString(err));
return 3;
}
glfwSwapInterval(1); // vsync
glfwSetKeyCallback(okno, key_callback);
GLuint program = glCreateProgram();
float points[] = {
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f
};
// <black box>
GLuint points_vbo, vao;
glGenBuffers(1, &points_vbo);
glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof points, points, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// </black box>
const char * vertex = _binary_vertex_glsl_start;
const char * fragment = _binary_fragment_glsl_start;
#define DO_SHADER(whi, WHI) \
fprintf(stderr, "shader code:\n%.*s\n", whi##_len, whi); \
fprintf(stderr, "glCreateShader ...\n"); \
GLuint whi##_shader = glCreateShader(GL_##WHI##_SHADER); \
fprintf(stderr, "glShaderSource ...\n"); \
glShaderSource(whi##_shader, 1, &whi, &whi##_len); \
fprintf(stderr, "glCompileShader ...\n"); \
glCompileShader(whi##_shader); \
GLint whi##_success = 0; \
fprintf(stderr, "glGetShaderiv ...\n"); \
glGetShaderiv(whi##_shader, GL_COMPILE_STATUS, &whi##_success); \
if (whi##_success == GL_FALSE) { \
GLint logSize = 0; \
glGetShaderiv(whi##_shader, GL_INFO_LOG_LENGTH, &logSize); \
char infoLog[logSize]; \
glGetShaderInfoLog(whi##_shader, logSize, &logSize, infoLog); \
fprintf(stderr, "prevod shaderja ni uspel. dnevnik:\n%s\n", infoLog); \
glDeleteShader(whi##_shader); \
return 4; \
} \
glAttachShader(program, whi##_shader);
DO_SHADER(vertex, VERTEX);
DO_SHADER(fragment, FRAGMENT);
// <black box>
glBindAttribLocation(program, 0, "vertex_position");
// </black box>
glLinkProgram(program);
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
if (isLinked == GL_FALSE) {
GLint logSize = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
char infoLog[logSize];
glGetProgramInfoLog(program, logSize, &logSize, infoLog);
fprintf(stderr, "linkanje programa ni uspelo. dnevnik:\n%s\n", infoLog);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
glDeleteProgram(program);
return 5;
}
// glDetachShader(program, vertex_shader);
// glDetachShader(program, fragment_shader);
// glDeleteShader(fragment_shader); // testiraj, mogoče se to sme
// glDeleteShader(vertex_shader);
GLuint timeI = glGetUniformLocation(program, "time");
GLuint optI = glGetUniformLocation(program, "OPTIONS");
uint32_t opts = 123456;
glClearColor(0.1, 0.2, 0.3, 1);
while (!glfwWindowShouldClose(okno)) {
int w, h;
glfwGetFramebufferSize(okno, &w, &h);
glViewport(0, 0, w, h);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program); // testiraj, mogoče se to sme dat iz loopa gor
glUniform1f(timeI, glfwGetTime());
glUniform1i(optI, opts++);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6 /* dva triangla po 3 */);
glfwSwapBuffers(okno);
glfwWaitEvents(); // glfwPollEvents pa returna takoj
}
glfwDestroyWindow(okno);
glfwTerminate();
return 0;
}
|