nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include "opengl.h" nuclear@4: #include "erebus.h" nuclear@2: nuclear@2: static bool init(); nuclear@2: static void cleanup(); nuclear@2: static void resize_rtarget(int xsz, int ysz); nuclear@2: static void update_rect(int x, int y, int xsz, int ysz, float *pixels); nuclear@4: static void idle(); nuclear@2: static void display(); nuclear@2: static void reshape(int x, int y); nuclear@2: static void keyb(unsigned char key, int x, int y); nuclear@9: static void keyb_up(unsigned char key, int x, int y); nuclear@2: static void mouse(int bn, int st, int x, int y); nuclear@9: static void motion(int x, int y); nuclear@9: static void sball_button(int bn, int st); nuclear@9: static void sball_motion(int x, int y, int z); nuclear@2: static int next_pow2(int x); nuclear@2: nuclear@2: static int width, height, rtex_width, rtex_height; nuclear@2: static unsigned int rtex; nuclear@2: nuclear@4: static erebus *erb; nuclear@4: static bool render_pending; nuclear@4: nuclear@4: nuclear@2: int main(int argc, char **argv) nuclear@2: { nuclear@2: glutInitWindowSize(1024, 600); nuclear@2: glutInit(&argc, argv); nuclear@2: glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); nuclear@2: glutCreateWindow("erebus OpenGL frontend"); nuclear@2: nuclear@2: glutDisplayFunc(display); nuclear@2: glutReshapeFunc(reshape); nuclear@2: glutKeyboardFunc(keyb); nuclear@9: glutKeyboardUpFunc(keyb_up); nuclear@2: glutMouseFunc(mouse); nuclear@9: glutMotionFunc(motion); nuclear@9: glutSpaceballButtonFunc(sball_button); nuclear@9: glutSpaceballMotionFunc(sball_motion); nuclear@2: nuclear@2: if(!init()) { nuclear@2: return 1; nuclear@2: } nuclear@2: atexit(cleanup); nuclear@2: nuclear@2: glutMainLoop(); nuclear@2: } nuclear@2: nuclear@2: static bool init() nuclear@2: { nuclear@8: width = glutGet(GLUT_WINDOW_WIDTH) / 2; nuclear@8: height = glutGet(GLUT_WINDOW_HEIGHT) / 2; nuclear@5: nuclear@4: if(!(erb = erb_init())) { nuclear@4: return false; nuclear@4: } nuclear@4: erb_setopti(erb, ERB_OPT_WIDTH, width); nuclear@4: erb_setopti(erb, ERB_OPT_HEIGHT, height); nuclear@4: nuclear@4: if(erb_load_scene(erb, "scene") == -1) { nuclear@4: return false; nuclear@4: } nuclear@4: nuclear@4: printf("begin rendering\n"); nuclear@4: render_pending = true; nuclear@4: glutIdleFunc(idle); nuclear@4: erb_begin_frame(erb, 0); nuclear@4: nuclear@8: glEnable(GL_TEXTURE_2D); nuclear@2: return true; nuclear@2: } nuclear@2: nuclear@2: static void cleanup() nuclear@2: { nuclear@4: erb_destroy(erb); nuclear@2: } nuclear@2: nuclear@2: static void resize_rtarget(int xsz, int ysz) nuclear@2: { nuclear@2: static unsigned char *defpix; nuclear@2: nuclear@8: width = xsz / 2; nuclear@8: height = ysz / 2; nuclear@2: nuclear@8: if(width <= rtex_width && height <= rtex_height) { nuclear@2: return; nuclear@2: } nuclear@8: rtex_width = next_pow2(width); nuclear@8: rtex_height = next_pow2(height); nuclear@2: nuclear@2: printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height); nuclear@2: nuclear@2: if(!rtex) { nuclear@2: glGenTextures(1, &rtex); nuclear@2: } nuclear@2: nuclear@2: delete [] defpix; nuclear@2: defpix = new unsigned char[rtex_width * rtex_height * 4]; nuclear@2: unsigned char *ptr = defpix; nuclear@2: for(int i=0; i> 4) & 1) == ((j >> 4) & 1); nuclear@2: nuclear@2: int val = chess ? 64 : 48; nuclear@2: nuclear@2: *ptr++ = val; nuclear@2: *ptr++ = val; nuclear@2: *ptr++ = val; nuclear@2: *ptr++ = 255; nuclear@2: } nuclear@2: } nuclear@2: nuclear@2: glBindTexture(GL_TEXTURE_2D, rtex); nuclear@2: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); nuclear@2: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); nuclear@2: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix); nuclear@2: } nuclear@2: nuclear@2: static void update_rect(int x, int y, int xsz, int ysz, float *pixels) nuclear@2: { nuclear@2: glBindTexture(GL_TEXTURE_2D, rtex); nuclear@2: glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels); nuclear@2: } nuclear@2: nuclear@4: static void idle() nuclear@4: { nuclear@4: glutPostRedisplay(); nuclear@4: } nuclear@4: nuclear@2: static void display() nuclear@2: { nuclear@4: if(render_pending) { nuclear@8: if(erb_render(erb, 64) == 0) { nuclear@4: render_pending = false; nuclear@4: glutIdleFunc(0); nuclear@4: } nuclear@4: update_rect(0, 0, width, height, erb_get_framebuffer(erb)); nuclear@4: } nuclear@4: nuclear@2: float maxu = (float)width / (float)rtex_width; nuclear@2: float maxv = (float)height / (float)rtex_height; nuclear@2: nuclear@2: glBegin(GL_QUADS); nuclear@2: glTexCoord2f(0, maxv); glVertex2f(-1, -1); nuclear@2: glTexCoord2f(maxu, maxv); glVertex2f(1, -1); nuclear@2: glTexCoord2f(maxu, 0); glVertex2f(1, 1); nuclear@2: glTexCoord2f(0, 0); glVertex2f(-1, 1); nuclear@2: glEnd(); nuclear@2: nuclear@2: glutSwapBuffers(); nuclear@2: assert(glGetError() == GL_NO_ERROR); nuclear@2: } nuclear@2: nuclear@2: static void reshape(int x, int y) nuclear@2: { nuclear@2: glViewport(0, 0, x, y); nuclear@2: resize_rtarget(x, y); nuclear@4: nuclear@4: erb_setopti(erb, ERB_OPT_WIDTH, width); nuclear@4: erb_setopti(erb, ERB_OPT_HEIGHT, height); nuclear@2: } nuclear@2: nuclear@2: static void keyb(unsigned char key, int x, int y) nuclear@2: { nuclear@2: switch(key) { nuclear@2: case 27: nuclear@2: exit(0); nuclear@4: nuclear@4: case ' ': nuclear@4: printf("begin rendering\n"); nuclear@4: render_pending = true; nuclear@4: glutIdleFunc(idle); nuclear@4: erb_begin_frame(erb, 0); nuclear@4: break; nuclear@2: } nuclear@9: nuclear@9: if(erb_input_keyboard(key, true)) { nuclear@9: glutPostRedisplay(); nuclear@9: } nuclear@9: } nuclear@9: nuclear@9: static void keyb_up(unsigned char key, int x, int y) nuclear@9: { nuclear@9: if(erb_input_keyboard(key, false)) { nuclear@9: glutPostRedisplay(); nuclear@9: } nuclear@2: } nuclear@2: nuclear@2: static void mouse(int bn, int st, int x, int y) nuclear@2: { nuclear@9: if(erb_input_mouse_button(bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y)) { nuclear@9: glutPostRedisplay(); nuclear@9: } nuclear@9: } nuclear@9: nuclear@9: static void motion(int x, int y) nuclear@9: { nuclear@9: if(erb_input_mouse_move(x, y)) { nuclear@9: glutPostRedisplay(); nuclear@9: } nuclear@9: } nuclear@9: nuclear@9: static void sball_button(int bn, int state) nuclear@9: { nuclear@9: if(erb_input_6dof_button(bn, state == GLUT_DOWN)) { nuclear@9: glutPostRedisplay(); nuclear@9: } nuclear@9: } nuclear@9: nuclear@9: static void sball_motion(int x, int y, int z) nuclear@9: { nuclear@9: if(erb_input_6dof_motion(x / 65536.0, y / 65536.0, z / 65536.0)) { nuclear@9: glutPostRedisplay(); nuclear@9: } nuclear@2: } nuclear@2: nuclear@2: static int next_pow2(int x) nuclear@2: { nuclear@2: int res = 2; nuclear@2: while(res < x) { nuclear@2: res <<= 1; nuclear@2: } nuclear@2: return res; nuclear@2: }