summaryrefslogtreecommitdiff
path: root/src/gl/init.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gl/init.cc')
-rw-r--r--src/gl/init.cc95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/gl/init.cc b/src/gl/init.cc
new file mode 100644
index 0000000..b8ac83e
--- /dev/null
+++ b/src/gl/init.cc
@@ -0,0 +1,95 @@
+// Copyright 2021 Benjamin Barenblat
+//
+// 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
+//
+// https://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 "src/gl/init.h"
+
+#include <stdexcept>
+
+#include "src/gl/error.h"
+#include "third_party/abseil/absl/strings/str_cat.h"
+#include "third_party/abseil/absl/strings/substitute.h"
+#include "third_party/glew/include/GL/glew.h"
+
+namespace gl {
+
+namespace {
+
+using ::gl_internal::ErrorCheck;
+using ::gl_internal::UnnecessaryErrorCheck;
+
+void InitializeGlew() {
+ glewExperimental = GL_TRUE;
+ if (GLenum err = glewInit(); err != GLEW_OK) {
+ const GLubyte* error_string = glewGetErrorString(err);
+ throw std::runtime_error(absl::StrCat(
+ "GL: glewInit failed: ", reinterpret_cast<const char*>(error_string)));
+ }
+}
+
+void CheckGlVersion() {
+ GLint major_version;
+ try {
+ glGetIntegerv(GL_MAJOR_VERSION, &major_version);
+ ErrorCheck();
+ } catch (const std::invalid_argument&) {
+ // GL_MAJOR_VERSION doesn't even exist yet, which means we're on OpenGL 2.
+ throw std::runtime_error("GL: OpenGL 3.2 is required");
+ }
+ if (major_version == 3) {
+ GLint minor_version;
+ glGetIntegerv(GL_MINOR_VERSION, &minor_version);
+ UnnecessaryErrorCheck();
+ if (minor_version < 2) {
+ throw std::runtime_error("GL: OpenGL 3.2 is required");
+ }
+ }
+}
+
+void CheckGlExtensions() {
+ if (!GLEW_ARB_texture_storage) {
+ throw std::runtime_error("GL: ARB_texture_storage is required");
+ }
+ if (!GLEW_ARB_direct_state_access) {
+ throw std::runtime_error("GL: ARB_direct_state_access is required");
+ }
+}
+
+} // namespace
+
+void InitializeForThisThread() {
+ gl_internal::RecordThread();
+ InitializeGlew();
+ ErrorCheck(); // just to make sure we're starting clean
+ CheckGlVersion();
+ CheckGlExtensions();
+
+ // Assume byte-aligned rows in images.
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ UnnecessaryErrorCheck();
+}
+
+void SetClearColor(float red, float green, float blue, float alpha) {
+ gl_internal::CheckThreadSafety();
+
+ if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1 ||
+ alpha < 0 || alpha > 1) {
+ throw std::invalid_argument(absl::Substitute(
+ "GL: invalid clear color ($0, $1, $2, $3)", red, green, blue, alpha));
+ }
+
+ glClearColor(red, green, blue, alpha);
+ gl_internal::UnnecessaryErrorCheck();
+}
+
+} // namespace gl