Pārlūkot izejas kodu

Adding OpenGL implementation of Texture files.

Sam Jaffe 6 gadi atpakaļ
vecāks
revīzija
df0605a766

+ 12 - 0
graphics/graphics.xcodeproj/project.pbxproj

@@ -12,6 +12,9 @@
 		CD3AC6FD1D2C06B5002B4BB0 /* shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3AC6FB1D2C06B5002B4BB0 /* shader.cpp */; };
 		CD3AC7191D2C0950002B4BB0 /* shader_program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3AC7171D2C0950002B4BB0 /* shader_program.cpp */; };
 		CD3AC7261D2C0C63002B4BB0 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3AC7241D2C0C63002B4BB0 /* object.cpp */; };
+		CD62FCF72290DC9000376440 /* helper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = CD62FCF52290DC9000376440 /* helper.hpp */; };
+		CD62FCF82290DC9000376440 /* opengl_helper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD62FCF62290DC9000376440 /* opengl_helper.cxx */; };
+		CD62FCFA2290E2E500376440 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD62FCF92290E2E500376440 /* OpenGL.framework */; };
 		CDA34D9A22517A3D008036A7 /* libmath.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CDA34D9922517A3D008036A7 /* libmath.dylib */; };
 /* End PBXBuildFile section */
 
@@ -54,6 +57,9 @@
 		CD3AC7171D2C0950002B4BB0 /* shader_program.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shader_program.cpp; sourceTree = "<group>"; };
 		CD3AC7241D2C0C63002B4BB0 /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
 		CD62FCD722904AD100376440 /* GoogleMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GoogleMock.xcodeproj; path = "../../gmock-xcode-master/GoogleMock.xcodeproj"; sourceTree = "<group>"; };
+		CD62FCF52290DC9000376440 /* helper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = helper.hpp; sourceTree = "<group>"; };
+		CD62FCF62290DC9000376440 /* opengl_helper.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = opengl_helper.cxx; sourceTree = "<group>"; };
+		CD62FCF92290E2E500376440 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		CDA34D86225171AA008036A7 /* game */ = {isa = PBXFileReference; lastKnownFileType = folder; name = game; path = include/game; sourceTree = "<group>"; };
 		CDA34D9922517A3D008036A7 /* libmath.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libmath.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
@@ -63,6 +69,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				CD62FCFA2290E2E500376440 /* OpenGL.framework in Frameworks */,
 				CDA34D9A22517A3D008036A7 /* libmath.dylib in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -95,6 +102,8 @@
 				CD3AC6F01D2C03B7002B4BB0 /* material.cpp */,
 				CD3AC6FB1D2C06B5002B4BB0 /* shader.cpp */,
 				CD3AC7171D2C0950002B4BB0 /* shader_program.cpp */,
+				CD62FCF52290DC9000376440 /* helper.hpp */,
+				CD62FCF62290DC9000376440 /* opengl_helper.cxx */,
 				CD3AC6F61D2C0518002B4BB0 /* texture.cpp */,
 				CD3AC7241D2C0C63002B4BB0 /* object.cpp */,
 			);
@@ -115,6 +124,7 @@
 		CDA34D9822517A3D008036A7 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				CD62FCF92290E2E500376440 /* OpenGL.framework */,
 				CDA34D9922517A3D008036A7 /* libmath.dylib */,
 			);
 			name = Frameworks;
@@ -127,6 +137,7 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				CD62FCF72290DC9000376440 /* helper.hpp in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -249,6 +260,7 @@
 				CD3AC6F21D2C03B7002B4BB0 /* material.cpp in Sources */,
 				CD3AC6F81D2C0518002B4BB0 /* texture.cpp in Sources */,
 				CD3AC7261D2C0C63002B4BB0 /* object.cpp in Sources */,
+				CD62FCF82290DC9000376440 /* opengl_helper.cxx in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 20 - 0
graphics/src/helper.hpp

@@ -0,0 +1,20 @@
+//
+//  helper.hpp
+//  graphics
+//
+//  Created by Sam Jaffe on 5/18/19.
+//  Copyright © 2019 Sam Jaffe. All rights reserved.
+//
+
+#pragma once
+
+#include <string>
+#include <unordered_map>
+
+#include "game/math/math_fwd.hpp"
+
+namespace graphics { namespace detail { namespace texture {
+  enum class format { RGB, RGBA };
+
+  unsigned int init(format, math::vec2i, unsigned char *);
+}}}

+ 92 - 0
graphics/src/opengl_helper.cxx

@@ -0,0 +1,92 @@
+//
+//  helper.cxx
+//  graphics
+//
+//  Created by Sam Jaffe on 5/18/19.
+//  Copyright © 2019 Sam Jaffe. All rights reserved.
+//
+
+#include "helper.hpp"
+
+#ifdef __APPLE__
+#include <OpenGL/gl3.h>
+#endif
+
+#include "vector/vector.hpp"
+
+namespace graphics { namespace detail { namespace texture {
+  static int glfmt(format color_fmt) {
+    switch (color_fmt) {
+    case format::RGB:
+      return GL_RGB;
+    case format::RGBA:
+      return GL_RGBA;
+    }
+  }
+
+  unsigned int init(format color_fmt, math::vec2i dimension,
+                    unsigned char * data) {
+    unsigned int id;
+    // Enable texturings
+    //    glEnable( GL_TEXTURE_2D );
+
+    // Tell OpenGL that our pixel data is single-byte aligned
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+    // Ask OpenGL for an unused texName (ID number) to use for this texture
+    glGenTextures(1, &id);
+
+    // Tell OpenGL to bind (set) this as the currently active texture
+    glBindTexture(GL_TEXTURE_2D, id);
+    // Set texture clamp vs. wrap (repeat)
+
+    // one of: GL_CLAMP_TO_EDGE, GL_REPEAT, GL_MIRRORED_REPEAT,
+    // GL_MIRROR_CLAMP_TO_EDGE, ...
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    // the format our source pixel data is currently in; any of: GL_RGB,
+    // GL_RGBA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, ...
+    int bufferFormat = glfmt(color_fmt);
+
+    // the format we want the texture to me on the card; allows us to translate
+    // into a different texture format as we upload to OpenGL
+    int internalFormat = bufferFormat;
+
+    /* glTexImage2D: Load a 2d texture image
+     * target: Creating this as a 2d texture.
+     * level: Which mipmap level to use as the "root" (0 = the highest-quality,
+     *  full-res image), if mipmaps are enabled.
+     * internalFormat: Type of texel format we want OpenGL to use for this
+     *  texture internally on the video card.
+     * width: Texel-width of image; for maximum compatibility, use 2^N + 2^B,
+     *  where N is some integer in the range [3,10], and B is the border
+     *  thickness [0,1]
+     * height: Texel-height of image; for maximum compatibility, use 2^M + 2^B,
+     *  where M is some integer in the range [3,10], and B is the border
+     *  thickness [0,1]
+     * border: Border size, in texels (must be 0 or 1)
+     * format: Pixel format describing the composition of the pixel data in
+     *  buffer
+     * type: Pixel color components are unsigned bytes (one byte per color/alpha
+     *  channel)
+     * pixels: Location of the actual pixel data bytes/buffer
+     */
+    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimension.x(), dimension.y(),
+                 0, bufferFormat, GL_UNSIGNED_BYTE, data);
+
+    glGenerateMipmap(GL_TEXTURE_2D);
+
+    // Set magnification (texel > pixel) and minification (texel < pixel)
+    // filters one of: GL_NEAREST, GL_LINEAR
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    // one of: GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST,
+    // GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST,
+    // GL_LINEAR_MIPMAP_LINEAR
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+                    GL_NEAREST_MIPMAP_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5);
+
+    return id;
+  }
+}}}

+ 2 - 9
graphics/src/texture.cpp

@@ -20,19 +20,12 @@
 unsigned char * stbi_load(char const *, int *, int *, int *, int);
 void stbi_image_free(void *);
 
-namespace graphics { namespace detail { namespace texture {
-  struct format {};
-
+namespace {
   std::unordered_map<std::string, ::graphics::texture> g_textures;
-
-  unsigned int init(format = {}, math::vec2i = {}, unsigned char * = {}) {
-    throw; // TODO implement
-  }
-}}}
+}
 
 namespace graphics {
   texture texture::create(std::string const & imagefile) {
-    using detail::texture::g_textures;
     auto found = g_textures.find(imagefile);
     if (found != g_textures.end()) { return found->second; }