/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ /** * @file Texture.h * @brief クラス MGGridCursor の宣言 */ #include "MGCLStdAfx.h" #include "mgGL/Texture.h" #include "mgGL/GLSLProgram.h" #include "mgGL/Image.h" namespace{int glErr;}; ///Texture definition class. ///Before use of mgTexture, set_image must be invoked. ///set_sampler is optionally invoked. If set_sampler is not invoked, ///uniform of spampler2D "texture1" is assumed. ///When set_textureUnit is not invoked, unit number 0 is assumed. const std::string& mgTexture::getDefaultSamplerVariable()const{ static const std::string m_DefaultSamplerVariable="texture1"; return m_DefaultSamplerVariable; } /// デフォルトコンストラクター ///Before use of mgTexture, set_image and set_sampler must be invoked. mgTexture::mgTexture( GLenum target///Currently only GL_TEXTURE_2D is allowed. ):m_target(target),m_width(0), m_height(0),m_numberOfTextureLevels(1), m_textureUnit(0),m_textureID(0),m_samplerLocation(-1){ } mgTexture::~mgTexture(){ if(m_textureID) glDeleteTextures(1,&m_textureID); } ///Set the glsl program and sampler variable name of void mgTexture::set_sampler(mgGLSLProgram* glsl, const std::string& samplerName){ //glsl->use(); m_samplerLocation=glsl->getUniformLocation(samplerName.c_str()); } ///image データをtextureにセットする /// @note pixelsピクセルデータのフォーマットについて説明すると、 /// GLuint 型の配列を利用し、各 4 バイトを 1 ピクセルの色に対応させている。 /// 整数の上位バイトから A, B, G, R の順に格納されていることを前提とする。 /// 例えば値 0xFF000000, 0xFFFF0000, 0xFF00FF00, 0xFF0000FF はそれぞれ /// 黒、青、緑、赤を意味する。 ///Set the image data. set_image() invokes: ///1. glGenTextures(if m_textureID was 0), ///2. glBindTexture ///3. glTexImage2D or glTexStorege2D ///4. glTexSubImage2D ///*******After set_image is invoked, image data is unnecessary since the data ///is transfered to GPU. void mgTexture::set_image( GLsizei width, ///< ビットマップデータの横幅。ピクセル幅と考えて差し支えない。 GLsizei height,///< ビットマップデータの縦幅。 const GLuint* pixels,///< RGBA バイト列。各整数の上位バイトが A 値。 bool mutableTexture ,bool isPointSprite ,GLint wrap///GL_TEXTURE_WRAP_S&GL_TEXTURE_WRAP_Tに指定するparameterを指定 ///GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_MIRRORED_REPEAT, ///or GL_MIRROR_CLAMP_TO_EDGEGL_REPEAT. ,GLint magminFilter///GL_TEXTURE_MAG_FILTER&GL_TEXTURE_MIN_FILTERに ///指定するparameterを指定する:GL_NEAREST,GL_LINEAR,GL_NEAREST_MIPMAP_NEAREST, ///GL_LINEAR_MIPMAP_NEAREST,GL_NEAREST_MIPMAP_LINEAR,GL_LINEAR_MIPMAP_LINEAR ///いずれか。GL_TEXTURE_MAG_FILTER&GL_TEXTURE_MIN_FILTER双方に同じ値がセットされる。 ){ if(!m_textureID) glGenTextures(1,&m_textureID); mgGLSLProgram* glsl=mgGLSLProgram::getCurrentGLSLProgram(); GLint major, minor; glsl->getOpenGLVerion(major,minor); if(minor<=1) mutableTexture=true; glBindTexture(m_target, m_textureID); assert(glIsTexture(m_textureID)); if(isPointSprite){ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); } GLint textureLevel=0; if(mutableTexture) glTexImage2D(m_target,textureLevel, GL_RGBA8,//internal format width,height, 0,GL_RGBA,GL_UNSIGNED_BYTE,0); else glTexStorage2D(m_target,m_numberOfTextureLevels,GL_RGBA8,width,height);//not usable in 4.1 glTexParameteri(m_target,GL_TEXTURE_WRAP_S,wrap); glTexParameteri(m_target,GL_TEXTURE_WRAP_T,wrap); glTexParameteri(m_target,GL_TEXTURE_MAG_FILTER,magminFilter); glTexParameteri(m_target,GL_TEXTURE_MIN_FILTER,magminFilter); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); glTexSubImage2D(m_target,textureLevel, 0,0,width,height,//xoffset, yoffset, width,hwight GL_RGBA,GL_UNSIGNED_BYTE,pixels); glBindTexture(m_target, 0); m_width=width; m_height=height; } ///Set the image data. set_image() invokes: ///1. glGenTextures(if m_textureIDwas 0), ///2. glBindTexture ///3. glTexImage2D or glTexStorege2D ///4. glTexSubImage2D ///*******After set_image is invoked, image data is unnecessary since teh data ///is transfered to GPU. void mgTexture::set_image( const MGImage& image, bool mutableTexture ,bool isPointSprite ,GLint wrap///GL_TEXTURE_WRAP_S&GL_TEXTURE_WRAP_Tに指定するparameterを指定 ///GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_MIRRORED_REPEAT, ///or GL_MIRROR_CLAMP_TO_EDGEGL_REPEAT. ,GLint magminFilter///GL_TEXTURE_MAG_FILTER&GL_TEXTURE_MIN_FILTERに ///指定するparameterを指定する:GL_NEAREST,GL_LINEAR,GL_NEAREST_MIPMAP_NEAREST, ///GL_LINEAR_MIPMAP_NEAREST,GL_NEAREST_MIPMAP_LINEAR,GL_LINEAR_MIPMAP_LINEAR ///いずれか。GL_TEXTURE_MAG_FILTER&GL_TEXTURE_MIN_FILTER双方に同じ値がセットされる。 ){ set_image(image.width(),image.height(),(GLuint*)image.image() ,mutableTexture, isPointSprite,wrap,magminFilter); } ///Use this texture after set_image and set_sampler are invoked. ///Use() will invoke OpenGL: ///1. glActiveTexture() ///2. glBindTexture() ///4. glSetUniform1i(m_samplerLocation). ///*****glUseProgram() is not invoked, m_samplerLocation must be ///the current program's. void mgTexture::use()const{ int TUnitEnum=GL_TEXTURE0+m_textureUnit; glActiveTexture(TUnitEnum); assert(m_textureID); glBindTexture(m_target,m_textureID); mgGLSLProgram* glsl=mgGLSLProgram::getCurrentGLSLProgram(); glsl->setUniform(mgGLSLProgram::texture2D, m_textureUnit); }