/* * Copyright 2011-2013 Blender Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "util/util_opengl.h" #include "util/util_string.h" #include "util/util_time.h" #include "util/util_version.h" #include "util/util_view.h" #ifdef __APPLE__ #include #else #include #endif CCL_NAMESPACE_BEGIN /* structs */ struct View { ViewInitFunc initf; ViewExitFunc exitf; ViewResizeFunc resize; ViewDisplayFunc display; ViewKeyboardFunc keyboard; ViewMotionFunc motion; bool first_display; bool redraw; int mouseX, mouseY; int mouseBut0, mouseBut2; int width, height; } V; /* public */ static void view_display_text(int x, int y, const char *text) { const char *c; glRasterPos3f(x, y, 0); for(c = text; *c != '\0'; c++) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c); } void view_display_info(const char *info) { const int height = 20; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.1f, 0.1f, 0.1f, 0.8f); glRectf(0.0f, V.height - height, V.width, V.height); glDisable(GL_BLEND); glColor3f(0.5f, 0.5f, 0.5f); view_display_text(10, 7 + V.height - height, info); glColor3f(1.0f, 1.0f, 1.0f); } void view_display_help() { const int w = (int)((float)V.width / 1.15f); const int h = (int)((float)V.height / 1.15f); const int x1 = (V.width - w) / 2; const int x2 = x1 + w; const int y1 = (V.height - h) / 2; const int y2 = y1 + h; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.5f, 0.5f, 0.5f, 0.8f); glRectf(x1, y1, x2, y2); glDisable(GL_BLEND); glColor3f(0.8f, 0.8f, 0.8f); string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING; view_display_text(x1+20, y2-20, info.c_str()); view_display_text(x1+20, y2-40, "(C) 2011-2016 Blender Foundation"); view_display_text(x1+20, y2-80, "Controls:"); view_display_text(x1+20, y2-100, "h: Info/Help"); view_display_text(x1+20, y2-120, "r: Reset"); view_display_text(x1+20, y2-140, "p: Pause"); view_display_text(x1+20, y2-160, "esc: Cancel"); view_display_text(x1+20, y2-180, "q: Quit program"); view_display_text(x1+20, y2-210, "i: Interactive mode"); view_display_text(x1+20, y2-230, "Left mouse: Move camera"); view_display_text(x1+20, y2-250, "Right mouse: Rotate camera"); view_display_text(x1+20, y2-270, "W/A/S/D: Move camera"); view_display_text(x1+20, y2-290, "0/1/2/3: Set max bounces"); glColor3f(1.0f, 1.0f, 1.0f); } static void view_display() { if(V.first_display) { if(V.initf) V.initf(); if(V.exitf) atexit(V.exitf); V.first_display = false; } glClearColor(0.05f, 0.05f, 0.05f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, V.width, 0, V.height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRasterPos3f(0, 0, 0); if(V.display) V.display(); glutSwapBuffers(); } static void view_reshape(int width, int height) { if(width <= 0 || height <= 0) return; V.width = width; V.height = height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if(V.resize) V.resize(width, height); } static void view_keyboard(unsigned char key, int x, int y) { if(V.keyboard) V.keyboard(key); if(key == 'm') printf("mouse %d %d\n", x, y); if(key == 'q') { if(V.exitf) V.exitf(); exit(0); } } static void view_mouse(int button, int state, int x, int y) { if(button == 0) { if(state == GLUT_DOWN) { V.mouseX = x; V.mouseY = y; V.mouseBut0 = 1; } else if(state == GLUT_UP) { V.mouseBut0 = 0; } } else if(button == 2) { if(state == GLUT_DOWN) { V.mouseX = x; V.mouseY = y; V.mouseBut2 = 1; } else if(state == GLUT_UP) { V.mouseBut2 = 0; } } } static void view_motion(int x, int y) { const int but = V.mouseBut0? 0:2; const int distX = x - V.mouseX; const int distY = y - V.mouseY; if(V.motion) V.motion(distX, distY, but); V.mouseX = x; V.mouseY = y; } static void view_idle(void) { if(V.redraw) { V.redraw = false; glutPostRedisplay(); } time_sleep(0.1); } void view_main_loop(const char *title, int width, int height, ViewInitFunc initf, ViewExitFunc exitf, ViewResizeFunc resize, ViewDisplayFunc display, ViewKeyboardFunc keyboard, ViewMotionFunc motion) { const char *name = "app"; char *argv = (char*)name; int argc = 1; memset(&V, 0, sizeof(V)); V.width = width; V.height = height; V.first_display = true; V.redraw = false; V.initf = initf; V.exitf = exitf; V.resize = resize; V.display = display; V.keyboard = keyboard; V.motion = motion; glutInit(&argc, &argv); glutInitWindowSize(width, height); glutInitWindowPosition(0, 0); glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH); glutCreateWindow(title); mxMakeCurrentContext(mxCreateContext()); view_reshape(width, height); glutDisplayFunc(view_display); glutIdleFunc(view_idle); glutReshapeFunc(view_reshape); glutKeyboardFunc(view_keyboard); glutMouseFunc(view_mouse); glutMotionFunc(view_motion); glutMainLoop(); } void view_redraw() { V.redraw = true; } CCL_NAMESPACE_END