summaryrefslogblamecommitdiffstats
path: root/fiz/naloga/gl/helmholtz.c
blob: 5f8f44d39a6a22f1d87a8bbd5b893c25ba6ff123 (plain) (tree)
1
2
3
4
5
6
7
8
9

                   


                       



                     




































                                                                                             




















                                                                             

                                                                  
                                                            














                                                                                       


                                                            













                                                                                        







                                                                          

                                                                                   



                                                     

                                                                                      
                                                     


                                                                         
                                      



























                                                                                                         




                                
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <GL/glxew.h>
#include <GLFW/glfw3.h>

#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.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) \
	GLuint whi##_shader = glCreateShader(GL_##WHI##_SHADER); \
	glShaderSource(whi##_shader, 1, &whi, &whi##_len); \
	glCompileShader(whi##_shader); \
	GLint whi##_success = 0; \
	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);
	unsigned frame = 0;
	getchar(); // da vmes odpremo okno v floating načinu s pravilno velikostjo
	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, (float) frame/60);
		glUniform1i(optI, opts++);
		glBindVertexArray(vao);
		glDrawArrays(GL_TRIANGLES, 0, 6 /* dva triangla po 3 */);
		glfwSwapBuffers(okno);
		glfwPollEvents(); // wait / poll
		frame++;
		char fn[25];
		sprintf(fn, "animacija%04d.ppm", frame);
		int fd;
		if ((fd = open(fn, O_CREAT | O_RDWR, 00664)) == -1) {
			perror("open");
			abort();
		}
		if (ftruncate(fd, 128+w*h*3) == -1) {
			perror("ftruncate");
			abort();
		}
		void * p;
		if ((p = mmap(NULL, 128+w*h*3, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
			perror("mmap");
			abort();
		}
		sprintf(p, "P6\n\n%57d\n%57d\n255\n", w, h);
		glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *) p + 128);
		if (munmap(p, 128+w*h*3) == -1) {
			perror("munmap");
			abort();
		}
		if (close(fd) == -1) {
			perror("close");
			abort();
		}
	}
	glfwDestroyWindow(okno);
	glfwTerminate();
	return 0;
}