#pragma once #include "AftrConfig.h" #include "TexDataShared.h" #include "Vector.h" #include "Mat4.h" #include #include namespace Aftr { /** \brief A class that represents a Tex that can be bound across one or more verticies. Each Tex object has two parts... Shared data and per instance data. The shared data is stored in memory exactly once and is managed by the ManagerTex; this is the fundamental data that does not ever change regardless of how it is drawn. This includes things like the server side OpenGL handle, the filename corresponding to that data, the actual image data, etc. This is owned by the ManagerTex and should not be directly manipulated by the user without using the ManagerTex's functions. This data is stored inside the TexDataShared Object. There is a many-to-one mapping where many Tex Objects map to a single TexDataShared. A Tex Object has an internal pointer to a TexDataShared Object. The per instance data is unique to this Tex Object and is owned by this Tex Object. This includes such things as this Tex Object's Tex rotation matrix, Tex translate amount, various Tex related OpenGL flags (GL_CLAMP_TO_EDGE, GL_REPEAT, GL_CLAMP_TO_BORDER, GL_MIRRORED_REPEAT, GL_MIRROR_CLAMP_TO_EDGE), and other attributes that change the properties of the Tex when it is rendered. */ class Tex { public: friend class ManagerTex; //Default Tex simply displays the default texture as its image. This let's one easily //default construct a Tex and change it later using value semantics. Tex(); Tex( std::shared_ptr texDataShared ); Tex( const Tex& tex ); ~Tex(); //This class is abstract and cannot be instantiated /** Returns a clone of this instance; behaves identically to proper copy constructor. This exists, however, because a copy constructor may be of a base type and accept a derived Tex. This method enforces that the new'd Tex is always of the exact subclass even though a base Tex* is returned. */ //virtual Tex* cloneMe() = 0; //replace w/ value semantics -- copy std::shared_ptr getTexDataShared() const; /** This resets all properties owned by this Tex Object. This includes resetting the this Tex's Tex rotation matrix to identity, this Tex's translate Vector to (0,0,0), resetting all flags to default values. */ void resetTexProperties(); Tex& operator =( const Tex& tex ); /** \return a string containg "FileName:'(fileName)', GLuint:'(glTexName)'". */ std::string toString() const; /// \returns the file name loaded in this Tex or "" if not set. std::string getFileName() const; /// \returns the name of the OpenGL Tex. That is, this is the value to use in glBindTex. GLuint getGLTex() const; /** This flag remains false until the Tex is fully loaded into OGL. Once true, this Tex's TexDataShared->glTex can be bound and will show the expected Tex. If this Tex is bound before this flag gets set to true, the engine's default Tex may be displayed but this will not cause undefined behavior. This flag is only useful if this Tex was loaded via ManagerTex::loadTexAsync(...); otherwise, this flag gets set to true before ManagerTex::loadTex(...) returns this object. ManagerTex::loadTexAsync(...) dispatches a separate thread to load the Tex so this can be done in parallel. */ bool isTexFullyInitialized() { return this->tds->isTexFullyInitialized(); } unsigned int getWidthInPixels() const { return this->tds->getWidthInPixels(); } unsigned int getHeightInPixels() const { return this->tds->getHeightInPixels(); } bool isMipmapped() { return this->tds->isMipmapped(); } bool isUsingTexMatrix() { return this->UseTexMat; } void isUsingTexMatrix( bool useTexMatrix ) { this->UseTexMat = useTexMatrix; } /** Enables Tex to be outputted to an ostream. */ friend std::ostream& operator <<( std::ostream&, const Tex& ); void bind() const; void bindGL32() const; void bindCompatibility() const; void unbind() const; void unbindGL32() const; void unbindCompatibility() const; Mat4 const& getTexMatrix() const noexcept; ///< Only the current Direction Cosine Matrix (no translations or scalings) Mat4 getTexMatrixWithRotScaleAndTrans() const noexcept; ///< Full Tex Matrix expected by a Shader void setTexMatrix( const float* const m4x4ColMajorTexMatrix ); void setTexMatrix( const Mat4& texMatrix ); Vector transformVecThroughCurrentTexMatrix( const Vector& vec ); Vector transformVecThroughCurrentTexMatrixAddingCurrentPosition( const Vector& vec ); Vector transformVecThroughCurrentTexMatrixSubtractingCurrentPosition( const Vector& vec ); Vector transformVecThroughInverseOfCurrentTexMatrix( const Vector& vec ); Vector transformVecThroughInverseOfCurrentTexMatrixAddingCurrentPosition( const Vector& vec ); Vector transformVecThroughInverseOfCurrentTexMatrixSubtractingCurrentPosition( const Vector& vec ); void rotateAboutGlobalX( float deltaRadianAngle ); void rotateAboutGlobalY( float deltaRadianAngle ); void rotateAboutGlobalZ( float deltaRadianAngle ); void rotateAboutRelAribitraryAxis( const Vector& axisOfRot, float radianDistance ); void rotateAboutRelX( float deltaRadianAngle ); void rotateAboutRelY( float deltaRadianAngle ); void rotateAboutRelZ( float deltaRadianAngle ); void rotateAboutGlobalAribitraryAxis( const Vector& axisOfRot, float radianDistance ); void translateTex( const Vector& displacement ); void setTexPosition( const Vector& position ); Vector getTexPosition() const { return this->texTrans; } void setTexRotationPoint( const Vector& rotPointTexSpace ) { this->fixedPoint = rotPointTexSpace; } void setTexScaleFactor( const Vector& scaleFactor ); void scaleTex( const Vector& deltaScaleToAddToCurrentScaleFactor ); Vector getTexScaleFactor() const { return this->texScale; } void setTexRepeatsInX( float numRepeats ); void setTexRepeatsInY( float numRepeats ); void setTexRepeatsInZ( float numRepeats ); void setTexRepeats( float numRepeats ); void setWrapS( GLint glWrapParam ); void setWrapT( GLint glWrapParam ); void setMinFilter( GLenum minFilter ); void setMagFilter( GLenum magFilter ); void setEnvMode( GLenum envMode ) { this->envMode = envMode; } private: /** Each Tex object has two parts... Shared data and per instance data. The shared data is stored in memory exactly once and is managed by the ManagerTex; this is the fundamental data that does not ever change regardless of how it is drawn. This includes things like the server side OpenGL handle, the filename corresponding to that data, the actual image data, etc. This is owned by the ManagerTex and should not be directly manipulated by the user without using the ManagerTex's functions. This data is stored inside the TexDataShared Object. There is a many-to-one mapping where many Tex Objects map to a single TexDataShared. A Tex Object has an internal pointer to a TexDataShared Object. The per instance data is unique to this Tex Object and is owned by this Tex Object. This includes such things as this Tex Object's Tex rotation matrix, Tex translate amount, various Tex related OpenGL flags (GL_CLAMP_TO_EDGE, GL_REPEAT, GL_CLAMP_TO_BORDER, GL_MIRRORED_REPEAT, GL_MIRROR_CLAMP_TO_EDGE), and other attributes that change the properties of the Tex when it is rendered. */ std::shared_ptr tds; //if loaded via ManagerTex::loadAsyncTex(...) one reference is in the ManagerTex's internal map //if loaded via ManagerTex::loadAsyncTex_unregistered(...) this is the only reference and will be destroyed if not kept alive /** Per instances data for this Tex Object. This data is owned by this Tex Object. */ Mat4 texMat; ///< Tex rotation matrix Vector texTrans; ///< Tex translation in X,Y, and Z dimensions Vector texScale{ 1,1,1 }; ///< Tex scaling in X,Y, and Z dimensions Vector fixedPoint{0.5f,0.5f,0.5f}; ///< Point about which this Tex is rotated - for OpenGL, .5,.5,.5 is center of Tex halfway between [0,1] bool UseTexMat = false; ///< Iff true, this Tex is rotated via this matrix prior to each render; else texMat is not used bool UseTexTrans = false; ///< Iff true, this Tex is translated by texTrans vector prior to each render; else texTrans is not used bool UseTexScale = false; ///< Iff true, this Tex is scaled by texScale vector prior to each render; else texScale is not used //Tex OpenGL Flags //http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/texparameter.html /** Sets this Tex's environment via glTexEnvi(). (not supported in core) This can be set to one of GL_MODULATE, GL_DECAL, GL_BLEND, or GL_REPLACE. */ GLint envMode = GL_MODULATE; GLint wrapS = GL_REPEAT; ///< Sets the wrap parameter for Tex coordinate s (u coord) to either GL_CLAMP_TO_EDGE, GL_REPEAT, GL_CLAMP_TO_BORDER, GL_MIRRORED_REPEAT, GL_MIRROR_CLAMP_TO_EDGE GLint wrapT = GL_REPEAT; ///< Sets the wrap parameter for Tex coordinate t (v coord) to either GL_CLAMP_TO_EDGE, GL_REPEAT, GL_CLAMP_TO_BORDER, GL_MIRRORED_REPEAT, GL_MIRROR_CLAMP_TO_EDGE /** Sets the GL_Tex_MAG_FILTER for magnifying a texel smaller than a pixel up to one pixel. Valid values are: GL_NEAREST and GL_LINEAR. These are initially set to an intelligent default upon construction and takes this Tex's mipmapping status into account. */ GLint magFilter = GL_LINEAR; /** Sets the GL_Tex_MIN_FILTER for shrinking a texel bigger than a pixel down to one pixel. Valid values are: GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, or GL_LINEAR_MIPMAP_LINEAR. These are initially set to an intelligent default upon construction and takes this Tex's mipmapping status into account. */ GLint minFilter = GL_LINEAR; }; std::ostream& operator <<( std::ostream&, const Tex& ); //actual declaration (not a friend qualifier) } //namespace Aftr