erebus

annotate src/main.cc @ 10:506e114b7ca2

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 24 May 2014 17:43:46 +0300
parents d38e13d6063c
children 20d6c05529f1
rev   line source
nuclear@2 1 #include <stdio.h>
nuclear@2 2 #include <stdlib.h>
nuclear@2 3 #include <assert.h>
nuclear@2 4 #include "opengl.h"
nuclear@4 5 #include "erebus.h"
nuclear@2 6
nuclear@2 7 static bool init();
nuclear@2 8 static void cleanup();
nuclear@2 9 static void resize_rtarget(int xsz, int ysz);
nuclear@2 10 static void update_rect(int x, int y, int xsz, int ysz, float *pixels);
nuclear@4 11 static void idle();
nuclear@2 12 static void display();
nuclear@2 13 static void reshape(int x, int y);
nuclear@2 14 static void keyb(unsigned char key, int x, int y);
nuclear@9 15 static void keyb_up(unsigned char key, int x, int y);
nuclear@2 16 static void mouse(int bn, int st, int x, int y);
nuclear@9 17 static void motion(int x, int y);
nuclear@9 18 static void sball_button(int bn, int st);
nuclear@9 19 static void sball_motion(int x, int y, int z);
nuclear@2 20 static int next_pow2(int x);
nuclear@2 21
nuclear@2 22 static int width, height, rtex_width, rtex_height;
nuclear@2 23 static unsigned int rtex;
nuclear@2 24
nuclear@4 25 static erebus *erb;
nuclear@4 26 static bool render_pending;
nuclear@4 27
nuclear@4 28
nuclear@2 29 int main(int argc, char **argv)
nuclear@2 30 {
nuclear@2 31 glutInitWindowSize(1024, 600);
nuclear@2 32 glutInit(&argc, argv);
nuclear@2 33 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
nuclear@2 34 glutCreateWindow("erebus OpenGL frontend");
nuclear@2 35
nuclear@2 36 glutDisplayFunc(display);
nuclear@2 37 glutReshapeFunc(reshape);
nuclear@2 38 glutKeyboardFunc(keyb);
nuclear@9 39 glutKeyboardUpFunc(keyb_up);
nuclear@2 40 glutMouseFunc(mouse);
nuclear@9 41 glutMotionFunc(motion);
nuclear@9 42 glutSpaceballButtonFunc(sball_button);
nuclear@9 43 glutSpaceballMotionFunc(sball_motion);
nuclear@2 44
nuclear@2 45 if(!init()) {
nuclear@2 46 return 1;
nuclear@2 47 }
nuclear@2 48 atexit(cleanup);
nuclear@2 49
nuclear@2 50 glutMainLoop();
nuclear@2 51 }
nuclear@2 52
nuclear@2 53 static bool init()
nuclear@2 54 {
nuclear@8 55 width = glutGet(GLUT_WINDOW_WIDTH) / 2;
nuclear@8 56 height = glutGet(GLUT_WINDOW_HEIGHT) / 2;
nuclear@5 57
nuclear@4 58 if(!(erb = erb_init())) {
nuclear@4 59 return false;
nuclear@4 60 }
nuclear@4 61 erb_setopti(erb, ERB_OPT_WIDTH, width);
nuclear@4 62 erb_setopti(erb, ERB_OPT_HEIGHT, height);
nuclear@4 63
nuclear@4 64 if(erb_load_scene(erb, "scene") == -1) {
nuclear@4 65 return false;
nuclear@4 66 }
nuclear@4 67
nuclear@4 68 printf("begin rendering\n");
nuclear@4 69 render_pending = true;
nuclear@4 70 glutIdleFunc(idle);
nuclear@4 71 erb_begin_frame(erb, 0);
nuclear@4 72
nuclear@8 73 glEnable(GL_TEXTURE_2D);
nuclear@2 74 return true;
nuclear@2 75 }
nuclear@2 76
nuclear@2 77 static void cleanup()
nuclear@2 78 {
nuclear@4 79 erb_destroy(erb);
nuclear@2 80 }
nuclear@2 81
nuclear@2 82 static void resize_rtarget(int xsz, int ysz)
nuclear@2 83 {
nuclear@2 84 static unsigned char *defpix;
nuclear@2 85
nuclear@8 86 width = xsz / 2;
nuclear@8 87 height = ysz / 2;
nuclear@2 88
nuclear@8 89 if(width <= rtex_width && height <= rtex_height) {
nuclear@2 90 return;
nuclear@2 91 }
nuclear@8 92 rtex_width = next_pow2(width);
nuclear@8 93 rtex_height = next_pow2(height);
nuclear@2 94
nuclear@2 95 printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height);
nuclear@2 96
nuclear@2 97 if(!rtex) {
nuclear@2 98 glGenTextures(1, &rtex);
nuclear@2 99 }
nuclear@2 100
nuclear@2 101 delete [] defpix;
nuclear@2 102 defpix = new unsigned char[rtex_width * rtex_height * 4];
nuclear@2 103 unsigned char *ptr = defpix;
nuclear@2 104 for(int i=0; i<rtex_height; i++) {
nuclear@2 105 for(int j=0; j<rtex_width; j++) {
nuclear@2 106 bool chess = ((i >> 4) & 1) == ((j >> 4) & 1);
nuclear@2 107
nuclear@2 108 int val = chess ? 64 : 48;
nuclear@2 109
nuclear@2 110 *ptr++ = val;
nuclear@2 111 *ptr++ = val;
nuclear@2 112 *ptr++ = val;
nuclear@2 113 *ptr++ = 255;
nuclear@2 114 }
nuclear@2 115 }
nuclear@2 116
nuclear@2 117 glBindTexture(GL_TEXTURE_2D, rtex);
nuclear@2 118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
nuclear@2 119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
nuclear@2 120 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix);
nuclear@2 121 }
nuclear@2 122
nuclear@2 123 static void update_rect(int x, int y, int xsz, int ysz, float *pixels)
nuclear@2 124 {
nuclear@2 125 glBindTexture(GL_TEXTURE_2D, rtex);
nuclear@2 126 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels);
nuclear@2 127 }
nuclear@2 128
nuclear@4 129 static void idle()
nuclear@4 130 {
nuclear@4 131 glutPostRedisplay();
nuclear@4 132 }
nuclear@4 133
nuclear@2 134 static void display()
nuclear@2 135 {
nuclear@4 136 if(render_pending) {
nuclear@8 137 if(erb_render(erb, 64) == 0) {
nuclear@4 138 render_pending = false;
nuclear@4 139 glutIdleFunc(0);
nuclear@4 140 }
nuclear@4 141 update_rect(0, 0, width, height, erb_get_framebuffer(erb));
nuclear@4 142 }
nuclear@4 143
nuclear@2 144 float maxu = (float)width / (float)rtex_width;
nuclear@2 145 float maxv = (float)height / (float)rtex_height;
nuclear@2 146
nuclear@2 147 glBegin(GL_QUADS);
nuclear@2 148 glTexCoord2f(0, maxv); glVertex2f(-1, -1);
nuclear@2 149 glTexCoord2f(maxu, maxv); glVertex2f(1, -1);
nuclear@2 150 glTexCoord2f(maxu, 0); glVertex2f(1, 1);
nuclear@2 151 glTexCoord2f(0, 0); glVertex2f(-1, 1);
nuclear@2 152 glEnd();
nuclear@2 153
nuclear@2 154 glutSwapBuffers();
nuclear@2 155 assert(glGetError() == GL_NO_ERROR);
nuclear@2 156 }
nuclear@2 157
nuclear@2 158 static void reshape(int x, int y)
nuclear@2 159 {
nuclear@2 160 glViewport(0, 0, x, y);
nuclear@2 161 resize_rtarget(x, y);
nuclear@4 162
nuclear@4 163 erb_setopti(erb, ERB_OPT_WIDTH, width);
nuclear@4 164 erb_setopti(erb, ERB_OPT_HEIGHT, height);
nuclear@2 165 }
nuclear@2 166
nuclear@2 167 static void keyb(unsigned char key, int x, int y)
nuclear@2 168 {
nuclear@2 169 switch(key) {
nuclear@2 170 case 27:
nuclear@2 171 exit(0);
nuclear@4 172
nuclear@4 173 case ' ':
nuclear@4 174 printf("begin rendering\n");
nuclear@4 175 render_pending = true;
nuclear@4 176 glutIdleFunc(idle);
nuclear@4 177 erb_begin_frame(erb, 0);
nuclear@4 178 break;
nuclear@2 179 }
nuclear@9 180
nuclear@10 181 if(erb_input_keyboard(erb, key, true)) {
nuclear@9 182 glutPostRedisplay();
nuclear@9 183 }
nuclear@9 184 }
nuclear@9 185
nuclear@9 186 static void keyb_up(unsigned char key, int x, int y)
nuclear@9 187 {
nuclear@10 188 if(erb_input_keyboard(erb, key, false)) {
nuclear@9 189 glutPostRedisplay();
nuclear@9 190 }
nuclear@2 191 }
nuclear@2 192
nuclear@2 193 static void mouse(int bn, int st, int x, int y)
nuclear@2 194 {
nuclear@10 195 if(erb_input_mouse_button(erb, bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y)) {
nuclear@9 196 glutPostRedisplay();
nuclear@9 197 }
nuclear@9 198 }
nuclear@9 199
nuclear@9 200 static void motion(int x, int y)
nuclear@9 201 {
nuclear@10 202 if(erb_input_mouse_move(erb, x, y)) {
nuclear@9 203 glutPostRedisplay();
nuclear@9 204 }
nuclear@9 205 }
nuclear@9 206
nuclear@9 207 static void sball_button(int bn, int state)
nuclear@9 208 {
nuclear@10 209 if(erb_input_6dof_button(erb, bn, state == GLUT_DOWN)) {
nuclear@9 210 glutPostRedisplay();
nuclear@9 211 }
nuclear@9 212 }
nuclear@9 213
nuclear@9 214 static void sball_motion(int x, int y, int z)
nuclear@9 215 {
nuclear@10 216 if(erb_input_6dof_motion(erb, x / 65536.0, y / 65536.0, z / 65536.0)) {
nuclear@9 217 glutPostRedisplay();
nuclear@9 218 }
nuclear@2 219 }
nuclear@2 220
nuclear@2 221 static int next_pow2(int x)
nuclear@2 222 {
nuclear@2 223 int res = 2;
nuclear@2 224 while(res < x) {
nuclear@2 225 res <<= 1;
nuclear@2 226 }
nuclear@2 227 return res;
nuclear@2 228 }