Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/app/opengl/window.cpp')
-rw-r--r--intern/cycles/app/opengl/window.cpp365
1 files changed, 365 insertions, 0 deletions
diff --git a/intern/cycles/app/opengl/window.cpp b/intern/cycles/app/opengl/window.cpp
new file mode 100644
index 00000000000..4da0ebdece5
--- /dev/null
+++ b/intern/cycles/app/opengl/window.cpp
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2011-2022 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 <stdio.h>
+#include <stdlib.h>
+
+#include "app/opengl/window.h"
+
+#include "util/string.h"
+#include "util/thread.h"
+#include "util/time.h"
+#include "util/version.h"
+
+#include <GL/glew.h>
+#include <SDL.h>
+
+CCL_NAMESPACE_BEGIN
+
+/* structs */
+
+struct Window {
+ WindowInitFunc initf = nullptr;
+ WindowExitFunc exitf = nullptr;
+ WindowResizeFunc resize = nullptr;
+ WindowDisplayFunc display = nullptr;
+ WindowKeyboardFunc keyboard = nullptr;
+ WindowMotionFunc motion = nullptr;
+
+ bool first_display = true;
+ bool redraw = false;
+
+ int mouseX = 0, mouseY = 0;
+ int mouseBut0 = 0, mouseBut2 = 0;
+
+ int width = 0, height = 0;
+
+ SDL_Window *window = nullptr;
+ SDL_GLContext gl_context = nullptr;
+ thread_mutex gl_context_mutex;
+} V;
+
+/* public */
+
+static void window_display_text(int x, int y, const char *text)
+{
+/* Not currently supported, need to add text rendering support. */
+#if 0
+ const char *c;
+
+ glRasterPos3f(x, y, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ printf("display %s\n", text);
+
+ for (c = text; *c != '\0'; c++) {
+ const uint8_t *bitmap = helvetica10_character_map[*c];
+ glBitmap(bitmap[0],
+ helvetica10_height,
+ helvetica10_x_offset,
+ helvetica10_y_offset,
+ bitmap[0],
+ 0.0f,
+ bitmap + 1);
+ }
+#else
+ static string last_text = "";
+
+ if (text != last_text) {
+ printf("%s\n", text);
+ last_text = text;
+ }
+#endif
+}
+
+void window_display_info(const char *info)
+{
+ const int height = 20;
+
+#if 0
+ 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);
+#endif
+
+ window_display_text(10, 7 + V.height - height, info);
+
+#if 0
+ glColor3f(1.0f, 1.0f, 1.0f);
+#endif
+}
+
+void window_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;
+#if 0
+ const int x2 = x1 + w;
+#endif
+
+ const int y1 = (V.height - h) / 2;
+ const int y2 = y1 + h;
+
+#if 0
+ 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);
+#endif
+
+ string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING;
+
+ window_display_text(x1 + 20, y2 - 20, info.c_str());
+ window_display_text(x1 + 20, y2 - 40, "(C) 2011-2016 Blender Foundation");
+ window_display_text(x1 + 20, y2 - 80, "Controls:");
+ window_display_text(x1 + 20, y2 - 100, "h: Info/Help");
+ window_display_text(x1 + 20, y2 - 120, "r: Reset");
+ window_display_text(x1 + 20, y2 - 140, "p: Pause");
+ window_display_text(x1 + 20, y2 - 160, "esc: Cancel");
+ window_display_text(x1 + 20, y2 - 180, "q: Quit program");
+
+ window_display_text(x1 + 20, y2 - 210, "i: Interactive mode");
+ window_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera");
+ window_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera");
+ window_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera");
+ window_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces");
+
+#if 0
+ glColor3f(1.0f, 1.0f, 1.0f);
+#endif
+}
+
+static void window_display()
+{
+ if (V.first_display) {
+ if (V.initf) {
+ V.initf();
+ }
+ if (V.exitf) {
+ atexit(V.exitf);
+ }
+
+ V.first_display = false;
+ }
+
+ window_opengl_context_enable();
+
+ glViewport(0, 0, V.width, V.height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glClearColor(0.05f, 0.05f, 0.05f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, V.width, 0, V.height, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glRasterPos3f(0, 0, 0);
+
+ if (V.display)
+ V.display();
+
+ SDL_GL_SwapWindow(V.window);
+ window_opengl_context_disable();
+}
+
+static void window_reshape(int width, int height)
+{
+ if (V.width != width || V.height != height) {
+ if (V.resize) {
+ V.resize(width, height);
+ }
+ }
+
+ V.width = width;
+ V.height = height;
+}
+
+static bool window_keyboard(unsigned char key)
+{
+ if (V.keyboard)
+ V.keyboard(key);
+
+ if (key == 'q') {
+ if (V.exitf)
+ V.exitf();
+ return true;
+ }
+
+ return false;
+}
+
+static void window_mouse(int button, int state, int x, int y)
+{
+ if (button == SDL_BUTTON_LEFT) {
+ if (state == SDL_MOUSEBUTTONDOWN) {
+ V.mouseX = x;
+ V.mouseY = y;
+ V.mouseBut0 = 1;
+ }
+ else if (state == SDL_MOUSEBUTTONUP) {
+ V.mouseBut0 = 0;
+ }
+ }
+ else if (button == SDL_BUTTON_RIGHT) {
+ if (state == SDL_MOUSEBUTTONDOWN) {
+ V.mouseX = x;
+ V.mouseY = y;
+ V.mouseBut2 = 1;
+ }
+ else if (state == SDL_MOUSEBUTTONUP) {
+ V.mouseBut2 = 0;
+ }
+ }
+}
+
+static void window_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;
+}
+
+bool window_opengl_context_enable()
+{
+ V.gl_context_mutex.lock();
+ SDL_GL_MakeCurrent(V.window, V.gl_context);
+ return true;
+}
+
+void window_opengl_context_disable()
+{
+ SDL_GL_MakeCurrent(V.window, nullptr);
+ V.gl_context_mutex.unlock();
+}
+
+void window_main_loop(const char *title,
+ int width,
+ int height,
+ WindowInitFunc initf,
+ WindowExitFunc exitf,
+ WindowResizeFunc resize,
+ WindowDisplayFunc display,
+ WindowKeyboardFunc keyboard,
+ WindowMotionFunc motion)
+{
+ 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;
+
+ SDL_Init(SDL_INIT_VIDEO);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
+ V.window = SDL_CreateWindow(title,
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ width,
+ height,
+ SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
+ if (V.window == nullptr) {
+ fprintf(stderr, "Failed to create window: %s\n", SDL_GetError());
+ return;
+ }
+
+ SDL_RaiseWindow(V.window);
+
+ V.gl_context = SDL_GL_CreateContext(V.window);
+ glewInit();
+ SDL_GL_MakeCurrent(V.window, nullptr);
+
+ window_reshape(width, height);
+ window_display();
+
+ while (true) {
+ bool quit = false;
+ SDL_Event event;
+ while (!quit && SDL_PollEvent(&event)) {
+ if (event.type == SDL_TEXTINPUT) {
+ quit = window_keyboard(event.text.text[0]);
+ }
+ else if (event.type == SDL_MOUSEMOTION) {
+ window_motion(event.motion.x, event.motion.y);
+ }
+ else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
+ window_mouse(event.button.button, event.button.state, event.button.x, event.button.y);
+ }
+ else if (event.type == SDL_WINDOWEVENT) {
+ if (event.window.event == SDL_WINDOWEVENT_RESIZED ||
+ event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+ window_reshape(event.window.data1, event.window.data2);
+ }
+ }
+ else if (event.type == SDL_QUIT) {
+ if (V.exitf) {
+ V.exitf();
+ }
+ quit = true;
+ }
+ }
+
+ if (quit) {
+ break;
+ }
+
+ if (V.redraw) {
+ V.redraw = false;
+ window_display();
+ }
+
+ SDL_WaitEventTimeout(NULL, 100);
+ }
+
+ SDL_GL_DeleteContext(V.gl_context);
+ SDL_DestroyWindow(V.window);
+ SDL_Quit();
+}
+
+void window_redraw()
+{
+ V.redraw = true;
+}
+
+CCL_NAMESPACE_END