introduce matrix class and use it

This commit is contained in:
Eduardo Bart 2011-12-24 21:14:12 -02:00
parent 339697fce9
commit 3abbf5255e
22 changed files with 366 additions and 317 deletions

View File

@ -199,16 +199,13 @@ void Application::exit()
void Application::poll()
{
// poll input events
if(m_appFlags & Fw::AppEnableGraphics)
if(m_appFlags & Fw::AppEnableGraphics) {
g_window.poll();
g_particleManager.update();
}
// poll network events
Connection::poll();
// poll application genareted events
g_dispatcher.poll();
g_particleManager.update();
}
void Application::render()
@ -221,8 +218,8 @@ void Application::render()
void Application::resize(const Size& size)
{
g_ui.resize(size);
g_graphics.resize(size);
g_ui.resize(size);
}
void Application::inputEvent(const InputEvent& event)

View File

@ -36,6 +36,7 @@
#include "util/color.h"
#include "util/rect.h"
#include "util/size.h"
#include "util/matrix.h"
// logger
#include "core/logger.h"

View File

@ -40,8 +40,8 @@ public:
void cacheVertexArrays();
GLfloat *getVertices() const { return m_vertices.vertices(); }
GLfloat *getTextureCoords() const { return m_textureCoords.vertices(); }
float *getVertices() const { return m_vertices.vertices(); }
float *getTextureCoords() const { return m_textureCoords.vertices(); }
int getVertexCount() const { return m_vertices.vertexCount(); }
int getTextureCoordsCount() const { return m_textureCoords.vertexCount(); }

View File

@ -24,28 +24,15 @@
#include "graphics.h"
#include "texture.h"
FrameBuffer::FrameBuffer(int width, int height)
{
// create FBO texture
m_texture = TexturePtr(new Texture(width, height, 4));
m_texture->enableBilinearFilter();
uint FrameBuffer::boundFbo = 0;
// generate FBO
FrameBuffer::FrameBuffer(const Size& size)
{
glGenFramebuffers(1, &m_fbo);
if(!m_fbo)
logFatal("Unable to create framebuffer object");
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
// attach 2D texture to this FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
logFatal("Unable to create framebuffer object");
// restore back buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
resize(size);
}
FrameBuffer::~FrameBuffer()
@ -53,25 +40,60 @@ FrameBuffer::~FrameBuffer()
glDeleteFramebuffers(1, &m_fbo);
}
void FrameBuffer::bind()
void FrameBuffer::resize(const Size& size)
{
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, m_texture->getWidth(), m_texture->getHeight());
g_painter.updateProjectionMatrix(m_texture->getSize(), true);
internalBind();
m_texture = TexturePtr(new Texture(size.width(), size.height(), 4));
m_texture->enableBilinearFilter();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
logFatal("Unable to setup framebuffer object");
internalRelease();
}
void FrameBuffer::bind(bool clear)
{
internalBind();
Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f,
0.0f, 2.0f/m_texture->getHeight(), 0.0f,
-1.0f, -1.0f, 0.0f };
m_oldProjectionMatrix = g_painter.getProjectionMatrix();
m_oldViewportSize = g_graphics.getViewportSize();
g_painter.setProjectionMatrix(projectionMatrix);
g_graphics.setViewportSize(m_texture->getSize());
if(clear)
glClear(GL_COLOR_BUFFER_BIT);
}
void FrameBuffer::release()
{
// bind back buffer again
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// restore graphics viewport
glViewport(0, 0, g_graphics.getViewportSize().width(), g_graphics.getViewportSize().height());
g_painter.updateProjectionMatrix(g_graphics.getViewportSize());
internalRelease();
g_painter.setProjectionMatrix(m_oldProjectionMatrix);
g_graphics.setViewportSize(m_oldViewportSize);
}
void FrameBuffer::draw(const Rect& dest)
{
g_painter.drawTexturedRect(dest, m_texture);
}
void FrameBuffer::internalBind()
{
if(boundFbo == m_fbo)
return;
assert(boundFbo != m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
m_prevBoundFbo = boundFbo;
boundFbo = m_fbo;
}
void FrameBuffer::internalRelease()
{
assert(boundFbo == m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_prevBoundFbo);
boundFbo = m_prevBoundFbo;
}

View File

@ -28,20 +28,28 @@
class FrameBuffer
{
public:
FrameBuffer(int width, int height);
FrameBuffer(const Size& size);
virtual ~FrameBuffer();
void bind();
void resize(const Size& size);
void bind(bool clear = true);
void release();
void draw(const Rect& dest);
TexturePtr getTexture() { return m_texture; }
private:
void internalBind();
void internalRelease();
TexturePtr m_texture;
TexturePtr m_screenBackup;
Matrix3 m_oldProjectionMatrix;
Size m_oldViewportSize;
uint m_fbo;
bool m_fallbackOldImp;
uint m_prevBoundFbo;
static uint boundFbo;
};
#endif

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2010-2011 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 "glbuffer.h"
GLBuffer::GLBuffer()
{
glGenBuffers(1, &m_id);
if(!m_id)
logFatal("Unable to create a simple GL buffer");
}
void GLBuffer::bind()
{
gl
}
void GLBuffer::release()
{
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2010-2011 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 GLBUFFER_H
#define GLBUFFER_H
#include "declarations.h"
class GLBuffer
{
public:
GLBuffer();
~GLBuffer();
void write(const
void bind();
void release();
GLuint bufferId();
private:
GLuint m_id;
};
#endif

View File

@ -24,21 +24,18 @@
#include <framework/graphics/graphics.h>
#include <framework/graphics/texture.h>
#include <framework/platform/platformwindow.h>
Graphics g_graphics;
void Graphics::init()
{
// setup opengl
glEnable(GL_BLEND);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
logInfo("GPU ", glGetString(GL_RENDERER));
logInfo("OpenGL ", glGetString(GL_VERSION));
//if(!isExtensionSupported("GL_ARB_framebuffer_object"))
// logFatal("Your graphics card is not supported.");
m_emptyTexture = TexturePtr(new Texture);
g_painter.init();
@ -60,9 +57,26 @@ bool Graphics::isExtensionSupported(const char *extension)
void Graphics::resize(const Size& size)
{
glViewport(0, 0, size.width(), size.height());
g_painter.updateProjectionMatrix(size);
m_viewportSize = size;
setViewportSize(size);
// The projection matrix converts from Painter's coordinate system to GL's coordinate system
// * GL's viewport is 2x2, Painter's is width x height
// * GL has +y -> -y going from bottom -> top, Painter is the other way round
// * GL has [0,0] in the center, Painter has it in the top-left
//
// This results in the Projection matrix below.
//
// Projection Matrix Painter Coord GL Coord
// ------------------------------------------------ --------- ---------
// | 2.0 / width | 0.0 | -1.0 | | x | | x' |
// | 0.0 | -2.0 / height | 1.0 | * | y | = | y' |
// | 0.0 | 0.0 | 0.0 | | 1 | | 0 |
// ------------------------------------------------ --------- ---------
Matrix3 projectionMatrix = { 2.0f/size.width(), 0.0f, -1.0f,
0.0f, -2.0f/size.height(), 1.0f,
0.0f, 0.0f, 0.0f };
projectionMatrix.transpose();
g_painter.setProjectionMatrix(projectionMatrix);
}
void Graphics::beginRender()
@ -74,3 +88,9 @@ void Graphics::endRender()
{
}
void Graphics::setViewportSize(const Size& size)
{
glViewport(0, 0, size.width(), size.height());
m_viewportSize = size;
}

View File

@ -38,7 +38,9 @@ public:
void beginRender();
void endRender();
const Size& getViewportSize() const { return m_viewportSize; }
void setViewportSize(const Size& size);
const Size& getViewportSize() { return m_viewportSize; }
TexturePtr getEmptyTexture() { return m_emptyTexture; }
private:

View File

@ -53,35 +53,6 @@ void Painter::terminate()
m_drawSolidColorProgram.reset();
}
void Painter::updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis)
{
// The projection matrix converts from Painter's coordinate system to GL's coordinate system
// * GL's viewport is 2x2, Painter's is width x height
// * GL has +y -> -y going from bottom -> top, Painter is the other way round
// * GL has [0,0] in the center, Painter has it in the top-left
//
// This results in the Projection matrix below, which is multiplied by the painter's
// transformation matrix, as shown below:
//
// Projection Matrix Painter Coord GL Coord
// ------------------------------------------------ --------- ---------
// | 2.0 / width | 0.0 | -1.0 | | x | | y' |
// | 0.0 | -2.0 / height | 1.0 | * | y | = | x' |
// | 0.0 | 0.0 | 0.0 | | 1 | | 0 |
// ------------------------------------------------ --------- ---------
float w = viewportSize.width();
float h = viewportSize.height();
if(inverseYAxis) {
m_projectionMatrix[0][0] = 2.0f/w; m_projectionMatrix[0][1] = 0.0f; m_projectionMatrix[0][2] =-1.0f;
m_projectionMatrix[1][0] = 0.0f; m_projectionMatrix[1][1] = 2.0f/h; m_projectionMatrix[1][2] =-1.0f;
m_projectionMatrix[2][0] = 0.0f; m_projectionMatrix[2][1] = 0.0f; m_projectionMatrix[2][2] = 0.0f;
} else {
m_projectionMatrix[0][0] = 2.0f/w; m_projectionMatrix[0][1] = 0.0f; m_projectionMatrix[0][2] =-1.0f;
m_projectionMatrix[1][0] = 0.0f; m_projectionMatrix[1][1] =-2.0f/h; m_projectionMatrix[1][2] = 1.0f;
m_projectionMatrix[2][0] = 0.0f; m_projectionMatrix[2][1] = 0.0f; m_projectionMatrix[2][2] = 0.0f;
}
}
void Painter::drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode)
{
coordsBuffer.cacheVertexArrays();

View File

@ -40,8 +40,6 @@ public:
void init();
void terminate();
void updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis = false);
void drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode = PainterShaderProgram::Triangles);
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
void drawTexturedRect(const Rect& dest, const TexturePtr& texture);
@ -59,16 +57,17 @@ public:
void setCustomProgram(PainterShaderProgramPtr program);
void releaseCustomProgram() { m_customProgram = nullptr; }
void setCompositionMode(CompositionMode compositionMode);
GLfloat *getProjectionMatrix() { return (GLfloat*)m_projectionMatrix; }
void setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; }
Matrix3 getProjectionMatrix() { return m_projectionMatrix; }
private:
PainterShaderProgramPtr m_drawTexturedProgram;
PainterShaderProgramPtr m_drawSolidColorProgram;
PainterShaderProgramPtr m_customProgram;
GLfloat m_projectionMatrix[3][3];
Matrix3 m_projectionMatrix;
Color m_currentColor;
GLfloat m_currentOpacity;
float m_currentOpacity;
CoordsBuffer m_coordsBuffer;
};

View File

@ -42,10 +42,10 @@ bool PainterShaderProgram::link()
return false;
}
void PainterShaderProgram::setProjectionMatrix(float projectionMatrix[3][3])
void PainterShaderProgram::setProjectionMatrix(const Matrix3& projectionMatrix)
{
bind();
setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix, true);
setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix);
}
void PainterShaderProgram::setColor(const Color& color)
@ -54,7 +54,7 @@ void PainterShaderProgram::setColor(const Color& color)
setUniformValue(COLOR_UNIFORM, color);
}
void PainterShaderProgram::setOpacity(GLfloat opacity)
void PainterShaderProgram::setOpacity(float opacity)
{
bind();
setUniformValue(OPACITY_UNIFORM, opacity);
@ -74,24 +74,23 @@ void PainterShaderProgram::setTexture(const TexturePtr& texture)
if(!texture)
return;
float w = texture->getGlSize().width();
float h = texture->getGlSize().height();
float w = texture->getWidth();
float h = texture->getHeight();
GLfloat textureTransformMatrix[2][2] = {
{ 1.0f/w, 0.0f },
{ 0.0f, 1.0f/h }
};
Matrix2 textureTransformMatrix = { 1.0f/w, 0.0f,
0.0f, 1.0f/h };
textureTransformMatrix.transpose();
bind();
setUniformTexture(TEXTURE_UNIFORM, texture, 0);
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix, true);
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix);
}
void PainterShaderProgram::draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode)
{
assert(bind());
setUniformValue(TICKS_UNIFORM, (GLfloat)g_clock.ticks());
setUniformValue(TICKS_UNIFORM, (float)g_clock.ticks());
int numVertices = coordsBuffer.getVertexCount();
if(numVertices == 0)

View File

@ -46,9 +46,9 @@ public:
bool link();
void setProjectionMatrix(GLfloat projectionMatrix[3][3]);
void setProjectionMatrix(const Matrix3& projectionMatrix);
void setColor(const Color& color);
void setOpacity(GLfloat opacity);
void setOpacity(float opacity);
void setTexture(const TexturePtr& texture);
void setUniformTexture(int location, const TexturePtr& texture, int index);
void draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);

View File

@ -53,31 +53,31 @@ public:
void bindAttributeLocation(int location, const char *name);
void bindUniformLocation(int location, const char *name);
void setAttributeArray(int location, const GLfloat *values, int size, int stride = 0) { glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, stride, values); }
void setAttributeValue(int location, GLfloat value) { glVertexAttrib1f(location, value); }
void setAttributeValue(int location, GLfloat x, GLfloat y) { glVertexAttrib2f(location, x, y); }
void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z) { glVertexAttrib3f(location, x, y, z); }
void setAttributeArray(const char *name, const GLfloat *values, int size, int stride = 0) { glVertexAttribPointer(getAttributeLocation(name), size, GL_FLOAT, GL_FALSE, stride, values); }
void setAttributeValue(const char *name, GLfloat value) { glVertexAttrib1f(getAttributeLocation(name), value); }
void setAttributeValue(const char *name, GLfloat x, GLfloat y) { glVertexAttrib2f(getAttributeLocation(name), x, y); }
void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z) { glVertexAttrib3f(getAttributeLocation(name), x, y, z); }
void setAttributeArray(int location, const float *values, int size, int stride = 0) { glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, stride, values); }
void setAttributeValue(int location, float value) { glVertexAttrib1f(location, value); }
void setAttributeValue(int location, float x, float y) { glVertexAttrib2f(location, x, y); }
void setAttributeValue(int location, float x, float y, float z) { glVertexAttrib3f(location, x, y, z); }
void setAttributeArray(const char *name, const float *values, int size, int stride = 0) { glVertexAttribPointer(getAttributeLocation(name), size, GL_FLOAT, GL_FALSE, stride, values); }
void setAttributeValue(const char *name, float value) { glVertexAttrib1f(getAttributeLocation(name), value); }
void setAttributeValue(const char *name, float x, float y) { glVertexAttrib2f(getAttributeLocation(name), x, y); }
void setAttributeValue(const char *name, float x, float y, float z) { glVertexAttrib3f(getAttributeLocation(name), x, y, z); }
void setUniformValue(int location, const Color& color) { glUniform4f(m_uniformLocations[location], color.r() / 255.0f, color.g() / 255.0f, color.b() / 255.0f, color.a() / 255.0f); }
void setUniformValue(int location, GLint value) { glUniform1i(m_uniformLocations[location], value); }
void setUniformValue(int location, GLfloat value) { glUniform1f(m_uniformLocations[location], value); }
void setUniformValue(int location, GLfloat x, GLfloat y) { glUniform2f(m_uniformLocations[location], x, y); }
void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z) { glUniform3f(m_uniformLocations[location], x, y, z); }
void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { glUniform4f(m_uniformLocations[location], x, y, z, w); }
void setUniformValue(int location, GLfloat mat2[2][2], bool transpose) { glUniformMatrix2fv(m_uniformLocations[location], 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat2); }
void setUniformValue(int location, GLfloat mat3[3][3], bool transpose) { glUniformMatrix3fv(m_uniformLocations[location], 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat3); }
void setUniformValue(int location, float value) { glUniform1f(m_uniformLocations[location], value); }
void setUniformValue(int location, float x, float y) { glUniform2f(m_uniformLocations[location], x, y); }
void setUniformValue(int location, float x, float y, float z) { glUniform3f(m_uniformLocations[location], x, y, z); }
void setUniformValue(int location, float x, float y, float z, float w) { glUniform4f(m_uniformLocations[location], x, y, z, w); }
void setUniformValue(int location, const Matrix2& mat) { glUniformMatrix2fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); }
void setUniformValue(int location, const Matrix3& mat) { glUniformMatrix3fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); }
void setUniformValue(const char *name, const Color& color) { glUniform4f(glGetUniformLocation(m_programId, name), color.r() / 255.0f, color.g() / 255.0f, color.b() / 255.0f, color.a() / 255.0f); }
void setUniformValue(const char *name, GLint value) { glUniform1i(glGetUniformLocation(m_programId, name), value); }
void setUniformValue(const char *name, GLfloat value) { glUniform1f(glGetUniformLocation(m_programId, name), value); }
void setUniformValue(const char *name, GLfloat x, GLfloat y) { glUniform2f(glGetUniformLocation(m_programId, name), x, y); }
void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z) { glUniform3f(glGetUniformLocation(m_programId, name), x, y, z); }
void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { glUniform4f(glGetUniformLocation(m_programId, name), x, y, z, w); }
void setUniformValue(const char *name, GLfloat mat2[2][2], bool transpose = false) { glUniformMatrix2fv(glGetUniformLocation(m_programId, name), 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat2); }
void setUniformValue(const char *name, GLfloat mat3[3][3], bool transpose = false) { glUniformMatrix3fv(glGetUniformLocation(m_programId, name), 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat3); }
void setUniformValue(const char *name, float value) { glUniform1f(glGetUniformLocation(m_programId, name), value); }
void setUniformValue(const char *name, float x, float y) { glUniform2f(glGetUniformLocation(m_programId, name), x, y); }
void setUniformValue(const char *name, float x, float y, float z) { glUniform3f(glGetUniformLocation(m_programId, name), x, y, z); }
void setUniformValue(const char *name, float x, float y, float z, float w) { glUniform4f(glGetUniformLocation(m_programId, name), x, y, z, w); }
void setUniformValue(const char *name, const Matrix2& mat) { glUniformMatrix2fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); }
void setUniformValue(const char *name, const Matrix3& mat) { glUniformMatrix3fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); }
// Point, PointF, Color, Size, SizeF,
bool isLinked() { return m_linked; }

View File

@ -22,6 +22,7 @@
#include "texture.h"
#include "graphics.h"
#include "framebuffer.h"
Texture::Texture()
{
@ -64,32 +65,6 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
std::vector<uint8> tmp;
// old opengl drivers only accept power of two dimensions
/*
if(!g_painter.isExtensionSupported("GL_ARB_texture_non_power_of_two")) {
int glWidth = 1;
while(glWidth < width)
glWidth = glWidth << 1;
int glHeight = 1;
while(glHeight < height)
glHeight = glHeight << 1;
if(m_size != m_glSize && pixels) {
tmp.resize(glHeight*glWidth*channels, 0);
for(int y=0; y<height; ++y)
for(int x=0; x<width; ++x)
for(int i=0; i<channels; ++i)
tmp[y*glWidth*channels+x*channels+i] = pixels[y*width*channels+x*channels+i];
pixels = &tmp[0];
}
m_glSize.resize(glWidth, glHeight);
} else */
m_glSize = m_size;
// detect pixels GL format
GLenum format = 0;
switch(channels) {
@ -108,7 +83,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
}
// load pixels into gl memory
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_glSize.width(), m_glSize.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.width(), m_size.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
// disable texture border
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -130,16 +105,12 @@ void Texture::enableBilinearFilter()
std::vector<uint8> Texture::getPixels()
{
// copy pixels from opengl memory
std::vector<uint8> pixels(m_glSize.area()*4, 0);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
// convert pixels to the real texture size
if(m_size != m_glSize)
for(int y=0; y<m_size.height(); ++y)
for(int x=0; x<m_size.width(); ++x)
for(int i=0; i<4; ++i)
pixels[y*m_size.width()*4+x*4+i] = pixels[y*m_glSize.width()*4+x*4+i];
// hack to copy pixels from opengl memory
FrameBufferPtr fb(new FrameBuffer(m_size));
std::vector<uint8> pixels(m_size.area()*4, 0);
fb->bind();
g_painter.drawTexturedRect(Rect(0,0,m_size), shared_from_this());
glReadPixels(0, 0, m_size.width(), m_size.height(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
fb->release();
return pixels;
}

View File

@ -28,24 +28,18 @@
class Texture : public std::enable_shared_from_this<Texture>
{
public:
/// Create a texture, width and height must be a multiple of 2
Texture();
Texture(int width, int height, int channels, uchar* pixels = NULL);
virtual ~Texture();
/// Enable texture bilinear filter (smooth scaled textures)
virtual void enableBilinearFilter();
/// Get OpenGL texture id
GLuint getId() { return m_textureId; }
/// Copy pixels from OpenGL texture
std::vector<uint8> getPixels();
int getWidth() { return m_size.width(); }
int getHeight() { return m_size.height(); }
const Size& getSize() { return m_size; }
const Size& getGlSize() { return m_glSize; }
bool isEmpty() const { return m_textureId == 0; }
@ -54,7 +48,6 @@ protected:
GLuint m_textureId;
Size m_size;
Size m_glSize;
};
#endif

View File

@ -1,24 +0,0 @@
/*
* Copyright (c) 2010-2011 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 "textureglyphcache.h"

View File

@ -1,30 +0,0 @@
/*
* Copyright (c) 2010-2011 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 TEXTUREGLYPHCACHE_H
#define TEXTUREGLYPHCACHE_H
class TextureGlyphCache
{
};
#endif

View File

@ -28,10 +28,8 @@
class TextureManager
{
public:
/// Load a texture from file, if is already loaded, it will be retrieved from cache
TexturePtr getTexture(const std::string& textureFile);
/// Load a png textures
static TexturePtr loadPNG(std::stringstream& file);
private:

View File

@ -29,12 +29,12 @@
class VertexArray
{
public:
inline void addVertex(GLfloat x, GLfloat y) { m_buffer << x << y; }
inline void addVertex(float x, float y) { m_buffer << x << y; }
inline void addRect(const Rect& rect) {
GLfloat top = rect.top();
GLfloat right = rect.right()+1;
GLfloat bottom = rect.bottom()+1;
GLfloat left = rect.left();
float top = rect.top();
float right = rect.right()+1;
float bottom = rect.bottom()+1;
float left = rect.left();
addVertex(left, top);
addVertex(right, top);
@ -45,10 +45,10 @@ public:
}
inline void addQuad(const Rect& rect) {
GLfloat top = rect.top();
GLfloat right = rect.right()+1;
GLfloat bottom = rect.bottom()+1;
GLfloat left = rect.left();
float top = rect.top();
float right = rect.right()+1;
float bottom = rect.bottom()+1;
float left = rect.left();
addVertex(left, top);
addVertex(right, top);
@ -57,11 +57,11 @@ public:
}
void clear() { m_buffer.reset(); }
GLfloat *vertices() const { return m_buffer.data(); }
float *vertices() const { return m_buffer.data(); }
int vertexCount() const { return m_buffer.size() / 2; }
private:
DataBuffer<GLfloat> m_buffer;
DataBuffer<float> m_buffer;
};
#endif

205
src/framework/util/matrix.h Normal file
View File

@ -0,0 +1,205 @@
/*
* Copyright (c) 2010-2011 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 MATRIX_H
#define MATRIX_H
#include <array>
#include <cstring>
#include <initializer_list>
#include <sstream>
template<int N, int M, typename T = float>
class Matrix
{
public:
Matrix() { setIdentity(); }
Matrix(const Matrix<N,M,T>& other) = default;
template<typename U>
Matrix(const std::initializer_list<U>& values) { *this = values; }
template<typename U>
Matrix(const U *values) { *this = values; }
void setIdentity();
bool isIdentity() const;
void fill(T value);
Matrix<M,N,T> transposed() const;
typename std::enable_if<N==M>::type transpose() { *this = transposed(); }
T *data() { return m[0]; }
const T *data() const { return m[0]; }
T& operator()(int row, int column) { return m[row-1][column-1]; }
T operator()(int row, int column) const { return m[row-1][column-1]; }
Matrix<N,M,T>& operator=(const Matrix<N,M,T>& other) = default;
template<typename U>
Matrix<N,M,T>& operator=(const std::initializer_list<U>& values);
template<typename U>
Matrix<N,M,T>& operator=(const U *values);
Matrix<N,M,T>& operator+=(const Matrix<N,M,T>& other);
Matrix<N,M,T>& operator-=(const Matrix<N,M,T>& other);
Matrix<N,M,T>& operator*=(T factor);
Matrix<N,M,T>& operator/=(T divisor);
bool operator==(const Matrix<N,M,T>& other) const;
bool operator!=(const Matrix<N,M,T>& other) const;
private:
Matrix(int) {} // construct without initializing identity matrix
T m[N][M];
};
template<int N, int M, typename T>
void Matrix<N,M,T>::setIdentity() {
for(int i=0;i<N;++i) {
for(int j=0;j<M;++j) {
if(i==j)
m[i][j] = 1.0f;
else
m[i][j] = 0.0f;
}
}
}
template<int N, int M, typename T>
bool Matrix<N,M,T>::isIdentity() const {
for(int i=0;i<N;++i) {
for(int j=0;j<M;++j) {
if((i==j && m[i][j] != 1.0f) || (i!=j && m[i][j] != 0.0f))
return false;
}
}
return true;
}
template<int N, int M, typename T>
void Matrix<N,M,T>::fill(T value) {
for(int i=0;i<N*M;++i)
m[0][i] = value;
}
template<int N, int M, typename T>
Matrix<M,N,T> Matrix<N,M,T>::transposed() const {
Matrix<M,N,T> result(1);
for(int i=0;i<N;++i)
for(int j=0;j<M;++j)
result.m[j][i] = m[i][j];
return result;
}
template<int N, int M, typename T>
template<typename U>
Matrix<N,M,T>& Matrix<N,M,T>::operator=(const std::initializer_list<U>& values) {
auto it = values.begin();
for(int i=0;i<N*M;++i)
m[0][i] = *(it++);
return *this;
}
template<int N, int M, typename T>
template<typename U>
Matrix<N,M,T>& Matrix<N,M,T>::operator=(const U *values) {
for(int i=0;i<N;++i)
for(int j=0;j<M;++j)
m[i][j] = values[i*N + j];
return *this;
}
template<int N, int M, typename T>
Matrix<N,M,T>& Matrix<N,M,T>::operator+=(const Matrix<N,M,T>& other) {
for(int i=0;i<N*M;++i)
m[0][i] += other.m[0][i];
return *this;
}
template<int N, int M, typename T>
Matrix<N,M,T>& Matrix<N,M,T>::operator-=(const Matrix<N,M,T>& other) {
for(int i=0;i<N*M;++i)
m[0][i] -= other.m[0][i];
return *this;
}
template<int N, int M, typename T>
Matrix<N,M,T>& Matrix<N,M,T>::operator*=(T factor) {
for(int i=0;i<N*M;++i)
m[0][i] *= factor;
return *this;
}
template<int N, int M, typename T>
Matrix<N,M,T>& Matrix<N,M,T>::operator/=(T divisor) {
for(int i=0;i<N*M;++i)
m[0][i] /= divisor;
return *this;
}
template<int N, int M, typename T>
bool Matrix<N,M,T>::operator==(const Matrix<N,M,T>& other) const
{
for(int i=0;i<N*M;++i)
if(m[0][i] != other.m[0][i])
return false;
return true;
}
template<int N, int M, typename T>
bool Matrix<N,M,T>::operator!=(const Matrix<N,M,T>& other) const
{
for(int i=0;i<N*M;++i)
if(m[0][i] != other.m[0][i])
return true;
return false;
}
template<int N, int M, typename T>
std::ostream& operator<<(std::ostream& out, const Matrix<N,M,T>& mat)
{
for(int i=0;i<N;++i) {
for(int j=0;j<M;++j) {
out << mat(i,j);
if(j+1 != M)
out << " ";
}
out << "\n";
}
return out;
}
template<int N, int M, typename T>
std::istream& operator>>(std::istream& in, Matrix<N,M,T>& mat)
{
for(int i=0;i<N;++i)
for(int j=0;j<M;++j)
in >> mat(i,j);
return in;
}
typedef Matrix<4,4> Matrix4x4;
typedef Matrix<3,3> Matrix3x3;
typedef Matrix<2,2> Matrix2x2;
typedef Matrix4x4 Matrix4;
typedef Matrix3x3 Matrix3;
typedef Matrix2x2 Matrix2;
#endif

View File

@ -42,7 +42,8 @@ PainterShaderProgramPtr program;
void Map::draw(const Rect& rect)
{
if(!m_framebuffer) {
m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));
Size fboSize(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS);
m_framebuffer = FrameBufferPtr(new FrameBuffer(fboSize));
program = PainterShaderProgramPtr(new PainterShaderProgram);
@ -308,8 +309,9 @@ void Map::setVisibleSize(const Size& visibleSize)
m_centralOffset = Point(std::ceil(m_visibleSize.width() / 2.0), std::ceil(m_visibleSize.height() / 2.0));
m_size = m_visibleSize + Size(3, 3);
if(m_framebuffer)
m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));
if(m_framebuffer) {
m_framebuffer->resize(Size(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));
}
}
Point Map::positionTo2D(const Position& position)