erebus

annotate src/main.cc @ 28:4a0a288ffb27

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