mirror of
https://github.com/edubart/otclient.git
synced 2025-06-07 19:34:29 +02:00
Add texture abstract class
This commit is contained in:
parent
ab9351196c
commit
b3b849000d
@ -26,6 +26,7 @@
|
|||||||
#include <framework/graphics/framebuffermanager.h>
|
#include <framework/graphics/framebuffermanager.h>
|
||||||
#include <framework/graphics/painter.h>
|
#include <framework/graphics/painter.h>
|
||||||
#include <framework/graphics/image.h>
|
#include <framework/graphics/image.h>
|
||||||
|
#include <framework/graphics/ogl/textureogl.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAX_LIGHT_INTENSITY = 8,
|
MAX_LIGHT_INTENSITY = 8,
|
||||||
@ -61,7 +62,7 @@ TexturePtr LightView::generateLightBubble(float centerFactor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TexturePtr tex = TexturePtr(new Texture(lightImage, true));
|
TexturePtr tex = TexturePtr(new TextureOGL(lightImage, true));
|
||||||
tex->setSmooth(true);
|
tex->setSmooth(true);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <framework/graphics/painter.h>
|
#include <framework/graphics/painter.h>
|
||||||
#include <framework/graphics/image.h>
|
#include <framework/graphics/image.h>
|
||||||
#include <framework/graphics/framebuffermanager.h>
|
#include <framework/graphics/framebuffermanager.h>
|
||||||
|
#include <framework/graphics/ogl/textureogl.h>
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <framework/core/filestream.h>
|
#include <framework/core/filestream.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
@ -65,7 +66,7 @@ void MinimapBlock::update()
|
|||||||
|
|
||||||
if(shouldDraw) {
|
if(shouldDraw) {
|
||||||
if(!m_texture) {
|
if(!m_texture) {
|
||||||
m_texture = TexturePtr(new Texture(image, true));
|
m_texture = TexturePtr(new TextureOGL(image, true));
|
||||||
} else {
|
} else {
|
||||||
m_texture->uploadPixels(image, true);
|
m_texture->uploadPixels(image, true);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
#include <framework/graphics/texture.h>
|
#include <framework/graphics/texture.h>
|
||||||
#include <framework/graphics/image.h>
|
#include <framework/graphics/image.h>
|
||||||
|
#include <framework/graphics/ogl/textureogl.h>
|
||||||
#include <framework/graphics/texturemanager.h>
|
#include <framework/graphics/texturemanager.h>
|
||||||
#include <framework/core/filestream.h>
|
#include <framework/core/filestream.h>
|
||||||
#include <framework/otml/otml.h>
|
#include <framework/otml/otml.h>
|
||||||
@ -283,7 +284,7 @@ const TexturePtr& ThingType::getTexture(int animationPhase)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
animationPhaseTexture = TexturePtr(new Texture(fullImage, true));
|
animationPhaseTexture = TexturePtr(new TextureOGL(fullImage, true));
|
||||||
animationPhaseTexture->setSmooth(true);
|
animationPhaseTexture->setSmooth(true);
|
||||||
}
|
}
|
||||||
return animationPhaseTexture;
|
return animationPhaseTexture;
|
||||||
|
@ -459,6 +459,8 @@ if(FRAMEWORK_GRAPHICS)
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.h
|
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.h
|
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/textureogl.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/textureogl.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.h
|
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/vertexarray.h
|
${CMAKE_CURRENT_LIST_DIR}/graphics/vertexarray.h
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <framework/graphics/particlemanager.h>
|
#include <framework/graphics/particlemanager.h>
|
||||||
#include <framework/graphics/texturemanager.h>
|
#include <framework/graphics/texturemanager.h>
|
||||||
#include <framework/graphics/painter.h>
|
#include <framework/graphics/painter.h>
|
||||||
|
#include <framework/graphics/ogl/textureogl.h>
|
||||||
|
|
||||||
#ifdef FW_SOUND
|
#ifdef FW_SOUND
|
||||||
#include <framework/sound/soundmanager.h>
|
#include <framework/sound/soundmanager.h>
|
||||||
@ -232,7 +233,7 @@ void GraphicalApplication::resize(const Size& size)
|
|||||||
m_onInputEvent = false;
|
m_onInputEvent = false;
|
||||||
|
|
||||||
if(g_graphics.canCacheBackbuffer()) {
|
if(g_graphics.canCacheBackbuffer()) {
|
||||||
m_foreground = TexturePtr(new Texture(size));
|
m_foreground = TexturePtr(new TextureOGL(size));
|
||||||
m_foreground->setUpsideDown(true);
|
m_foreground->setUpsideDown(true);
|
||||||
}
|
}
|
||||||
m_mustRepaint = true;
|
m_mustRepaint = true;
|
||||||
|
@ -24,14 +24,15 @@
|
|||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
#include "ogl/textureogl.h"
|
||||||
|
|
||||||
AnimatedTexture::AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps, bool compress)
|
AnimatedTexture::AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps)
|
||||||
{
|
{
|
||||||
if(!setupSize(size, buildMipmaps))
|
if(!setupSize(size, buildMipmaps))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(uint i=0;i<frames.size();++i) {
|
for(uint i=0;i<frames.size();++i) {
|
||||||
m_frames.push_back(new Texture(frames[i], buildMipmaps, compress));
|
m_frames.push_back(new TextureOGL(frames[i], buildMipmaps));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_framesDelay = framesDelay;
|
m_framesDelay = framesDelay;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
class AnimatedTexture : public Texture
|
class AnimatedTexture : public Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps = false, bool compress = false);
|
AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps = false);
|
||||||
virtual ~AnimatedTexture();
|
virtual ~AnimatedTexture();
|
||||||
|
|
||||||
virtual bool buildHardwareMipmaps();
|
virtual bool buildHardwareMipmaps();
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <framework/platform/platformwindow.h>
|
#include <framework/platform/platformwindow.h>
|
||||||
#include <framework/core/application.h>
|
#include <framework/core/application.h>
|
||||||
|
#include <framework/graphics/ogl/textureogl.h>
|
||||||
|
|
||||||
uint FrameBuffer::boundFbo = 0;
|
uint FrameBuffer::boundFbo = 0;
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ void FrameBuffer::resize(const Size& size)
|
|||||||
if(m_texture && m_texture->getSize() == size)
|
if(m_texture && m_texture->getSize() == size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_texture = TexturePtr(new Texture(size));
|
m_texture = TexturePtr(new TextureOGL(size));
|
||||||
m_texture->setSmooth(m_smooth);
|
m_texture->setSmooth(m_smooth);
|
||||||
m_texture->setUpsideDown(true);
|
m_texture->setUpsideDown(true);
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ void FrameBuffer::resize(const Size& size)
|
|||||||
internalRelease();
|
internalRelease();
|
||||||
} else {
|
} else {
|
||||||
if(m_backuping) {
|
if(m_backuping) {
|
||||||
m_screenBackup = TexturePtr(new Texture(size));
|
m_screenBackup = TexturePtr(new TextureOGL(size));
|
||||||
m_screenBackup->setUpsideDown(true);
|
m_screenBackup->setUpsideDown(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
227
src/framework/graphics/ogl/textureogl.cpp
Normal file
227
src/framework/graphics/ogl/textureogl.cpp
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "textureogl.h"
|
||||||
|
#include <framework/graphics/image.h>
|
||||||
|
#include <framework/core/application.h>
|
||||||
|
#include <framework/graphics/graphics.h>
|
||||||
|
|
||||||
|
TextureOGL::TextureOGL()
|
||||||
|
{
|
||||||
|
m_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureOGL::TextureOGL(const Size& size)
|
||||||
|
{
|
||||||
|
m_id = 0;
|
||||||
|
|
||||||
|
if(!setupSize(size))
|
||||||
|
return;
|
||||||
|
|
||||||
|
createTexture();
|
||||||
|
bind();
|
||||||
|
setupPixels(0, m_glSize, nullptr, 4);
|
||||||
|
setupWrap();
|
||||||
|
setupFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureOGL::TextureOGL(const ImagePtr& image, bool buildMipmaps)
|
||||||
|
{
|
||||||
|
m_id = 0;
|
||||||
|
|
||||||
|
if(!setupSize(image->getSize(), buildMipmaps))
|
||||||
|
return;
|
||||||
|
|
||||||
|
createTexture();
|
||||||
|
|
||||||
|
uploadPixels(image, buildMipmaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureOGL::~TextureOGL()
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
assert(!g_app.isTerminated());
|
||||||
|
#endif
|
||||||
|
// free texture from gl memory
|
||||||
|
if(g_graphics.ok() && m_id != 0)
|
||||||
|
glDeleteTextures(1, &m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::uploadPixels(const ImagePtr& image, bool buildMipmaps)
|
||||||
|
{
|
||||||
|
ImagePtr glImage = image;
|
||||||
|
if(m_size != m_glSize) {
|
||||||
|
glImage = ImagePtr(new Image(m_glSize, image->getBpp()));
|
||||||
|
glImage->paste(image);
|
||||||
|
} else
|
||||||
|
glImage = image;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
if(buildMipmaps) {
|
||||||
|
int level = 0;
|
||||||
|
do {
|
||||||
|
setupPixels(level++, glImage->getSize(), glImage->getPixelData(), glImage->getBpp());
|
||||||
|
} while(glImage->nextMipmap());
|
||||||
|
m_hasMipmaps = true;
|
||||||
|
} else
|
||||||
|
setupPixels(0, glImage->getSize(), glImage->getPixelData(), glImage->getBpp());
|
||||||
|
|
||||||
|
setupWrap();
|
||||||
|
setupFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::bind()
|
||||||
|
{
|
||||||
|
// must reset painter texture state
|
||||||
|
g_painter->setTexture(this);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::copyFromScreen(const Rect& screenRect)
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureOGL::buildHardwareMipmaps()
|
||||||
|
{
|
||||||
|
if(!g_graphics.canUseHardwareMipmaps())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
if(!m_hasMipmaps) {
|
||||||
|
m_hasMipmaps = true;
|
||||||
|
setupFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::setSmooth(bool smooth)
|
||||||
|
{
|
||||||
|
if(smooth && !g_graphics.canUseBilinearFiltering())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(smooth == m_smooth)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_smooth = smooth;
|
||||||
|
bind();
|
||||||
|
setupFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::setRepeat(bool repeat)
|
||||||
|
{
|
||||||
|
if(m_repeat == repeat)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_repeat = repeat;
|
||||||
|
bind();
|
||||||
|
setupWrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::setUpsideDown(bool upsideDown)
|
||||||
|
{
|
||||||
|
if(m_upsideDown == upsideDown)
|
||||||
|
return;
|
||||||
|
m_upsideDown = upsideDown;
|
||||||
|
setupTranformMatrix(m_glSize, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::createTexture()
|
||||||
|
{
|
||||||
|
glGenTextures(1, &m_id);
|
||||||
|
assert(m_id != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureOGL::setupSize(const Size& size, bool forcePowerOfTwo)
|
||||||
|
{
|
||||||
|
Size glSize;
|
||||||
|
if(!g_graphics.canUseNonPowerOfTwoTextures() || forcePowerOfTwo)
|
||||||
|
glSize.resize(stdext::to_power_of_two(size.width()), stdext::to_power_of_two(size.height()));
|
||||||
|
else
|
||||||
|
glSize = size;
|
||||||
|
|
||||||
|
// checks texture max size
|
||||||
|
if(std::max(glSize.width(), glSize.height()) > g_graphics.getMaxTextureSize()) {
|
||||||
|
g_logger.error(stdext::format("loading texture with size %dx%d failed, "
|
||||||
|
"the maximum size allowed by the graphics card is %dx%d,"
|
||||||
|
"to prevent crashes the texture will be displayed as a blank texture",
|
||||||
|
size.width(), size.height(), g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size = size;
|
||||||
|
m_glSize = glSize;
|
||||||
|
setupTranformMatrix(m_glSize, m_size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::setupWrap()
|
||||||
|
{
|
||||||
|
int texParam;
|
||||||
|
if(!m_repeat && g_graphics.canUseClampToEdge())
|
||||||
|
texParam = GL_CLAMP_TO_EDGE;
|
||||||
|
else
|
||||||
|
texParam = GL_REPEAT;
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::setupFilters()
|
||||||
|
{
|
||||||
|
int minFilter;
|
||||||
|
int magFilter;
|
||||||
|
if(m_smooth) {
|
||||||
|
minFilter = m_hasMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
|
||||||
|
magFilter = GL_LINEAR;
|
||||||
|
} else {
|
||||||
|
minFilter = m_hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
|
||||||
|
magFilter = GL_NEAREST;
|
||||||
|
}
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureOGL::setupPixels(int level, const Size& size, uchar* pixels, int channels)
|
||||||
|
{
|
||||||
|
GLenum format = 0;
|
||||||
|
switch(channels) {
|
||||||
|
case 4:
|
||||||
|
format = GL_RGBA;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
format = GL_RGB;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
format = GL_LUMINANCE_ALPHA;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
format = GL_LUMINANCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
}
|
54
src/framework/graphics/ogl/textureogl.h
Normal file
54
src/framework/graphics/ogl/textureogl.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TEXTUREOGL_H
|
||||||
|
#define TEXTUREOGL_H
|
||||||
|
|
||||||
|
#include <framework/graphics/texture.h>
|
||||||
|
|
||||||
|
class TextureOGL : public Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureOGL();
|
||||||
|
TextureOGL(const Size& size);
|
||||||
|
TextureOGL(const ImagePtr& image, bool buildMipmaps = false);
|
||||||
|
virtual ~TextureOGL();
|
||||||
|
|
||||||
|
void uploadPixels(const ImagePtr& image, bool buildMipmaps = false);
|
||||||
|
void bind();
|
||||||
|
void copyFromScreen(const Rect& screenRect);
|
||||||
|
virtual bool buildHardwareMipmaps();
|
||||||
|
|
||||||
|
virtual void setSmooth(bool smooth);
|
||||||
|
virtual void setRepeat(bool repeat);
|
||||||
|
void setUpsideDown(bool upsideDown);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void createTexture();
|
||||||
|
bool setupSize(const Size& size, bool forcePowerOfTwo = false);
|
||||||
|
void setupWrap();
|
||||||
|
void setupFilters();
|
||||||
|
void setupPixels(int level, const Size& size, uchar *pixels, int channels = 4);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -33,223 +33,29 @@ Texture::Texture()
|
|||||||
m_time = 0;
|
m_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(const Size& size)
|
|
||||||
{
|
|
||||||
m_id = 0;
|
|
||||||
m_time = 0;
|
|
||||||
|
|
||||||
if(!setupSize(size))
|
|
||||||
return;
|
|
||||||
|
|
||||||
createTexture();
|
|
||||||
bind();
|
|
||||||
setupPixels(0, m_glSize, nullptr, 4);
|
|
||||||
setupWrap();
|
|
||||||
setupFilters();
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::Texture(const ImagePtr& image, bool buildMipmaps, bool compress)
|
|
||||||
{
|
|
||||||
m_id = 0;
|
|
||||||
m_time = 0;
|
|
||||||
|
|
||||||
createTexture();
|
|
||||||
|
|
||||||
uploadPixels(image, buildMipmaps, compress);
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert(!g_app.isTerminated());
|
assert(!g_app.isTerminated());
|
||||||
#endif
|
#endif
|
||||||
// free texture from gl memory
|
|
||||||
if(g_graphics.ok() && m_id != 0)
|
|
||||||
glDeleteTextures(1, &m_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::uploadPixels(const ImagePtr& image, bool buildMipmaps, bool compress)
|
bool Texture::setupSize(const Size& size, bool)
|
||||||
{
|
{
|
||||||
if(!setupSize(image->getSize(), buildMipmaps))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImagePtr glImage = image;
|
|
||||||
if(m_size != m_glSize) {
|
|
||||||
glImage = ImagePtr(new Image(m_glSize, image->getBpp()));
|
|
||||||
glImage->paste(image);
|
|
||||||
} else
|
|
||||||
glImage = image;
|
|
||||||
|
|
||||||
bind();
|
|
||||||
|
|
||||||
if(buildMipmaps) {
|
|
||||||
int level = 0;
|
|
||||||
do {
|
|
||||||
setupPixels(level++, glImage->getSize(), glImage->getPixelData(), glImage->getBpp(), compress);
|
|
||||||
} while(glImage->nextMipmap());
|
|
||||||
m_hasMipmaps = true;
|
|
||||||
} else
|
|
||||||
setupPixels(0, glImage->getSize(), glImage->getPixelData(), glImage->getBpp(), compress);
|
|
||||||
|
|
||||||
setupWrap();
|
|
||||||
setupFilters();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::bind()
|
|
||||||
{
|
|
||||||
// must reset painter texture state
|
|
||||||
g_painter->setTexture(this);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::copyFromScreen(const Rect& screenRect)
|
|
||||||
{
|
|
||||||
bind();
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Texture::buildHardwareMipmaps()
|
|
||||||
{
|
|
||||||
if(!g_graphics.canUseHardwareMipmaps())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bind();
|
|
||||||
|
|
||||||
if(!m_hasMipmaps) {
|
|
||||||
m_hasMipmaps = true;
|
|
||||||
setupFilters();
|
|
||||||
}
|
|
||||||
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::setSmooth(bool smooth)
|
|
||||||
{
|
|
||||||
if(smooth && !g_graphics.canUseBilinearFiltering())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(smooth == m_smooth)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_smooth = smooth;
|
|
||||||
bind();
|
|
||||||
setupFilters();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::setRepeat(bool repeat)
|
|
||||||
{
|
|
||||||
if(m_repeat == repeat)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_repeat = repeat;
|
|
||||||
bind();
|
|
||||||
setupWrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::setUpsideDown(bool upsideDown)
|
|
||||||
{
|
|
||||||
if(m_upsideDown == upsideDown)
|
|
||||||
return;
|
|
||||||
m_upsideDown = upsideDown;
|
|
||||||
setupTranformMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::createTexture()
|
|
||||||
{
|
|
||||||
glGenTextures(1, &m_id);
|
|
||||||
assert(m_id != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Texture::setupSize(const Size& size, bool forcePowerOfTwo)
|
|
||||||
{
|
|
||||||
Size glSize;
|
|
||||||
if(!g_graphics.canUseNonPowerOfTwoTextures() || forcePowerOfTwo)
|
|
||||||
glSize.resize(stdext::to_power_of_two(size.width()), stdext::to_power_of_two(size.height()));
|
|
||||||
else
|
|
||||||
glSize = size;
|
|
||||||
|
|
||||||
// checks texture max size
|
|
||||||
if(std::max(glSize.width(), glSize.height()) > g_graphics.getMaxTextureSize()) {
|
|
||||||
g_logger.error(stdext::format("loading texture with size %dx%d failed, "
|
|
||||||
"the maximum size allowed by the graphics card is %dx%d,"
|
|
||||||
"to prevent crashes the texture will be displayed as a blank texture",
|
|
||||||
size.width(), size.height(), g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_size = size;
|
m_size = size;
|
||||||
m_glSize = glSize;
|
setupTranformMatrix(size, size);
|
||||||
setupTranformMatrix();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setupWrap()
|
void Texture::setupTranformMatrix(const Size& textureSize, const Size& realSize)
|
||||||
{
|
|
||||||
int texParam;
|
|
||||||
if(!m_repeat && g_graphics.canUseClampToEdge())
|
|
||||||
texParam = GL_CLAMP_TO_EDGE;
|
|
||||||
else
|
|
||||||
texParam = GL_REPEAT;
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::setupFilters()
|
|
||||||
{
|
|
||||||
int minFilter;
|
|
||||||
int magFilter;
|
|
||||||
if(m_smooth) {
|
|
||||||
minFilter = m_hasMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
|
|
||||||
magFilter = GL_LINEAR;
|
|
||||||
} else {
|
|
||||||
minFilter = m_hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
|
|
||||||
magFilter = GL_NEAREST;
|
|
||||||
}
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::setupTranformMatrix()
|
|
||||||
{
|
{
|
||||||
if(m_upsideDown) {
|
if(m_upsideDown) {
|
||||||
m_transformMatrix = { 1.0f/m_glSize.width(), 0.0f, 0.0f,
|
m_transformMatrix = { 1.0f/textureSize.width(), 0.0f, 0.0f,
|
||||||
0.0f, -1.0f/m_glSize.height(), 0.0f,
|
0.0f, -1.0f/textureSize.height(), 0.0f,
|
||||||
0.0f, m_size.height()/(float)m_glSize.height(), 1.0f };
|
0.0f, realSize.height()/(float)textureSize.height(), 1.0f };
|
||||||
} else {
|
} else {
|
||||||
m_transformMatrix = { 1.0f/m_glSize.width(), 0.0f, 0.0f,
|
m_transformMatrix = { 1.0f/textureSize.width(), 0.0f, 0.0f,
|
||||||
0.0f, 1.0f/m_glSize.height(), 0.0f,
|
0.0f, 1.0f/textureSize.height(), 0.0f,
|
||||||
0.0f, 0.0f, 1.0f };
|
0.0f, 0.0f, 1.0f };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setupPixels(int level, const Size& size, uchar* pixels, int channels, bool compress)
|
|
||||||
{
|
|
||||||
GLenum format = 0;
|
|
||||||
switch(channels) {
|
|
||||||
case 4:
|
|
||||||
format = GL_RGBA;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
format = GL_RGB;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
format = GL_LUMINANCE_ALPHA;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
format = GL_LUMINANCE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum internalFormat = GL_RGBA;
|
|
||||||
|
|
||||||
#ifdef OPENGL_ES
|
|
||||||
//TODO
|
|
||||||
#else
|
|
||||||
if(compress)
|
|
||||||
internalFormat = GL_COMPRESSED_RGBA;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, level, internalFormat, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
}
|
|
||||||
|
@ -29,26 +29,25 @@ class Texture : public stdext::shared_object
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture();
|
Texture();
|
||||||
Texture(const Size& size);
|
|
||||||
Texture(const ImagePtr& image, bool buildMipmaps = false, bool compress = false);
|
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
void uploadPixels(const ImagePtr& image, bool buildMipmaps = false, bool compress = false);
|
virtual void setSmooth(bool) {}
|
||||||
void bind();
|
virtual void setRepeat(bool) {}
|
||||||
void copyFromScreen(const Rect& screenRect);
|
virtual void setUpsideDown(bool) {}
|
||||||
virtual bool buildHardwareMipmaps();
|
|
||||||
|
virtual bool setupSize(const Size& size, bool);
|
||||||
|
virtual void copyFromScreen(const Rect&) {}
|
||||||
|
virtual bool buildHardwareMipmaps() { return false; }
|
||||||
|
virtual void uploadPixels(const ImagePtr&, bool) {}
|
||||||
|
|
||||||
virtual void setSmooth(bool smooth);
|
|
||||||
virtual void setRepeat(bool repeat);
|
|
||||||
void setUpsideDown(bool upsideDown);
|
|
||||||
void setTime(ticks_t time) { m_time = time; }
|
void setTime(ticks_t time) { m_time = time; }
|
||||||
|
void setupTranformMatrix(const Size& textureSize, const Size& realSize);
|
||||||
|
|
||||||
uint getId() { return m_id; }
|
uint getId() { return m_id; }
|
||||||
ticks_t getTime() { return m_time; }
|
ticks_t getTime() { return m_time; }
|
||||||
int getWidth() { return m_size.width(); }
|
int getWidth() { return m_size.width(); }
|
||||||
int getHeight() { return m_size.height(); }
|
int getHeight() { return m_size.height(); }
|
||||||
const Size& getSize() { return m_size; }
|
const Size& getSize() { return m_size; }
|
||||||
const Size& getGlSize() { return m_glSize; }
|
|
||||||
const Matrix3& getTransformMatrix() { return m_transformMatrix; }
|
const Matrix3& getTransformMatrix() { return m_transformMatrix; }
|
||||||
bool isEmpty() { return m_id == 0; }
|
bool isEmpty() { return m_id == 0; }
|
||||||
bool hasRepeat() { return m_repeat; }
|
bool hasRepeat() { return m_repeat; }
|
||||||
@ -56,13 +55,6 @@ public:
|
|||||||
virtual bool isAnimatedTexture() { return false; }
|
virtual bool isAnimatedTexture() { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void createTexture();
|
|
||||||
bool setupSize(const Size& size, bool forcePowerOfTwo = false);
|
|
||||||
void setupWrap();
|
|
||||||
void setupFilters();
|
|
||||||
void setupTranformMatrix();
|
|
||||||
void setupPixels(int level, const Size& size, uchar *pixels, int channels = 4, bool compress = false);
|
|
||||||
|
|
||||||
uint m_id;
|
uint m_id;
|
||||||
ticks_t m_time;
|
ticks_t m_time;
|
||||||
Size m_size;
|
Size m_size;
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <framework/core/clock.h>
|
#include <framework/core/clock.h>
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
#include <framework/graphics/apngloader.h>
|
#include <framework/graphics/apngloader.h>
|
||||||
|
#include "ogl/textureogl.h"
|
||||||
|
|
||||||
TextureManager g_textures;
|
TextureManager g_textures;
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ TexturePtr TextureManager::loadTexture(std::stringstream& file)
|
|||||||
texture = animatedTexture;
|
texture = animatedTexture;
|
||||||
} else {
|
} else {
|
||||||
ImagePtr image = ImagePtr(new Image(imageSize, apng.bpp, apng.pdata));
|
ImagePtr image = ImagePtr(new Image(imageSize, apng.bpp, apng.pdata));
|
||||||
texture = TexturePtr(new Texture(image));
|
texture = TexturePtr(new TextureOGL(image));
|
||||||
}
|
}
|
||||||
free_apng(&apng);
|
free_apng(&apng);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user