123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- #include "GameEngine.h"
- #include "Control.h"
- static GLuint program;
- static GLuint vShader;
- static GLuint fShader;
- static WindowResize windowResize;
- static MouseMove mouseMove;
- static int activeFocus = 0;
- static double oldMouseX = 0;
- static double oldMouseY = 0;
- static void flushOutput() {
- fflush(stdout);
- }
- static void onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mods) {
- if(action == GLFW_RELEASE) {
- if(key == GLFW_KEY_ESCAPE) {
- activeFocus = 0;
- glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- }
- keyRelease(key);
- }
- if(action == GLFW_PRESS) {
- keyPress(key);
- }
- }
- static void onMouseClick(GLFWwindow* w, int button, int action, int mods) {
- if(action == GLFW_PRESS) {
- if(!activeFocus) {
- glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- oldMouseX = 0;
- oldMouseY = 0;
- activeFocus = 1;
- } else {
- mousePress(button);
- }
- } else if(action == GLFW_RELEASE) {
- mouseRelease(button);
- }
- }
- static void onMouseMove(GLFWwindow* w, double x, double y) {
- if(activeFocus) {
- if(oldMouseX == 0 && oldMouseY == 0) {
- oldMouseX = x;
- oldMouseY = y;
- } else {
- mouseMove(x - oldMouseX, y - oldMouseY);
- oldMouseX = x;
- oldMouseY = y;
- }
- }
- }
- static void onWindowResize(GLFWwindow* w, int width, int height) {
- glViewport(0, 0, width, height);
- windowResize(width, height);
- }
- static GLchar* readFile(char* name) {
- FILE* file = fopen(name, "r");
- if(file != NULL) {
- int size = 128;
- int index = 0;
- GLchar* content = malloc(sizeof(GLchar) * size);
- while(1) {
- int c = fgetc(file);
- if(c == EOF) {
- break;
- }
- if(index >= size) {
- size *= 2;
- content = realloc(content, size);
- }
- content[index] = c;
- index++;
- }
- if(index >= size) {
- size++;
- content = realloc(content, size);
- }
- content[index] = '\0';
- index++;
- fclose(file);
- return content;
- }
- return NULL;
- }
- int checkShaderErrors(char* name, GLuint shader) {
- int returnValue = 0;
- printf("compiling %s shader ...\n", name);
- GLenum error = glGetError();
- if(error) {
- fprintf(stderr, "error: %u\n", glGetError());
- returnValue = 1;
- } else {
- printf("no error occured ...\n");
- }
- GLint compiled[1];
- glGetShaderiv(shader, GL_COMPILE_STATUS, compiled);
- if(compiled[0]) {
- printf("%s shader successfully compiled\n", name);
- } else {
- fprintf(stderr, "compiling of %s shader failed:\n", name);
- GLchar buffer[512];
- GLsizei bufferSize = 512;
- GLsizei charsUsed = 0;
- glGetShaderInfoLog(shader, bufferSize, &charsUsed, buffer);
- buffer[bufferSize - 1] = '\0';
- fprintf(stderr, "%s\n", buffer);
- returnValue = 1;
- }
- return returnValue;
- }
- static GLuint compileProgram(const GLchar* vertex, const GLchar* fragment) {
- vShader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vShader, 1, &vertex, NULL);
- glCompileShader(vShader);
- if(checkShaderErrors("vertex", vShader)) {
- return 0;
- }
- fShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fShader, 1, &fragment, NULL);
- glCompileShader(fShader);
- if(checkShaderErrors("fragment", fShader)) {
- return 0;
- }
- GLuint program = glCreateProgram();
- glAttachShader(program, vShader);
- glAttachShader(program, fShader);
- glLinkProgram(program);
- printf("linking shaders to program ...\n");
- GLenum error = glGetError();
- if(error) {
- fprintf(stderr, "error: %u\n", glGetError());
- return 0;
- } else {
- printf("no error occured ...\n");
- }
- GLint compiled[1];
- glGetProgramiv(program, GL_LINK_STATUS, compiled);
- if(compiled[0]) {
- printf("shaders successfully linked\n");
- } else {
- fprintf(stderr, "linking of shaders failed:\n");
- GLchar buffer[512];
- GLsizei bufferSize = 512;
- GLsizei charsUsed = 0;
- glGetProgramInfoLog(program, bufferSize, &charsUsed, buffer);
- buffer[bufferSize - 1] = '\0';
- fprintf(stderr, "%s\n", buffer);
- return 0;
- }
- glUseProgram(program);
- return program;
- }
- static GLuint createProgram() {
- GLchar* vertex = readFile("shader/vertex.vs");
- if(vertex == NULL) {
- fprintf(stderr, "cannot read vertex.vs\n");
- return 0;
- }
- GLchar* fragment = readFile("shader/fragment.fs");
- if(fragment == NULL) {
- fprintf(stderr, "cannot read fragment.fs\n");
- free(vertex);
- return 0;
- }
- GLuint program = compileProgram(vertex, fragment);
- flushOutput();
- free(vertex);
- free(fragment);
- return program;
- }
- static void onTerm(GLFWwindow* window) {
- glfwDestroyWindow(window);
- glfwTerminate();
- }
- int startGame(char* name, InitFunction init, TickFunction tick, RenderTickFunction renderTick,
- WindowResize inWindowResize, MouseMove move) {
- if(!glfwInit()) {
- fprintf(stderr, "could not initialize GLFW");
- return 1;
- }
- windowResize = inWindowResize;
- mouseMove = move;
- glfwDefaultWindowHints();
- glfwWindowHint(GLFW_VISIBLE, 0);
- glfwWindowHint(GLFW_RESIZABLE, 1);
- GLFWwindow* window = glfwCreateWindow(640, 480, name, NULL, NULL);
- if(!window) {
- fprintf(stderr, "could not create window");
- glfwTerminate();
- return 1;
- }
- glfwSetKeyCallback(window, onKeyEvent);
- glfwSetFramebufferSizeCallback(window, onWindowResize);
- glfwSetMouseButtonCallback(window, onMouseClick);
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- activeFocus = 1;
- glfwSetCursorPosCallback(window, onMouseMove);
- glfwMakeContextCurrent(window);
- glfwSwapInterval(1);
- glfwShowWindow(window);
- GLenum err = glewInit();
- if(GLEW_OK != err) {
- fprintf(stderr, "Could not initialize GLEW: %s\n", glewGetErrorString(err));
- return 1;
- }
- printf("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
- program = createProgram();
- if(program == 0) {
- onTerm(window);
- return 1;
- }
- // glEnable(GL_CULL_FACE);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- init(program);
- // printf("%lu\n", glfwGetTimerFrequency());
- // printf("%lu\n", glfwGetTimerValue());
- // printf("%lu\n", glfwGetTimerValue());
- long newTime = glfwGetTimerValue();
- long oldTime = newTime;
- long lag = 0;
- while(!glfwWindowShouldClose(window)) {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- oldTime = newTime;
- newTime = glfwGetTimerValue();
- lag += newTime - oldTime;
- int ticksPerFrame = 0;
- while(lag >= NANOS_PER_TICK) {
- lag -= NANOS_PER_TICK;
- controlTick();
- tick(program);
- ticksPerFrame++;
- if(ticksPerFrame >= MAX_TICKS_PER_FRAME) {
- long skip = lag / NANOS_PER_TICK;
- lag -= skip * NANOS_PER_TICK;
- if(skip > 0) {
- printf("skipped %ld game ticks %ld\n", skip, lag);
- }
- break;
- }
- }
- renderTick(program, (float)lag / NANOS_PER_TICK);
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
- glDeleteShader(vShader);
- glDeleteShader(fShader);
- glDeleteProgram(program);
- onTerm(window);
- return 0;
- }
- GLuint getProgram() {
- return program;
- }
|