mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:30:05 +00:00 
			
		
		
		
	Add texture loading in GlContext
This commit is contained in:
		
							parent
							
								
									82d761c939
								
							
						
					
					
						commit
						ab50f0b9a2
					
				
					 2 changed files with 120 additions and 2 deletions
				
			
		|  | @ -1,5 +1,14 @@ | ||||||
| #include <scwx/qt/gl/gl_context.hpp> | #include <scwx/qt/gl/gl_context.hpp> | ||||||
|  | #include <scwx/qt/util/streams.hpp> | ||||||
| #include <scwx/util/hash.hpp> | #include <scwx/util/hash.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | #pragma warning(push, 0) | ||||||
|  | #include <boost/gil.hpp> | ||||||
|  | #include <boost/gil/extension/io/png.hpp> | ||||||
|  | #include <boost/iostreams/stream.hpp> | ||||||
|  | #include <QFile> | ||||||
|  | #pragma warning(pop) | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -8,19 +17,34 @@ namespace qt | ||||||
| namespace gl | namespace gl | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::qt::gl::gl_context"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
| class GlContext::Impl | class GlContext::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl() : gl_ {}, shaderProgramMap_ {}, shaderProgramMutex_ {} {} |    explicit Impl() : | ||||||
|  |        gl_ {}, | ||||||
|  |        shaderProgramMap_ {}, | ||||||
|  |        shaderProgramMutex_ {}, | ||||||
|  |        textureMap_ {}, | ||||||
|  |        textureMutex_ {} | ||||||
|  |    { | ||||||
|  |    } | ||||||
|    ~Impl() {} |    ~Impl() {} | ||||||
| 
 | 
 | ||||||
|  |    GLuint CreateTexture(const std::string& texturePath); | ||||||
|  | 
 | ||||||
|    gl::OpenGLFunctions gl_; |    gl::OpenGLFunctions gl_; | ||||||
| 
 | 
 | ||||||
|    std::unordered_map<std::pair<std::string, std::string>, |    std::unordered_map<std::pair<std::string, std::string>, | ||||||
|                       std::shared_ptr<gl::ShaderProgram>, |                       std::shared_ptr<gl::ShaderProgram>, | ||||||
|                       util::hash<std::pair<std::string, std::string>>> |                       scwx::util::hash<std::pair<std::string, std::string>>> | ||||||
|               shaderProgramMap_; |               shaderProgramMap_; | ||||||
|    std::mutex shaderProgramMutex_; |    std::mutex shaderProgramMutex_; | ||||||
|  | 
 | ||||||
|  |    std::unordered_map<std::string, GLuint> textureMap_; | ||||||
|  |    std::mutex                              textureMutex_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| GlContext::GlContext() : p(std::make_unique<Impl>()) {} | GlContext::GlContext() : p(std::make_unique<Impl>()) {} | ||||||
|  | @ -59,6 +83,98 @@ GlContext::GetShaderProgram(const std::string& vertexPath, | ||||||
|    return shaderProgram; |    return shaderProgram; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | GLuint GlContext::GetTexture(const std::string& texturePath) | ||||||
|  | { | ||||||
|  |    GLuint texture = GL_INVALID_INDEX; | ||||||
|  | 
 | ||||||
|  |    std::unique_lock lock(p->textureMutex_); | ||||||
|  | 
 | ||||||
|  |    auto it = p->textureMap_.find(texturePath); | ||||||
|  | 
 | ||||||
|  |    if (it == p->textureMap_.end()) | ||||||
|  |    { | ||||||
|  |       texture                     = p->CreateTexture(texturePath); | ||||||
|  |       p->textureMap_[texturePath] = texture; | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       texture = it->second; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return texture; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TODO: Move to dedicated file
 | ||||||
|  | GLuint GlContext::Impl::CreateTexture(const std::string& texturePath) | ||||||
|  | { | ||||||
|  |    logger_->warn("Create Texture: {}", texturePath); | ||||||
|  | 
 | ||||||
|  |    GLuint texture; | ||||||
|  | 
 | ||||||
|  |    QFile textureFile(texturePath.c_str()); | ||||||
|  | 
 | ||||||
|  |    textureFile.open(QIODevice::ReadOnly); | ||||||
|  | 
 | ||||||
|  |    if (!textureFile.isOpen()) | ||||||
|  |    { | ||||||
|  |       logger_->error("Could not load texture: {}", texturePath); | ||||||
|  |       return GL_INVALID_INDEX; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    boost::iostreams::stream<util::IoDeviceSource> dataStream(textureFile); | ||||||
|  | 
 | ||||||
|  |    boost::gil::rgba8_image_t image; | ||||||
|  | 
 | ||||||
|  |    try | ||||||
|  |    { | ||||||
|  |       boost::gil::read_and_convert_image( | ||||||
|  |          dataStream, image, boost::gil::png_tag()); | ||||||
|  |    } | ||||||
|  |    catch (const std::exception& ex) | ||||||
|  |    { | ||||||
|  |       logger_->error("Error reading texture: {}", ex.what()); | ||||||
|  |       return GL_INVALID_INDEX; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    boost::gil::rgba8_view_t view = boost::gil::view(image); | ||||||
|  | 
 | ||||||
|  |    std::vector<boost::gil::rgba8_pixel_t> pixelData(view.width() * | ||||||
|  |                                                     view.height()); | ||||||
|  | 
 | ||||||
|  |    boost::gil::copy_pixels( | ||||||
|  |       view, | ||||||
|  |       boost::gil::interleaved_view(view.width(), | ||||||
|  |                                    view.height(), | ||||||
|  |                                    pixelData.data(), | ||||||
|  |                                    view.width() * | ||||||
|  |                                       sizeof(boost::gil::rgba8_pixel_t))); | ||||||
|  | 
 | ||||||
|  |    OpenGLFunctions& gl = gl_; | ||||||
|  | 
 | ||||||
|  |    gl.glGenTextures(1, &texture); | ||||||
|  |    gl.glBindTexture(GL_TEXTURE_2D, texture); | ||||||
|  | 
 | ||||||
|  |    // TODO: Change to GL_REPEAT once a texture atlas is used
 | ||||||
|  |    gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||||||
|  |    gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||||||
|  |    gl.glTexParameteri( | ||||||
|  |       GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); | ||||||
|  |    gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||||
|  | 
 | ||||||
|  |    gl.glTexImage2D(GL_TEXTURE_2D, | ||||||
|  |                    0, | ||||||
|  |                    GL_RGBA, | ||||||
|  |                    view.width(), | ||||||
|  |                    view.height(), | ||||||
|  |                    0, | ||||||
|  |                    GL_RGBA, | ||||||
|  |                    GL_UNSIGNED_BYTE, | ||||||
|  |                    pixelData.data()); | ||||||
|  |    gl.glGenerateMipmap(GL_TEXTURE_2D); | ||||||
|  | 
 | ||||||
|  |    return texture; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace gl
 | } // namespace gl
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
| } // namespace scwx
 | } // namespace scwx
 | ||||||
|  |  | ||||||
|  | @ -28,6 +28,8 @@ public: | ||||||
|    GetShaderProgram(const std::string& vertexPath, |    GetShaderProgram(const std::string& vertexPath, | ||||||
|                     const std::string& fragmentPath); |                     const std::string& fragmentPath); | ||||||
| 
 | 
 | ||||||
|  |    GLuint GetTexture(const std::string& texturePath); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|    class Impl; |    class Impl; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat