graphics fixes
* zooming without real FBOs kinda works, but with lower quality * hardware detection for glGenerateMipmaps * possibility to disable bilinear filtering, mipmaps, framebuffers, and realtime mipmap generation in g_graphics * otclient works well using 3D acceleration in VirtualBox again * many fixes regarding FBOs fallback implementation
This commit is contained in:
parent
01d5fad315
commit
c7469e4454
|
@ -23,6 +23,7 @@
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
#include <framework/platform/platformwindow.h>
|
||||||
|
|
||||||
uint FrameBuffer::boundFbo = 0;
|
uint FrameBuffer::boundFbo = 0;
|
||||||
std::vector<bool> auxBuffers;
|
std::vector<bool> auxBuffers;
|
||||||
|
@ -42,14 +43,14 @@ FrameBuffer::FrameBuffer(const Size& size)
|
||||||
|
|
||||||
void FrameBuffer::internalCreate()
|
void FrameBuffer::internalCreate()
|
||||||
{
|
{
|
||||||
if(g_graphics.hasFBO()) {
|
if(g_graphics.canUseFBO()) {
|
||||||
glGenFramebuffers(1, &m_fbo);
|
glGenFramebuffers(1, &m_fbo);
|
||||||
if(!m_fbo)
|
if(!m_fbo)
|
||||||
logFatal("Unable to create framebuffer object");
|
logFatal("Unable to create framebuffer object");
|
||||||
} else { // use auxiliar buffers when FBOs are not supported
|
} else { // use auxiliar buffers when FBOs are not supported
|
||||||
m_fbo = 0;
|
m_fbo = 0;
|
||||||
if(auxBuffers.size() == 0) {
|
if(auxBuffers.size() == 0) {
|
||||||
int maxAuxs;
|
int maxAuxs = 0;
|
||||||
glGetIntegerv(GL_AUX_BUFFERS, &maxAuxs);
|
glGetIntegerv(GL_AUX_BUFFERS, &maxAuxs);
|
||||||
auxBuffers.resize(maxAuxs+1, false);
|
auxBuffers.resize(maxAuxs+1, false);
|
||||||
}
|
}
|
||||||
|
@ -57,16 +58,17 @@ void FrameBuffer::internalCreate()
|
||||||
if(auxBuffers[i] == false) {
|
if(auxBuffers[i] == false) {
|
||||||
m_fbo = i;
|
m_fbo = i;
|
||||||
auxBuffers[i] = true;
|
auxBuffers[i] = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!m_fbo)
|
if(!m_fbo)
|
||||||
logFatal("There is no available auxiliar buffer for a new framebuffer");
|
logFatal("There is no available auxiliar buffer for a new framebuffer, total AUXs: ", auxBuffers.size()-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer::~FrameBuffer()
|
FrameBuffer::~FrameBuffer()
|
||||||
{
|
{
|
||||||
if(g_graphics.hasFBO()) {
|
if(g_graphics.canUseFBO()) {
|
||||||
glDeleteFramebuffers(1, &m_fbo);
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
} else {
|
} else {
|
||||||
auxBuffers[m_fbo] = false;
|
auxBuffers[m_fbo] = false;
|
||||||
|
@ -84,7 +86,7 @@ void FrameBuffer::resize(const Size& size)
|
||||||
m_texture = TexturePtr(new Texture(size.width(), size.height(), 4));
|
m_texture = TexturePtr(new Texture(size.width(), size.height(), 4));
|
||||||
m_texture->setSmooth(true);
|
m_texture->setSmooth(true);
|
||||||
|
|
||||||
if(g_graphics.hasFBO()) {
|
if(g_graphics.canUseFBO()) {
|
||||||
internalBind();
|
internalBind();
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
|
||||||
|
|
||||||
|
@ -121,11 +123,6 @@ void FrameBuffer::release()
|
||||||
g_graphics.setViewportSize(m_oldViewportSize);
|
g_graphics.setViewportSize(m_oldViewportSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::generateMipmaps()
|
|
||||||
{
|
|
||||||
m_texture->generateMipmaps();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FrameBuffer::draw(const Rect& dest, const Rect& src)
|
void FrameBuffer::draw(const Rect& dest, const Rect& src)
|
||||||
{
|
{
|
||||||
g_painter.drawTexturedRect(dest, m_texture, src);
|
g_painter.drawTexturedRect(dest, m_texture, src);
|
||||||
|
@ -133,7 +130,10 @@ void FrameBuffer::draw(const Rect& dest, const Rect& src)
|
||||||
|
|
||||||
void FrameBuffer::draw(const Rect& dest)
|
void FrameBuffer::draw(const Rect& dest)
|
||||||
{
|
{
|
||||||
|
if(g_graphics.canUseFBO())
|
||||||
g_painter.drawTexturedRect(dest, m_texture);
|
g_painter.drawTexturedRect(dest, m_texture);
|
||||||
|
else
|
||||||
|
g_painter.drawTexturedRect(dest, m_texture, Rect(0, 0, g_window.getSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::internalBind()
|
void FrameBuffer::internalBind()
|
||||||
|
@ -142,7 +142,7 @@ void FrameBuffer::internalBind()
|
||||||
return;
|
return;
|
||||||
assert(boundFbo != m_fbo);
|
assert(boundFbo != m_fbo);
|
||||||
|
|
||||||
if(g_graphics.hasFBO()) {
|
if(g_graphics.canUseFBO()) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
} else {
|
} else {
|
||||||
int buffer = GL_AUX0 + m_fbo - 1;
|
int buffer = GL_AUX0 + m_fbo - 1;
|
||||||
|
@ -157,11 +157,13 @@ void FrameBuffer::internalBind()
|
||||||
void FrameBuffer::internalRelease()
|
void FrameBuffer::internalRelease()
|
||||||
{
|
{
|
||||||
assert(boundFbo == m_fbo);
|
assert(boundFbo == m_fbo);
|
||||||
if(g_graphics.hasFBO()) {
|
if(g_graphics.canUseFBO()) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_prevBoundFbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_prevBoundFbo);
|
||||||
} else {
|
} else {
|
||||||
m_texture->bind();
|
m_texture->bind();
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_texture->getWidth(), m_texture->getHeight());
|
|
||||||
|
Size size = getSize();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.width(), size.height());
|
||||||
|
|
||||||
int buffer = GL_BACK;
|
int buffer = GL_BACK;
|
||||||
if(m_prevBoundFbo != 0)
|
if(m_prevBoundFbo != 0)
|
||||||
|
@ -172,3 +174,14 @@ void FrameBuffer::internalRelease()
|
||||||
}
|
}
|
||||||
boundFbo = m_prevBoundFbo;
|
boundFbo = m_prevBoundFbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size FrameBuffer::getSize()
|
||||||
|
{
|
||||||
|
if(g_graphics.canUseFBO()) {
|
||||||
|
return m_texture->getSize();
|
||||||
|
} else {
|
||||||
|
// the buffer size is limited by the window size
|
||||||
|
return Size(std::min(m_texture->getWidth(), g_window.getWidth()),
|
||||||
|
std::min(m_texture->getHeight(), g_window.getHeight()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,14 +36,13 @@ public:
|
||||||
void resize(const Size& size);
|
void resize(const Size& size);
|
||||||
void bind(bool clear = true);
|
void bind(bool clear = true);
|
||||||
void release();
|
void release();
|
||||||
void generateMipmaps();
|
|
||||||
void draw(const Rect& dest);
|
void draw(const Rect& dest);
|
||||||
void draw(const Rect& dest, const Rect& src);
|
void draw(const Rect& dest, const Rect& src);
|
||||||
|
|
||||||
void setClearColor(const Color& color) { m_clearColor = color; }
|
void setClearColor(const Color& color) { m_clearColor = color; }
|
||||||
|
|
||||||
TexturePtr getTexture() { return m_texture; }
|
TexturePtr getTexture() { return m_texture; }
|
||||||
const Size& getSize() { return m_texture->getSize(); }
|
Size getSize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void internalCreate();
|
void internalCreate();
|
||||||
|
|
|
@ -30,22 +30,35 @@ Graphics g_graphics;
|
||||||
|
|
||||||
void Graphics::init()
|
void Graphics::init()
|
||||||
{
|
{
|
||||||
|
logInfo("GPU ", glGetString(GL_RENDERER));
|
||||||
|
logInfo("OpenGL ", glGetString(GL_VERSION));
|
||||||
|
|
||||||
#ifndef OPENGL_ES2
|
#ifndef OPENGL_ES2
|
||||||
// init GL extensions
|
// init GL extensions
|
||||||
GLenum err = glewInit();
|
GLenum err = glewInit();
|
||||||
if(err != GLEW_OK)
|
if(err != GLEW_OK)
|
||||||
logFatal("Unable to init GLEW: ", glewGetErrorString(err));
|
logFatal("Unable to init GLEW: ", glewGetErrorString(err));
|
||||||
|
|
||||||
if(!GLEW_ARB_vertex_program || !GLEW_ARB_vertex_shader ||
|
if(!GLEW_ARB_vertex_program || !GLEW_ARB_vertex_shader ||
|
||||||
!GLEW_ARB_fragment_program || !GLEW_ARB_fragment_shader ||
|
!GLEW_ARB_fragment_program || !GLEW_ARB_fragment_shader ||
|
||||||
!GLEW_ARB_texture_non_power_of_two || !GLEW_ARB_multitexture)
|
!GLEW_ARB_texture_non_power_of_two || !GLEW_ARB_multitexture)
|
||||||
logFatal("Some OpenGL 2.0 extensions is not supported by your system graphics, please try updating your video drivers or buy a new hardware.");
|
logFatal("Some OpenGL 2.0 extensions is not supported by your system graphics, please try updating your video drivers or buy a new hardware.");
|
||||||
|
|
||||||
|
m_useFBO = GLEW_ARB_framebuffer_object;
|
||||||
|
m_useBilinearFiltering = true;
|
||||||
|
m_generateMipmaps = true;
|
||||||
|
m_generateHardwareMipmaps = m_useFBO; // glGenerateMipmap is supported when FBO is
|
||||||
|
m_generateRealtimeMipmaps = m_generateHardwareMipmaps;
|
||||||
|
#else
|
||||||
|
m_useFBO = true; // FBOs is always supported by mobile devices
|
||||||
|
m_useBilinearFiltering = true;
|
||||||
|
m_generateMipmaps = true;
|
||||||
|
m_generateHardwareMipmaps = true;
|
||||||
|
m_realtimeMipmapGeneration = false; // realtime mipmaps can be slow on mobile devices
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
logInfo("GPU ", glGetString(GL_RENDERER));
|
|
||||||
logInfo("OpenGL ", glGetString(GL_VERSION));
|
|
||||||
|
|
||||||
m_emptyTexture = TexturePtr(new Texture);
|
m_emptyTexture = TexturePtr(new Texture);
|
||||||
|
|
||||||
g_painter.init();
|
g_painter.init();
|
||||||
|
@ -58,15 +71,6 @@ void Graphics::terminate()
|
||||||
m_emptyTexture.reset();
|
m_emptyTexture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::hasFBO()
|
|
||||||
{
|
|
||||||
#ifndef OPENGL_ES2
|
|
||||||
return GLEW_ARB_framebuffer_object;
|
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::resize(const Size& size)
|
void Graphics::resize(const Size& size)
|
||||||
{
|
{
|
||||||
setViewportSize(size);
|
setViewportSize(size);
|
||||||
|
|
|
@ -32,7 +32,11 @@ public:
|
||||||
void init();
|
void init();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
bool hasFBO();
|
bool canUseFBO() { return m_useFBO; }
|
||||||
|
bool canUseBilinearFiltering() { return m_useBilinearFiltering; }
|
||||||
|
bool canGenerateMipmaps() { return m_generateMipmaps; }
|
||||||
|
bool canGenerateHardwareMipmaps() { return m_generateHardwareMipmaps; }
|
||||||
|
bool canGenerateRealtimeMipmaps() { return m_generateRealtimeMipmaps; }
|
||||||
|
|
||||||
void resize(const Size& size);
|
void resize(const Size& size);
|
||||||
void beginRender();
|
void beginRender();
|
||||||
|
@ -47,6 +51,12 @@ public:
|
||||||
private:
|
private:
|
||||||
Size m_viewportSize;
|
Size m_viewportSize;
|
||||||
TexturePtr m_emptyTexture;
|
TexturePtr m_emptyTexture;
|
||||||
|
|
||||||
|
Boolean<false> m_useFBO;
|
||||||
|
Boolean<false> m_useBilinearFiltering;
|
||||||
|
Boolean<false> m_generateMipmaps;
|
||||||
|
Boolean<false> m_generateHardwareMipmaps;
|
||||||
|
Boolean<false> m_generateRealtimeMipmaps;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Graphics g_graphics;
|
extern Graphics g_graphics;
|
||||||
|
|
|
@ -99,6 +99,19 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
||||||
|
|
||||||
void Texture::generateMipmaps()
|
void Texture::generateMipmaps()
|
||||||
{
|
{
|
||||||
|
if(g_graphics.canGenerateHardwareMipmaps())
|
||||||
|
generateHardwareMipmaps();
|
||||||
|
else {
|
||||||
|
// fallback to software mipmaps generation, this can be slow
|
||||||
|
generateSoftwareMipmaps(getPixels());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::generateHardwareMipmaps()
|
||||||
|
{
|
||||||
|
if(!g_graphics.canGenerateHardwareMipmaps())
|
||||||
|
return;
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
if(!m_hasMipmaps) {
|
if(!m_hasMipmaps) {
|
||||||
|
@ -111,6 +124,9 @@ void Texture::generateMipmaps()
|
||||||
|
|
||||||
void Texture::setSmooth(bool smooth)
|
void Texture::setSmooth(bool smooth)
|
||||||
{
|
{
|
||||||
|
if(smooth && !g_graphics.canUseBilinearFiltering())
|
||||||
|
return;
|
||||||
|
|
||||||
if(smooth == m_smooth)
|
if(smooth == m_smooth)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -140,7 +156,7 @@ std::vector<uint8> Texture::getPixels()
|
||||||
return pixels;
|
return pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::generateBilinearMipmaps(std::vector<uint8> inPixels)
|
void Texture::generateSoftwareMipmaps(std::vector<uint8> inPixels)
|
||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
|
@ -155,6 +171,7 @@ void Texture::generateBilinearMipmaps(std::vector<uint8> inPixels)
|
||||||
|
|
||||||
int mipmap = 1;
|
int mipmap = 1;
|
||||||
while(true) {
|
while(true) {
|
||||||
|
// this is a simple bilinear filtering algorithm, it combines every 4 pixels in one pixel
|
||||||
for(int x=0;x<outSize.width();++x) {
|
for(int x=0;x<outSize.width();++x) {
|
||||||
for(int y=0;y<outSize.height();++y) {
|
for(int y=0;y<outSize.height();++y) {
|
||||||
uint8 *inPixel[4];
|
uint8 *inPixel[4];
|
||||||
|
@ -180,13 +197,13 @@ void Texture::generateBilinearMipmaps(std::vector<uint8> inPixels)
|
||||||
usedPixels++;
|
usedPixels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try to guess the alpha pixel more accurately
|
||||||
for(int i=0;i<4;++i) {
|
for(int i=0;i<4;++i) {
|
||||||
if(usedPixels > 0)
|
if(usedPixels > 0)
|
||||||
outPixel[i] = pixelsSum[i] / usedPixels;
|
outPixel[i] = pixelsSum[i] / usedPixels;
|
||||||
else
|
else
|
||||||
outPixel[i] = 0;
|
outPixel[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
outPixel[3] = pixelsSum[3]/4;
|
outPixel[3] = pixelsSum[3]/4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,14 @@ public:
|
||||||
|
|
||||||
void bind() { glBindTexture(GL_TEXTURE_2D, m_textureId); }
|
void bind() { glBindTexture(GL_TEXTURE_2D, m_textureId); }
|
||||||
|
|
||||||
|
/// Tries to generate mipmaps via hardware, otherwise fallback to software implementation
|
||||||
void generateMipmaps();
|
void generateMipmaps();
|
||||||
|
/// Generate mipmaps via hardware
|
||||||
|
void generateHardwareMipmaps();
|
||||||
|
/// Generate mipmaps via software, which has a special algorithm for combining alpha pixels
|
||||||
|
void generateSoftwareMipmaps(std::vector<uint8> inPixels);
|
||||||
|
|
||||||
// generate bilinear mipmaps optimized for alpha textures
|
/// Activate texture altialising
|
||||||
void generateBilinearMipmaps(std::vector<uint8> inPixels);
|
|
||||||
|
|
||||||
void setSmooth(bool smooth);
|
void setSmooth(bool smooth);
|
||||||
GLuint getId() { return m_textureId; }
|
GLuint getId() { return m_textureId; }
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ X11Window::X11Window()
|
||||||
m_xic = 0;
|
m_xic = 0;
|
||||||
m_screen = 0;
|
m_screen = 0;
|
||||||
m_wmDelete = 0;
|
m_wmDelete = 0;
|
||||||
m_size = Size(16,16);
|
m_size = Size(600,480);
|
||||||
|
|
||||||
#ifndef OPENGL_ES2
|
#ifndef OPENGL_ES2
|
||||||
m_glxContext = 0;
|
m_glxContext = 0;
|
||||||
|
@ -203,7 +203,6 @@ X11Window::X11Window()
|
||||||
|
|
||||||
void X11Window::init()
|
void X11Window::init()
|
||||||
{
|
{
|
||||||
m_size = Size(200, 200);
|
|
||||||
internalOpenDisplay();
|
internalOpenDisplay();
|
||||||
internalCheckGL();
|
internalCheckGL();
|
||||||
internalChooseGLVisual();
|
internalChooseGLVisual();
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <framework/graphics/painter.h>
|
#include <framework/graphics/painter.h>
|
||||||
#include <framework/graphics/texture.h>
|
#include <framework/graphics/texture.h>
|
||||||
#include <framework/graphics/texturemanager.h>
|
#include <framework/graphics/texturemanager.h>
|
||||||
|
#include <framework/graphics/graphics.h>
|
||||||
|
|
||||||
void UIWidget::initImage()
|
void UIWidget::initImage()
|
||||||
{
|
{
|
||||||
|
@ -167,7 +168,7 @@ void UIWidget::drawImage(const Rect& screenCoords)
|
||||||
m_imageTexture->setSmooth(m_imageSmooth);
|
m_imageTexture->setSmooth(m_imageSmooth);
|
||||||
|
|
||||||
// this will increase fps when rendering larger images, like the background, and improve image quality
|
// this will increase fps when rendering larger images, like the background, and improve image quality
|
||||||
if(m_imageSmooth && !m_imageTexture->hasMipmaps())
|
if(m_imageSmooth && g_graphics.canGenerateMipmaps() && !m_imageTexture->hasMipmaps())
|
||||||
m_imageTexture->generateMipmaps();
|
m_imageTexture->generateMipmaps();
|
||||||
|
|
||||||
g_painter.setColor(m_imageColor);
|
g_painter.setColor(m_imageColor);
|
||||||
|
|
|
@ -57,7 +57,8 @@ void UIWidget::drawText(const Rect& screenCoords)
|
||||||
m_textCachedScreenCoords = screenCoords;
|
m_textCachedScreenCoords = screenCoords;
|
||||||
|
|
||||||
m_textCoordsBuffer.clear();
|
m_textCoordsBuffer.clear();
|
||||||
m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_text, screenCoords, m_textAlign);
|
|
||||||
|
m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_text, screenCoords.translated(m_textOffset), m_textAlign);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_painter.setColor(m_color);
|
g_painter.setColor(m_color);
|
||||||
|
|
|
@ -99,9 +99,13 @@ void MapView::draw(const Rect& rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_framebuffer->generateMipmaps();
|
|
||||||
m_framebuffer->release();
|
m_framebuffer->release();
|
||||||
|
|
||||||
|
// generating mipmaps each frame can be slow in older cards
|
||||||
|
if(g_graphics.canGenerateRealtimeMipmaps())
|
||||||
|
m_framebuffer->getTexture()->generateHardwareMipmaps();
|
||||||
|
|
||||||
m_mustDrawVisibleTilesCache = false;
|
m_mustDrawVisibleTilesCache = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +261,7 @@ void MapView::updateVisibleTilesCache(int start)
|
||||||
} else {
|
} else {
|
||||||
static std::vector<Point> points;
|
static std::vector<Point> points;
|
||||||
points.clear();
|
points.clear();
|
||||||
assert(m_drawDimension.width() % 2 == 0 && m_drawDimension.height() % 2 == 0);
|
//assert(m_drawDimension.width() % 2 == 0 && m_drawDimension.height() % 2 == 0);
|
||||||
Point quadTopLeft(m_drawDimension.width()/2 - 1, m_drawDimension.height()/2 - 1);
|
Point quadTopLeft(m_drawDimension.width()/2 - 1, m_drawDimension.height()/2 - 1);
|
||||||
for(int step = 1; !(quadTopLeft.x < 0 && quadTopLeft.y < 0) && !stop; ++step) {
|
for(int step = 1; !(quadTopLeft.x < 0 && quadTopLeft.y < 0) && !stop; ++step) {
|
||||||
int quadWidth = std::min(2*step, m_drawDimension.width());
|
int quadWidth = std::min(2*step, m_drawDimension.width());
|
||||||
|
@ -404,12 +408,14 @@ void MapView::setVisibleDimension(const Size& visibleDimension)
|
||||||
int possiblesTileSizes[] = {32,16,8,4,2,1};
|
int possiblesTileSizes[] = {32,16,8,4,2,1};
|
||||||
int tileSize = 0;
|
int tileSize = 0;
|
||||||
Size drawDimension = visibleDimension + Size(3,3);
|
Size drawDimension = visibleDimension + Size(3,3);
|
||||||
|
Size framebufferSize = m_framebuffer->getSize();
|
||||||
for(int candidateTileSize : possiblesTileSizes) {
|
for(int candidateTileSize : possiblesTileSizes) {
|
||||||
Size candidateDrawSize = drawDimension * candidateTileSize;
|
Size candidateDrawSize = drawDimension * candidateTileSize;
|
||||||
|
|
||||||
// found a valid size
|
// found a valid size
|
||||||
if(candidateDrawSize <= m_framebuffer->getSize()) {
|
if(candidateDrawSize.width() <= framebufferSize.width() && candidateDrawSize.height() <= framebufferSize.height()) {
|
||||||
tileSize = candidateTileSize;
|
tileSize = candidateTileSize;
|
||||||
|
dump << candidateDrawSize << m_framebuffer->getSize() << tileSize;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,10 @@ TexturePtr SpriteManager::loadSpriteTexture(int id)
|
||||||
|
|
||||||
TexturePtr spriteTex(new Texture(32, 32, 4, &pixels[0]));
|
TexturePtr spriteTex(new Texture(32, 32, 4, &pixels[0]));
|
||||||
spriteTex->setSmooth(true);
|
spriteTex->setSmooth(true);
|
||||||
spriteTex->generateBilinearMipmaps(pixels);
|
|
||||||
|
if(g_graphics.canGenerateMipmaps())
|
||||||
|
spriteTex->generateSoftwareMipmaps(pixels);
|
||||||
|
|
||||||
return spriteTex;
|
return spriteTex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue