begin implementing OpenGL 1.0 engine
* option to pass -opengl1 or -opengl2 as argument * note that with this commit there are a lot of graphics regressions and the master will remaing unstable for a while * shaders disabled for a while
This commit is contained in:
parent
a4a00a49fe
commit
58d76e255d
|
@ -5,6 +5,7 @@ uniform sampler2D tex0; // map texture
|
||||||
varying vec2 texCoord; // map texture coords
|
varying vec2 texCoord; // map texture coords
|
||||||
//uniform vec4 awareArea;
|
//uniform vec4 awareArea;
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_FragColor = texture2D(tex0, texCoord);
|
gl_FragColor = texture2D(tex0, texCoord);
|
||||||
|
@ -84,3 +85,21 @@ void main()
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 sum = vec4(0);
|
||||||
|
vec2 texcoord = texCoord;
|
||||||
|
int j;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for( i= -4 ;i < 4; i++)
|
||||||
|
{
|
||||||
|
for (j = -4; j < 4; j++)
|
||||||
|
{
|
||||||
|
sum += texture2D(tex0, texcoord + vec2(j, i)*0.0025) * 0.0125;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gl_FragColor = texture2D(tex0, texCoord) + sum;
|
||||||
|
}
|
||||||
|
*/
|
|
@ -189,6 +189,8 @@ SET(framework_SOURCES ${framework_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/fontmanager.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/fontmanager.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/painter.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/painter.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/painterogl1.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/painterogl2.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/framebuffer.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/framebuffer.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
|
||||||
|
@ -201,6 +203,7 @@ SET(framework_SOURCES ${framework_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/shader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/shader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershadermanager.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/coordsbuffer.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/coordsbuffer.cpp
|
||||||
|
|
||||||
# framework sound
|
# framework sound
|
||||||
|
|
|
@ -45,7 +45,6 @@ ticks_t Clock::asyncTicks()
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(timeNow - m_startupTime).count();
|
return std::chrono::duration_cast<std::chrono::milliseconds>(timeNow - m_startupTime).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Clock::sleep(int ms)
|
void Clock::sleep(int ms)
|
||||||
{
|
{
|
||||||
usleep(ms * 1000);
|
usleep(ms * 1000);
|
||||||
|
|
|
@ -23,13 +23,7 @@
|
||||||
#ifndef FRAMEWORK_GLOBAL_H
|
#ifndef FRAMEWORK_GLOBAL_H
|
||||||
#define FRAMEWORK_GLOBAL_H
|
#define FRAMEWORK_GLOBAL_H
|
||||||
|
|
||||||
#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
#include "util/compiler.h"
|
||||||
#error "sorry, you need gcc 4.6 or greater to compile"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
||||||
#error "sorry, you must enable C++0x to compile"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// common C/C++ headers
|
// common C/C++ headers
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
@ -38,7 +32,6 @@
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
|
|
||||||
// additional utilities
|
// additional utilities
|
||||||
#include "util/compiler.h"
|
|
||||||
#include "util/types.h"
|
#include "util/types.h"
|
||||||
#include "util/tools.h"
|
#include "util/tools.h"
|
||||||
#include "math/point.h"
|
#include "math/point.h"
|
||||||
|
|
|
@ -26,18 +26,18 @@
|
||||||
CoordsBuffer::CoordsBuffer()
|
CoordsBuffer::CoordsBuffer()
|
||||||
{
|
{
|
||||||
m_hardwareCacheMode = HardwareBuffer::DynamicDraw;
|
m_hardwareCacheMode = HardwareBuffer::DynamicDraw;
|
||||||
m_hardwareVertexBuffer = nullptr;
|
m_hardwareVertexArray = nullptr;
|
||||||
m_hardwareTextureVertexBuffer = nullptr;
|
m_hardwareTextureCoordArray = nullptr;
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
m_hardwareCaching = false;
|
m_hardwareCaching = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoordsBuffer::~CoordsBuffer()
|
CoordsBuffer::~CoordsBuffer()
|
||||||
{
|
{
|
||||||
if(m_hardwareVertexBuffer)
|
if(m_hardwareVertexArray)
|
||||||
delete m_hardwareVertexBuffer;
|
delete m_hardwareVertexArray;
|
||||||
if(m_hardwareTextureVertexBuffer)
|
if(m_hardwareTextureCoordArray)
|
||||||
delete m_hardwareTextureVertexBuffer;
|
delete m_hardwareTextureCoordArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoordsBuffer::addBoudingRect(const Rect& dest, int innerLineWidth)
|
void CoordsBuffer::addBoudingRect(const Rect& dest, int innerLineWidth)
|
||||||
|
@ -78,8 +78,8 @@ void CoordsBuffer::addRepeatedRects(const Rect& dest, const Rect& src)
|
||||||
}
|
}
|
||||||
|
|
||||||
partialDest.translate(dest.topLeft());
|
partialDest.translate(dest.topLeft());
|
||||||
m_vertexBuffer.addRect(partialDest);
|
m_vertexArray.addRect(partialDest);
|
||||||
m_textureVertexBuffer.addRect(partialSrc);
|
m_textureCoordArray.addRect(partialSrc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
|
@ -90,10 +90,6 @@ void CoordsBuffer::enableHardwareCaching(HardwareBuffer::UsagePattern usagePatte
|
||||||
if(!g_graphics.canUseHardwareBuffers())
|
if(!g_graphics.canUseHardwareBuffers())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifndef OPENGL_ES2
|
|
||||||
if(!GL_ARB_vertex_buffer_object)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
m_hardwareCacheMode = usagePattern;
|
m_hardwareCacheMode = usagePattern;
|
||||||
m_hardwareCaching = true;
|
m_hardwareCaching = true;
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
|
@ -104,18 +100,18 @@ void CoordsBuffer::updateCaches()
|
||||||
if(!m_hardwareCaching || m_hardwareCached)
|
if(!m_hardwareCaching || m_hardwareCached)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(m_vertexBuffer.vertexCount() > 0) {
|
if(m_vertexArray.vertexCount() > 0) {
|
||||||
if(!m_hardwareVertexBuffer && m_vertexBuffer.vertexCount() > 0)
|
if(!m_hardwareVertexArray && m_vertexArray.vertexCount() > 0)
|
||||||
m_hardwareVertexBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
m_hardwareVertexArray = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||||
m_hardwareVertexBuffer->bind();
|
m_hardwareVertexArray->bind();
|
||||||
m_hardwareVertexBuffer->write((void*)m_vertexBuffer.vertices(), m_vertexBuffer.size() * sizeof(float), m_hardwareCacheMode);
|
m_hardwareVertexArray->write((void*)m_vertexArray.vertices(), m_vertexArray.size() * sizeof(float), m_hardwareCacheMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_textureVertexBuffer.vertexCount() > 0) {
|
if(m_textureCoordArray.vertexCount() > 0) {
|
||||||
if(!m_hardwareTextureVertexBuffer && m_textureVertexBuffer.vertexCount() > 0)
|
if(!m_hardwareTextureCoordArray && m_textureCoordArray.vertexCount() > 0)
|
||||||
m_hardwareTextureVertexBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
m_hardwareTextureCoordArray = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||||
m_hardwareTextureVertexBuffer->bind();
|
m_hardwareTextureCoordArray->bind();
|
||||||
m_hardwareTextureVertexBuffer->write((void*)m_textureVertexBuffer.vertices(), m_textureVertexBuffer.size() * sizeof(float), m_hardwareCacheMode);
|
m_hardwareTextureCoordArray->write((void*)m_textureCoordArray.vertices(), m_textureCoordArray.size() * sizeof(float), m_hardwareCacheMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hardwareCached = true;
|
m_hardwareCached = true;
|
||||||
|
|
|
@ -33,23 +33,23 @@ public:
|
||||||
~CoordsBuffer();
|
~CoordsBuffer();
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
m_textureVertexBuffer.clear();
|
m_textureCoordArray.clear();
|
||||||
m_vertexBuffer.clear();
|
m_vertexArray.clear();
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addRect(const Rect& dest) {
|
void addRect(const Rect& dest) {
|
||||||
m_vertexBuffer.addRect(dest);
|
m_vertexArray.addRect(dest);
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
}
|
}
|
||||||
void addRect(const Rect& dest, const Rect& src) {
|
void addRect(const Rect& dest, const Rect& src) {
|
||||||
m_vertexBuffer.addRect(dest);
|
m_vertexArray.addRect(dest);
|
||||||
m_textureVertexBuffer.addRect(src);
|
m_textureCoordArray.addRect(src);
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
}
|
}
|
||||||
void addQuad(const Rect& dest, const Rect& src) {
|
void addQuad(const Rect& dest, const Rect& src) {
|
||||||
m_vertexBuffer.addQuad(dest);
|
m_vertexArray.addQuad(dest);
|
||||||
m_textureVertexBuffer.addQuad(src);
|
m_textureCoordArray.addQuad(src);
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,20 +60,20 @@ public:
|
||||||
void updateCaches();
|
void updateCaches();
|
||||||
bool isHardwareCached() { return m_hardwareCached; }
|
bool isHardwareCached() { return m_hardwareCached; }
|
||||||
|
|
||||||
float *getVertexBuffer() const { return m_vertexBuffer.vertices(); }
|
float *getVertexArray() const { return m_vertexArray.vertices(); }
|
||||||
float *getTextureVertexBuffer() const { return m_textureVertexBuffer.vertices(); }
|
float *getTextureCoordArray() const { return m_textureCoordArray.vertices(); }
|
||||||
int getVertexCount() const { return m_vertexBuffer.vertexCount(); }
|
int getVertexCount() const { return m_vertexArray.vertexCount(); }
|
||||||
int getTextureVertexCount() const { return m_textureVertexBuffer.vertexCount(); }
|
int getTextureCoordCount() const { return m_textureCoordArray.vertexCount(); }
|
||||||
|
|
||||||
HardwareBuffer *getHardwareVertexBuffer() { return m_hardwareVertexBuffer; }
|
HardwareBuffer *getHardwareVertexArray() { return m_hardwareVertexArray; }
|
||||||
HardwareBuffer *getHardwareTextureVertexBuffer() { return m_hardwareTextureVertexBuffer; }
|
HardwareBuffer *getHardwareTextureCoordArray() { return m_hardwareTextureCoordArray; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HardwareBuffer *m_hardwareVertexBuffer;
|
HardwareBuffer *m_hardwareVertexArray;
|
||||||
HardwareBuffer *m_hardwareTextureVertexBuffer;
|
HardwareBuffer *m_hardwareTextureCoordArray;
|
||||||
HardwareBuffer::UsagePattern m_hardwareCacheMode;
|
HardwareBuffer::UsagePattern m_hardwareCacheMode;
|
||||||
VertexArray m_vertexBuffer;
|
VertexArray m_vertexArray;
|
||||||
VertexArray m_textureVertexBuffer;
|
VertexArray m_textureCoordArray;
|
||||||
bool m_hardwareCached;
|
bool m_hardwareCached;
|
||||||
bool m_hardwareCaching;
|
bool m_hardwareCaching;
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,7 +77,7 @@ void Font::drawText(const std::string& text, const Rect& screenCoords, Fw::Align
|
||||||
coordsBuffer.clear();
|
coordsBuffer.clear();
|
||||||
|
|
||||||
calculateDrawTextCoords(coordsBuffer, text, screenCoords, align);
|
calculateDrawTextCoords(coordsBuffer, text, screenCoords, align);
|
||||||
g_painter.drawTextureCoords(coordsBuffer, m_texture);
|
g_painter->drawTextureCoords(coordsBuffer, m_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align)
|
void Font::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align)
|
||||||
|
|
|
@ -105,43 +105,44 @@ void FrameBuffer::clear(const Color& color, const Rect& rect)
|
||||||
{
|
{
|
||||||
bool clip = rect.isValid();
|
bool clip = rect.isValid();
|
||||||
if(clip)
|
if(clip)
|
||||||
g_painter.setClipRect(Rect(0, 0, m_texture->getSize()));
|
g_painter->setClipRect(Rect(0, 0, m_texture->getSize()));
|
||||||
|
|
||||||
glClearColor(color.rF(), color.gF(), color.bF(), color.aF());
|
glClearColor(color.rF(), color.gF(), color.bF(), color.aF());
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
if(clip)
|
if(clip)
|
||||||
g_painter.resetClipRect();
|
g_painter->resetClipRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::bind()
|
void FrameBuffer::bind()
|
||||||
{
|
{
|
||||||
internalBind();
|
internalBind();
|
||||||
|
|
||||||
Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f,
|
Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f,
|
||||||
0.0f, 2.0f/m_texture->getHeight(), 0.0f,
|
0.0f, 2.0f/m_texture->getHeight(), 0.0f,
|
||||||
-1.0f, -1.0f, 0.0f };
|
-1.0f, -1.0f, 1.0f };
|
||||||
|
g_painter->saveAndResetState();
|
||||||
|
g_painter->setProjectionMatrix(projectionMatrix);
|
||||||
|
|
||||||
m_oldProjectionMatrix = g_painter.getProjectionMatrix();
|
|
||||||
m_oldViewportSize = g_graphics.getViewportSize();
|
m_oldViewportSize = g_graphics.getViewportSize();
|
||||||
g_painter.setProjectionMatrix(projectionMatrix);
|
|
||||||
g_graphics.setViewportSize(m_texture->getSize());
|
g_graphics.setViewportSize(m_texture->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::release()
|
void FrameBuffer::release()
|
||||||
{
|
{
|
||||||
internalRelease();
|
internalRelease();
|
||||||
g_painter.setProjectionMatrix(m_oldProjectionMatrix);
|
g_painter->restoreSavedState();
|
||||||
g_graphics.setViewportSize(m_oldViewportSize);
|
g_graphics.setViewportSize(m_oldViewportSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::draw(const Rect& dest)
|
void FrameBuffer::draw(const Rect& dest)
|
||||||
{
|
{
|
||||||
g_painter.drawTexturedRect(dest, m_texture, Rect(0,0, getSize()));
|
g_painter->drawTexturedRect(dest, m_texture, Rect(0,0, getSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::internalBind()
|
void FrameBuffer::internalBind()
|
||||||
|
|
|
@ -50,7 +50,6 @@ private:
|
||||||
|
|
||||||
TexturePtr m_texture;
|
TexturePtr m_texture;
|
||||||
TexturePtr m_screenBackup;
|
TexturePtr m_screenBackup;
|
||||||
Matrix3 m_oldProjectionMatrix;
|
|
||||||
Size m_oldViewportSize;
|
Size m_oldViewportSize;
|
||||||
uint m_fbo;
|
uint m_fbo;
|
||||||
uint m_prevBoundFbo;
|
uint m_prevBoundFbo;
|
||||||
|
|
|
@ -27,12 +27,9 @@
|
||||||
#ifndef OPENGL_ES2
|
#ifndef OPENGL_ES2
|
||||||
#define GLEW_STATIC
|
#define GLEW_STATIC
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
//#include <GL/gl.h>
|
|
||||||
//#include <GL/glext.h>
|
|
||||||
#else
|
#else
|
||||||
#define GL_GLEXT_PROTOTYPES
|
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
#include <GLES2/gl2ext.h>
|
//#include <GLES2/gl2ext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fontmanager.h"
|
#include "fontmanager.h"
|
||||||
|
#include "painterogl1.h"
|
||||||
|
#include "painterogl2.h"
|
||||||
|
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
#include <framework/graphics/texture.h>
|
#include <framework/graphics/texture.h>
|
||||||
|
@ -33,6 +35,11 @@ void oglDebugCallback(unsigned int source, unsigned int type, unsigned int id, u
|
||||||
logWarning("OGL: ", message);
|
logWarning("OGL: ", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Graphics::Graphics()
|
||||||
|
{
|
||||||
|
m_maxTextureSize = -1;
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::init()
|
void Graphics::init()
|
||||||
{
|
{
|
||||||
logInfo("GPU ", glGetString(GL_RENDERER));
|
logInfo("GPU ", glGetString(GL_RENDERER));
|
||||||
|
@ -50,29 +57,7 @@ void Graphics::init()
|
||||||
glDebugMessageCallbackARB(oglDebugCallback, NULL);
|
glDebugMessageCallbackARB(oglDebugCallback, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char *requiredExtensions[] = {
|
// overwrite framebuffer API if needed
|
||||||
"GL_ARB_vertex_program",
|
|
||||||
"GL_ARB_vertex_shader",
|
|
||||||
"GL_ARB_fragment_shader",
|
|
||||||
"GL_ARB_texture_non_power_of_two",
|
|
||||||
"GL_ARB_multitexture"
|
|
||||||
};
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
bool unsupported = false;
|
|
||||||
for(auto ext : requiredExtensions) {
|
|
||||||
if(!glewIsSupported(ext)) {
|
|
||||||
ss << ext << std::endl;
|
|
||||||
unsupported = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(unsupported)
|
|
||||||
logFatal("The following OpenGL 2.0 extensions are not supported by your system graphics, please try updating your video drivers or buy a new hardware:\n",
|
|
||||||
ss.str(),
|
|
||||||
"Graphics card: ", glGetString(GL_RENDERER),
|
|
||||||
"\nOpenGL driver: ", glGetString(GL_VERSION));
|
|
||||||
|
|
||||||
if(GLEW_EXT_framebuffer_object && !GLEW_ARB_framebuffer_object) {
|
if(GLEW_EXT_framebuffer_object && !GLEW_ARB_framebuffer_object) {
|
||||||
glGenFramebuffers = glGenFramebuffersEXT;
|
glGenFramebuffers = glGenFramebuffersEXT;
|
||||||
glDeleteFramebuffers = glDeleteFramebuffersEXT;
|
glDeleteFramebuffers = glDeleteFramebuffersEXT;
|
||||||
|
@ -82,41 +67,105 @@ void Graphics::init()
|
||||||
glGenerateMipmap = glGenerateMipmapEXT;
|
glGenerateMipmap = glGenerateMipmapEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_useFBO = m_useFBO && (GLEW_ARB_framebuffer_object || GLEW_EXT_framebuffer_object);
|
// opengl 1 is always supported
|
||||||
m_generateHardwareMipmaps = m_generateHardwareMipmaps; // glGenerateMipmap is supported when framebuffers are
|
g_painterOGL1 = new PainterOGL1;
|
||||||
|
|
||||||
|
// opengl 2 is only supported in newer hardware
|
||||||
|
if(GLEW_VERSION_2_0)
|
||||||
|
g_painterOGL2 = new PainterOGL2;
|
||||||
|
#else
|
||||||
|
g_painterOGL2 = new PainterOGL2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
// determine max texture size
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
static GLint maxTextureSize = -1;
|
||||||
|
if(maxTextureSize == -1)
|
||||||
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||||
|
if(m_maxTextureSize == -1 || m_maxTextureSize > maxTextureSize)
|
||||||
|
m_maxTextureSize = maxTextureSize;
|
||||||
|
|
||||||
|
//glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
//m_prefferedPainterEngine = Painter_OpenGL1;
|
||||||
|
|
||||||
|
selectPainterEngine(m_prefferedPainterEngine);
|
||||||
m_emptyTexture = TexturePtr(new Texture);
|
m_emptyTexture = TexturePtr(new Texture);
|
||||||
|
|
||||||
g_painter.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::terminate()
|
void Graphics::terminate()
|
||||||
{
|
{
|
||||||
g_fonts.releaseFonts();
|
g_fonts.releaseFonts();
|
||||||
g_painter.terminate();
|
|
||||||
|
if(g_painterOGL1) {
|
||||||
|
delete g_painterOGL1;
|
||||||
|
g_painterOGL1 = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(g_painterOGL2) {
|
||||||
|
delete g_painterOGL2;
|
||||||
|
g_painterOGL2 = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_painter = nullptr;
|
||||||
|
|
||||||
m_emptyTexture.reset();
|
m_emptyTexture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::parseOption(const std::string& option)
|
bool Graphics::parseOption(const std::string& option)
|
||||||
{
|
{
|
||||||
if(option == "-no-fbos")
|
if(option == "-no-draw-arrays")
|
||||||
|
m_useDrawArrays = false;
|
||||||
|
else if(option == "-no-fbos")
|
||||||
m_useFBO = false;
|
m_useFBO = false;
|
||||||
else if(option == "-no-mipmapping")
|
else if(option == "-no-mipmaps")
|
||||||
m_generateMipmaps = false;
|
m_useMipmaps = false;
|
||||||
else if(option == "-no-smoothing")
|
else if(option == "-no-hardware-mipmaps")
|
||||||
|
m_useHardwareMipmaps = false;
|
||||||
|
else if(option == "-no-smooth")
|
||||||
m_useBilinearFiltering = false;
|
m_useBilinearFiltering = false;
|
||||||
else if(option == "-no-hardware-buffering")
|
else if(option == "-no-hardware-buffers")
|
||||||
m_useHardwareBuffers = false;
|
m_useHardwareBuffers = false;
|
||||||
|
else if(option == "-no-non-power-of-two-textures")
|
||||||
|
m_useNonPowerOfTwoTextures = false;
|
||||||
|
else if(option == "-opengl1")
|
||||||
|
m_prefferedPainterEngine = Painter_OpenGL1;
|
||||||
|
else if(option == "-opengl2")
|
||||||
|
m_prefferedPainterEngine = Painter_OpenGL2;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Graphics::selectPainterEngine(PainterEngine painterEngine)
|
||||||
|
{
|
||||||
|
// always prefer OpenGL 2 over OpenGL 1
|
||||||
|
if(g_painterOGL2 && (painterEngine == Painter_OpenGL2 || painterEngine == Painter_Any))
|
||||||
|
g_painter = g_painterOGL2;
|
||||||
|
// fallback to OpenGL 1 in older hardwares
|
||||||
|
else if(g_painterOGL1 && (painterEngine == Painter_OpenGL1 || painterEngine == Painter_Any))
|
||||||
|
g_painter = g_painterOGL1;
|
||||||
|
else
|
||||||
|
logFatal("Neither OpenGL 1.0 nor OpenGL 2.0 painter engine is supported by your platform, "
|
||||||
|
"try updating your graphics drivers or your hardware and then run again.");
|
||||||
|
|
||||||
|
// switch painters GL state
|
||||||
|
if(g_painter)
|
||||||
|
g_painter->unbind();
|
||||||
|
g_painter->bind();
|
||||||
|
|
||||||
|
if(painterEngine == Painter_Any)
|
||||||
|
return true;
|
||||||
|
return getPainterEngine() == painterEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics::PainterEngine Graphics::getPainterEngine()
|
||||||
|
{
|
||||||
|
if(g_painter == g_painterOGL2)
|
||||||
|
return Painter_OpenGL2;
|
||||||
|
else
|
||||||
|
return Painter_OpenGL1;
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::resize(const Size& size)
|
void Graphics::resize(const Size& size)
|
||||||
{
|
{
|
||||||
setViewportSize(size);
|
setViewportSize(size);
|
||||||
|
@ -128,17 +177,21 @@ void Graphics::resize(const Size& size)
|
||||||
//
|
//
|
||||||
// This results in the Projection matrix below.
|
// This results in the Projection matrix below.
|
||||||
//
|
//
|
||||||
// Projection Matrix Painter Coord GL Coord
|
// Projection Matrix
|
||||||
// ------------------------------------------------ --------- ---------
|
// Painter Coord ------------------------------------------------ GL Coord
|
||||||
// | 2.0 / width | 0.0 | -1.0 | | x | | x' |
|
// ------------- | 2.0 / width | 0.0 | 0.0 | ---------------
|
||||||
// | 0.0 | -2.0 / height | 1.0 | * | y | = | y' |
|
// | x y 1 | * | 0.0 | -2.0 / height | 0.0 | = | x' y' 1 |
|
||||||
// | 0.0 | 0.0 | 0.0 | | 1 | | 0 |
|
// ------------- | -1.0 | 1.0 | 1.0 | ---------------
|
||||||
// ------------------------------------------------ --------- ---------
|
// ------------------------------------------------
|
||||||
Matrix3 projectionMatrix = { 2.0f/size.width(), 0.0f, -1.0f,
|
Matrix3 projectionMatrix = { 2.0f/size.width(), 0.0f, 0.0f,
|
||||||
0.0f, -2.0f/size.height(), 1.0f,
|
0.0f, -2.0f/size.height(), 0.0f,
|
||||||
0.0f, 0.0f, 0.0f };
|
-1.0f, 1.0f, 1.0f };
|
||||||
projectionMatrix.transpose();
|
|
||||||
g_painter.setProjectionMatrix(projectionMatrix);
|
if(g_painterOGL1)
|
||||||
|
g_painterOGL1->setProjectionMatrix(projectionMatrix);
|
||||||
|
|
||||||
|
if(g_painterOGL2)
|
||||||
|
g_painterOGL2->setProjectionMatrix(projectionMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::beginRender()
|
void Graphics::beginRender()
|
||||||
|
@ -149,16 +202,6 @@ void Graphics::beginRender()
|
||||||
|
|
||||||
void Graphics::endRender()
|
void Graphics::endRender()
|
||||||
{
|
{
|
||||||
// this is a simple blur effect
|
|
||||||
/*
|
|
||||||
static Timer timer;
|
|
||||||
if(timer.ticksElapsed() >= 10) {
|
|
||||||
glAccum(GL_MULT, 0.9);
|
|
||||||
glAccum(GL_ACCUM, 0.1);
|
|
||||||
timer.restart();
|
|
||||||
}
|
|
||||||
glAccum(GL_RETURN, 1);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setViewportSize(const Size& size)
|
void Graphics::setViewportSize(const Size& size)
|
||||||
|
@ -167,10 +210,71 @@ void Graphics::setViewportSize(const Size& size)
|
||||||
m_viewportSize = size;
|
m_viewportSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getMaxTextureSize()
|
bool Graphics::canUseDrawArrays()
|
||||||
{
|
{
|
||||||
static GLint maxTexSize = -1;
|
#ifndef OPENGL_ES2
|
||||||
if(maxTexSize == -1)
|
if(!GLEW_VERSION_1_1)
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
|
return false;
|
||||||
return maxTexSize;
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
return m_useDrawArrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::canUseShaders()
|
||||||
|
{
|
||||||
|
#ifndef OPENGL_ES2
|
||||||
|
if(GLEW_ARB_vertex_program && GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::canUseFBO()
|
||||||
|
{
|
||||||
|
#ifndef OPENGL_ES2
|
||||||
|
if(!GLEW_ARB_framebuffer_object || !GLEW_EXT_framebuffer_object)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
return m_useFBO;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::canUseBilinearFiltering()
|
||||||
|
{
|
||||||
|
return m_useBilinearFiltering;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::canUseHardwareBuffers()
|
||||||
|
{
|
||||||
|
#ifndef OPENGL_ES2
|
||||||
|
if(!GLEW_ARB_vertex_buffer_object)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
return m_useHardwareBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::canUseNonPowerOfTwoTextures()
|
||||||
|
{
|
||||||
|
#ifndef OPENGL_ES2
|
||||||
|
if(!GLEW_ARB_texture_non_power_of_two)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
return m_useNonPowerOfTwoTextures;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::canUseMipmaps()
|
||||||
|
{
|
||||||
|
return m_useMipmaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::canUseHardwareMipmaps()
|
||||||
|
{
|
||||||
|
#ifndef OPENGL_ES2
|
||||||
|
// glGenerateMipmap is supported when framebuffers are too
|
||||||
|
if(!GLEW_ARB_framebuffer_object || !GLEW_EXT_framebuffer_object)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
return m_useHardwareMipmaps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,15 +29,20 @@
|
||||||
class Graphics
|
class Graphics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Graphics();
|
||||||
|
|
||||||
|
enum PainterEngine {
|
||||||
|
Painter_Any,
|
||||||
|
Painter_OpenGL1,
|
||||||
|
Painter_OpenGL2
|
||||||
|
};
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void terminate();
|
void terminate();
|
||||||
bool parseOption(const std::string& option);
|
bool parseOption(const std::string& option);
|
||||||
|
|
||||||
bool canUseFBO() { return m_useFBO; }
|
bool selectPainterEngine(PainterEngine painterEngine);
|
||||||
bool canUseBilinearFiltering() { return m_useBilinearFiltering; }
|
PainterEngine getPainterEngine();
|
||||||
bool canUseHardwareBuffers() { return m_useHardwareBuffers; }
|
|
||||||
bool canGenerateMipmaps() { return m_generateMipmaps; }
|
|
||||||
bool canGenerateHardwareMipmaps() { return m_generateHardwareMipmaps; }
|
|
||||||
|
|
||||||
void resize(const Size& size);
|
void resize(const Size& size);
|
||||||
void beginRender();
|
void beginRender();
|
||||||
|
@ -45,19 +50,32 @@ public:
|
||||||
|
|
||||||
void setViewportSize(const Size& size);
|
void setViewportSize(const Size& size);
|
||||||
|
|
||||||
int getMaxTextureSize();
|
int getMaxTextureSize() { return m_maxTextureSize; }
|
||||||
const Size& getViewportSize() { return m_viewportSize; }
|
const Size& getViewportSize() { return m_viewportSize; }
|
||||||
TexturePtr& getEmptyTexture() { return m_emptyTexture; }
|
TexturePtr& getEmptyTexture() { return m_emptyTexture; }
|
||||||
|
|
||||||
|
bool canUseDrawArrays();
|
||||||
|
bool canUseShaders();
|
||||||
|
bool canUseFBO();
|
||||||
|
bool canUseBilinearFiltering();
|
||||||
|
bool canUseHardwareBuffers();
|
||||||
|
bool canUseNonPowerOfTwoTextures();
|
||||||
|
bool canUseMipmaps();
|
||||||
|
bool canUseHardwareMipmaps();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Size m_viewportSize;
|
Size m_viewportSize;
|
||||||
TexturePtr m_emptyTexture;
|
TexturePtr m_emptyTexture;
|
||||||
|
|
||||||
|
int m_maxTextureSize;
|
||||||
|
Boolean<true> m_useDrawArrays;
|
||||||
Boolean<true> m_useFBO;
|
Boolean<true> m_useFBO;
|
||||||
Boolean<true> m_useHardwareBuffers;
|
Boolean<true> m_useHardwareBuffers;
|
||||||
Boolean<true> m_useBilinearFiltering;
|
Boolean<true> m_useBilinearFiltering;
|
||||||
Boolean<true> m_generateMipmaps;
|
Boolean<true> m_useNonPowerOfTwoTextures;
|
||||||
Boolean<true> m_generateHardwareMipmaps;
|
Boolean<true> m_useMipmaps;
|
||||||
|
Boolean<true> m_useHardwareMipmaps;
|
||||||
|
PainterEngine m_prefferedPainterEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Graphics g_graphics;
|
extern Graphics g_graphics;
|
||||||
|
|
|
@ -53,7 +53,6 @@ public:
|
||||||
void bind() { glBindBuffer(m_type, m_id); }
|
void bind() { glBindBuffer(m_type, m_id); }
|
||||||
static void unbind(Type type) { glBindBuffer(type, 0); }
|
static void unbind(Type type) { glBindBuffer(type, 0); }
|
||||||
void write(void *data, int count, UsagePattern usage) { glBufferData(m_type, count, data, usage); }
|
void write(void *data, int count, UsagePattern usage) { glBufferData(m_type, count, data, usage); }
|
||||||
//void read(void *data, int count);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type m_type;
|
Type m_type;
|
||||||
|
|
|
@ -21,102 +21,108 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "painter.h"
|
#include "painter.h"
|
||||||
#include "texture.h"
|
|
||||||
#include "paintershadersources.h"
|
|
||||||
#include "paintershaderprogram.h"
|
|
||||||
#include "shaderprogram.h"
|
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "vertexarray.h"
|
|
||||||
|
|
||||||
Painter g_painter;
|
Painter *g_painter = nullptr;
|
||||||
|
|
||||||
void Painter::init()
|
Painter::Painter()
|
||||||
{
|
{
|
||||||
setColor(Color::white);
|
m_glTextureId = 0;
|
||||||
setOpacity(1.0f);
|
m_oldStateIndex = 0;
|
||||||
setCompositionMode(CompositionMode_Normal);
|
m_color = Color::white;
|
||||||
releaseCustomProgram();
|
m_opacity = 1.0f;
|
||||||
|
m_compositionMode = CompositionMode_Normal;
|
||||||
m_drawTexturedProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
m_shaderProgram = nullptr;
|
||||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
m_texture = nullptr;
|
||||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader);
|
|
||||||
m_drawTexturedProgram->link();
|
|
||||||
|
|
||||||
m_drawSolidColorProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
|
||||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader);
|
|
||||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader);
|
|
||||||
m_drawSolidColorProgram->link();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::terminate()
|
void Painter::resetState()
|
||||||
{
|
{
|
||||||
m_drawTexturedProgram.reset();
|
resetColor();
|
||||||
m_drawSolidColorProgram.reset();
|
resetOpacity();
|
||||||
|
resetCompositionMode();
|
||||||
|
resetClipRect();
|
||||||
|
resetShaderProgram();
|
||||||
|
resetTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::drawProgram(PainterShaderProgram *program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode)
|
void Painter::refreshState()
|
||||||
{
|
{
|
||||||
if(coordsBuffer.getVertexCount() == 0)
|
updateGlCompositionMode();
|
||||||
return;
|
updateGlClipRect();
|
||||||
|
updateGlTexture();
|
||||||
program->setProjectionMatrix(m_projectionMatrix);
|
|
||||||
program->setOpacity(m_opacity);
|
|
||||||
program->setColor(m_color);
|
|
||||||
program->draw(coordsBuffer, drawMode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
void Painter::saveAndResetState()
|
||||||
{
|
{
|
||||||
PainterShaderProgram *program = m_customProgram ? m_customProgram : m_drawTexturedProgram.get();
|
assert(m_oldStateIndex<10);
|
||||||
program->setTexture(texture);
|
m_olderStates[m_oldStateIndex].projectionMatrix = m_projectionMatrix;
|
||||||
drawProgram(program, coordsBuffer);
|
m_olderStates[m_oldStateIndex].textureMatrix = m_textureMatrix;
|
||||||
|
m_olderStates[m_oldStateIndex].color = m_color;
|
||||||
|
m_olderStates[m_oldStateIndex].opacity = m_opacity;
|
||||||
|
m_olderStates[m_oldStateIndex].compositionMode = m_compositionMode;
|
||||||
|
m_olderStates[m_oldStateIndex].clipRect = m_clipRect;
|
||||||
|
m_olderStates[m_oldStateIndex].shaderProgram = m_shaderProgram;
|
||||||
|
m_olderStates[m_oldStateIndex].texture = m_texture;
|
||||||
|
m_oldStateIndex++;
|
||||||
|
resetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
void Painter::restoreSavedState()
|
||||||
{
|
{
|
||||||
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
m_oldStateIndex--;
|
||||||
return;
|
setProjectionMatrix(m_olderStates[m_oldStateIndex].projectionMatrix);
|
||||||
|
setTextureMatrix(m_olderStates[m_oldStateIndex].textureMatrix);
|
||||||
m_coordsBuffer.clear();
|
setColor(m_olderStates[m_oldStateIndex].color);
|
||||||
m_coordsBuffer.addQuad(dest, src);
|
setOpacity(m_olderStates[m_oldStateIndex].opacity);
|
||||||
PainterShaderProgram *program = m_customProgram ? m_customProgram : m_drawTexturedProgram.get();
|
setCompositionMode(m_olderStates[m_oldStateIndex].compositionMode);
|
||||||
program->setTexture(texture);
|
setClipRect(m_olderStates[m_oldStateIndex].clipRect);
|
||||||
drawProgram(program, m_coordsBuffer, PainterShaderProgram::TriangleStrip);
|
setShaderProgram(m_olderStates[m_oldStateIndex].shaderProgram);
|
||||||
}
|
setTexture(m_olderStates[m_oldStateIndex].texture);
|
||||||
|
|
||||||
void Painter::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
|
||||||
{
|
|
||||||
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_coordsBuffer.clear();
|
|
||||||
m_coordsBuffer.addRepeatedRects(dest, src);
|
|
||||||
drawTextureCoords(m_coordsBuffer, texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Painter::drawFilledRect(const Rect& dest)
|
|
||||||
{
|
|
||||||
if(dest.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_coordsBuffer.clear();
|
|
||||||
m_coordsBuffer.addRect(dest);
|
|
||||||
drawProgram(m_customProgram ? m_customProgram : m_drawSolidColorProgram.get(), m_coordsBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Painter::drawBoundingRect(const Rect& dest, int innerLineWidth)
|
|
||||||
{
|
|
||||||
if(dest.isEmpty() || innerLineWidth == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_coordsBuffer.clear();
|
|
||||||
m_coordsBuffer.addBoudingRect(dest, innerLineWidth);
|
|
||||||
drawProgram(m_customProgram ? m_customProgram : m_drawSolidColorProgram.get(), m_coordsBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::setCompositionMode(Painter::CompositionMode compositionMode)
|
void Painter::setCompositionMode(Painter::CompositionMode compositionMode)
|
||||||
{
|
{
|
||||||
switch(compositionMode) {
|
if(m_compositionMode == compositionMode)
|
||||||
|
return;
|
||||||
|
m_compositionMode = compositionMode;
|
||||||
|
updateGlCompositionMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::setClipRect(const Rect& clipRect)
|
||||||
|
{
|
||||||
|
if(m_clipRect == clipRect)
|
||||||
|
return;
|
||||||
|
m_clipRect = clipRect;
|
||||||
|
updateGlClipRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::setTexture(Texture* texture)
|
||||||
|
{
|
||||||
|
if(m_texture == texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_texture = texture;
|
||||||
|
|
||||||
|
if(texture) {
|
||||||
|
m_glTextureId = texture->getId();
|
||||||
|
setTextureMatrix(texture->getTransformMatrix());
|
||||||
|
} else
|
||||||
|
m_glTextureId = 0;
|
||||||
|
m_texture = texture;
|
||||||
|
|
||||||
|
updateGlTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::updateGlTexture()
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_glTextureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::updateGlCompositionMode()
|
||||||
|
{
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
switch(m_compositionMode) {
|
||||||
case CompositionMode_Normal:
|
case CompositionMode_Normal:
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
break;
|
break;
|
||||||
|
@ -133,50 +139,14 @@ void Painter::setCompositionMode(Painter::CompositionMode compositionMode)
|
||||||
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
|
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_compostionMode = compositionMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::setClipRect(const Rect& clipRect)
|
void Painter::updateGlClipRect()
|
||||||
{
|
{
|
||||||
if(m_clipRect == clipRect)
|
if(m_clipRect.isValid()) {
|
||||||
return;
|
|
||||||
|
|
||||||
if(clipRect.isValid()) {
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glScissor(clipRect.left(), g_graphics.getViewportSize().height() - clipRect.bottom() - 1, clipRect.width(), clipRect.height());
|
glScissor(m_clipRect.left(), g_graphics.getViewportSize().height() - m_clipRect.bottom() - 1, m_clipRect.width(), m_clipRect.height());
|
||||||
} else {
|
} else {
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
m_clipRect = clipRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Painter::saveAndResetState()
|
|
||||||
{
|
|
||||||
m_oldCustomProgram = m_customProgram;
|
|
||||||
m_oldProjectionMatrix = m_projectionMatrix;
|
|
||||||
m_oldColor = m_color;
|
|
||||||
m_oldOpacity = m_opacity;
|
|
||||||
m_oldCompostionMode = m_compostionMode;
|
|
||||||
m_oldClipRect = m_clipRect;
|
|
||||||
|
|
||||||
releaseCustomProgram();
|
|
||||||
resetClipRect();
|
|
||||||
setColor(Color::white);
|
|
||||||
setOpacity(1);
|
|
||||||
setCompositionMode(CompositionMode_Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Painter::restoreSavedState()
|
|
||||||
{
|
|
||||||
m_customProgram = m_oldCustomProgram;
|
|
||||||
setColor(m_oldColor);
|
|
||||||
setOpacity(m_oldOpacity);
|
|
||||||
setCompositionMode(m_oldCompostionMode);
|
|
||||||
setClipRect(m_oldClipRect);
|
|
||||||
|
|
||||||
m_oldCustomProgram = nullptr;
|
|
||||||
m_oldColor = Color::white;
|
|
||||||
m_oldOpacity = 1;
|
|
||||||
m_oldCompostionMode = CompositionMode_Normal;
|
|
||||||
m_oldClipRect = Rect();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#define PAINTER_H
|
#define PAINTER_H
|
||||||
|
|
||||||
#include "declarations.h"
|
#include "declarations.h"
|
||||||
#include <framework/util/databuffer.h>
|
|
||||||
#include "coordsbuffer.h"
|
#include "coordsbuffer.h"
|
||||||
#include "paintershaderprogram.h"
|
#include "paintershaderprogram.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
@ -39,58 +38,90 @@ public:
|
||||||
CompositionMode_Replace,
|
CompositionMode_Replace,
|
||||||
CompositionMode_DestBlending
|
CompositionMode_DestBlending
|
||||||
};
|
};
|
||||||
|
enum DrawMode {
|
||||||
|
Triangles = GL_TRIANGLES,
|
||||||
|
TriangleStrip = GL_TRIANGLE_STRIP
|
||||||
|
};
|
||||||
|
|
||||||
void init();
|
struct PainterState {
|
||||||
void terminate();
|
Matrix3 projectionMatrix;
|
||||||
|
Matrix2 textureMatrix;
|
||||||
|
Color color;
|
||||||
|
float opacity;
|
||||||
|
Painter::CompositionMode compositionMode;
|
||||||
|
Rect clipRect;
|
||||||
|
Texture *texture;
|
||||||
|
PainterShaderProgram *shaderProgram;
|
||||||
|
};
|
||||||
|
|
||||||
void drawProgram(PainterShaderProgram *program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode = PainterShaderProgram::Triangles);
|
Painter();
|
||||||
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
virtual ~Painter() { }
|
||||||
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
|
||||||
void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); }
|
|
||||||
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
|
||||||
void drawFilledRect(const Rect& dest);
|
|
||||||
void drawBoundingRect(const Rect& dest, int innerLineWidth = 1);
|
|
||||||
|
|
||||||
void setColor(const Color& color) { m_color = color; }
|
virtual void bind() { refreshState(); }
|
||||||
Color getColor() { return m_color; }
|
virtual void unbind() { }
|
||||||
|
|
||||||
void setOpacity(float opacity) { m_opacity = opacity; }
|
|
||||||
float getOpacity() { return m_opacity; }
|
|
||||||
|
|
||||||
void setClipRect(const Rect& clipRect);
|
|
||||||
Rect getClipRect() { return m_clipRect; }
|
|
||||||
void resetClipRect() { setClipRect(Rect()); }
|
|
||||||
|
|
||||||
void setCustomProgram(const PainterShaderProgramPtr& program) { m_customProgram = program.get(); }
|
|
||||||
void releaseCustomProgram() { m_customProgram = nullptr; }
|
|
||||||
void setCompositionMode(CompositionMode compositionMode);
|
|
||||||
void resetCompositionMode() { setCompositionMode(CompositionMode_Normal); }
|
|
||||||
|
|
||||||
void setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; }
|
|
||||||
Matrix3 getProjectionMatrix() { return m_projectionMatrix; }
|
|
||||||
|
|
||||||
|
void resetState();
|
||||||
|
virtual void refreshState();
|
||||||
void saveAndResetState();
|
void saveAndResetState();
|
||||||
void restoreSavedState();
|
void restoreSavedState();
|
||||||
|
|
||||||
private:
|
virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0;
|
||||||
PainterShaderProgramPtr m_drawTexturedProgram;
|
virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0;
|
||||||
PainterShaderProgramPtr m_drawSolidColorProgram;
|
virtual void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
||||||
PainterShaderProgram *m_customProgram;
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); }
|
||||||
|
virtual void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
||||||
|
virtual void drawFilledRect(const Rect& dest) = 0;
|
||||||
|
virtual void drawBoundingRect(const Rect& dest, int innerLineWidth = 1) = 0;
|
||||||
|
|
||||||
|
virtual void setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; }
|
||||||
|
virtual void setTextureMatrix(const Matrix2& textureMatrix) { m_textureMatrix = textureMatrix; }
|
||||||
|
virtual void setColor(const Color& color) { m_color = color; }
|
||||||
|
virtual void setOpacity(float opacity) { m_opacity = opacity; }
|
||||||
|
virtual void setCompositionMode(CompositionMode compositionMode);
|
||||||
|
virtual void setClipRect(const Rect& clipRect);
|
||||||
|
virtual void setShaderProgram(PainterShaderProgram *shaderProgram) { m_shaderProgram = shaderProgram; }
|
||||||
|
virtual void setTexture(Texture *texture);
|
||||||
|
|
||||||
|
void setShaderProgram(const PainterShaderProgramPtr& shaderProgram) { setShaderProgram(shaderProgram.get()); }
|
||||||
|
void setTexture(const TexturePtr& texture) { setTexture(texture.get()); }
|
||||||
|
|
||||||
|
Matrix3 getProjectionMatrix() { return m_projectionMatrix; }
|
||||||
|
Matrix2 getTextureMatrix() { return m_textureMatrix; }
|
||||||
|
Color getColor() { return m_color; }
|
||||||
|
float getOpacity() { return m_opacity; }
|
||||||
|
CompositionMode getCompositionMode() { return m_compositionMode; }
|
||||||
|
Rect getClipRect() { return m_clipRect; }
|
||||||
|
PainterShaderProgram *getShaderProgram() { return m_shaderProgram; }
|
||||||
|
|
||||||
|
void resetColor() { setColor(Color::white); }
|
||||||
|
void resetOpacity() { setOpacity(1.0f); }
|
||||||
|
void resetClipRect() { setClipRect(Rect()); }
|
||||||
|
void resetCompositionMode() { setCompositionMode(CompositionMode_Normal); }
|
||||||
|
void resetShaderProgram() { setShaderProgram(nullptr); }
|
||||||
|
void resetTexture() { setTexture(nullptr); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateGlTexture();
|
||||||
|
void updateGlCompositionMode();
|
||||||
|
void updateGlClipRect();
|
||||||
|
|
||||||
|
CoordsBuffer m_coordsBuffer;
|
||||||
|
|
||||||
Matrix3 m_projectionMatrix;
|
Matrix3 m_projectionMatrix;
|
||||||
|
Matrix2 m_textureMatrix;
|
||||||
Color m_color;
|
Color m_color;
|
||||||
float m_opacity;
|
float m_opacity;
|
||||||
CompositionMode m_compostionMode;
|
CompositionMode m_compositionMode;
|
||||||
CoordsBuffer m_coordsBuffer;
|
|
||||||
Rect m_clipRect;
|
Rect m_clipRect;
|
||||||
|
Texture *m_texture;
|
||||||
|
PainterShaderProgram *m_shaderProgram;
|
||||||
|
|
||||||
PainterShaderProgram *m_oldCustomProgram;
|
PainterState m_olderStates[10];
|
||||||
Matrix3 m_oldProjectionMatrix;
|
int m_oldStateIndex;
|
||||||
Color m_oldColor;
|
|
||||||
float m_oldOpacity;
|
GLuint m_glTextureId;
|
||||||
Rect m_oldClipRect;
|
|
||||||
CompositionMode m_oldCompostionMode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Painter g_painter;
|
extern Painter *g_painter;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 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 "painterogl1.h"
|
||||||
|
#include "graphics.h"
|
||||||
|
|
||||||
|
PainterOGL1 *g_painterOGL1 = nullptr;
|
||||||
|
|
||||||
|
PainterOGL1::PainterOGL1()
|
||||||
|
{
|
||||||
|
m_matrixMode = GL_PROJECTION;
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::refreshState()
|
||||||
|
{
|
||||||
|
Painter::refreshState();
|
||||||
|
updateGlColor();
|
||||||
|
updateGlMatrixMode();
|
||||||
|
updateGlProjectionMatrix();
|
||||||
|
updateGlTextureMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::bind()
|
||||||
|
{
|
||||||
|
Painter::bind();
|
||||||
|
|
||||||
|
// vertex and texture coord arrays are always enabled
|
||||||
|
// to avoid massive enable/disables, thus improving frame rate
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::unbind()
|
||||||
|
{
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||||
|
{
|
||||||
|
int vertexCount = coordsBuffer.getVertexCount();
|
||||||
|
if(vertexCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool textured = coordsBuffer.getTextureCoordCount() != 0;
|
||||||
|
if(textured)
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
else
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
// use vertex arrays if possible, much faster
|
||||||
|
if(g_graphics.canUseDrawArrays()) {
|
||||||
|
// update coords buffer hardware caches if enabled
|
||||||
|
coordsBuffer.updateCaches();
|
||||||
|
bool hardwareCached = coordsBuffer.isHardwareCached();
|
||||||
|
|
||||||
|
// only set texture coords arrays when needed
|
||||||
|
if(textured) {
|
||||||
|
if(hardwareCached) {
|
||||||
|
coordsBuffer.getHardwareTextureCoordArray()->bind();
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
|
||||||
|
} else
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 0, coordsBuffer.getTextureCoordArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
// set vertex array
|
||||||
|
if(hardwareCached) {
|
||||||
|
coordsBuffer.getHardwareVertexArray()->bind();
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, nullptr);
|
||||||
|
} else
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, coordsBuffer.getVertexArray());
|
||||||
|
|
||||||
|
if(hardwareCached)
|
||||||
|
HardwareBuffer::unbind(HardwareBuffer::VertexBuffer);
|
||||||
|
|
||||||
|
// draw the element in coords buffers
|
||||||
|
glDrawArrays(drawMode, 0, vertexCount);
|
||||||
|
} else {
|
||||||
|
int verticesSize = vertexCount*2;
|
||||||
|
float *vertices = coordsBuffer.getVertexArray();
|
||||||
|
float *texCoords = coordsBuffer.getTextureCoordArray();
|
||||||
|
|
||||||
|
// use glBegin/glEnd, this is not available in OpenGL ES
|
||||||
|
// and is considered much slower then glDrawArrays,
|
||||||
|
// but this code is executed in really old graphics cards
|
||||||
|
glBegin(drawMode);
|
||||||
|
for(int i=0;i<verticesSize;i+=2) {
|
||||||
|
if(textured)
|
||||||
|
glTexCoord2f(texCoords[i], texCoords[i+1]);
|
||||||
|
glVertex2f(vertices[i], vertices[i+1]);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
||||||
|
{
|
||||||
|
if(!texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setTexture(texture.get());
|
||||||
|
drawCoords(coordsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addQuad(dest, src);
|
||||||
|
|
||||||
|
setTexture(texture.get());
|
||||||
|
drawCoords(m_coordsBuffer, TriangleStrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addRepeatedRects(dest, src);
|
||||||
|
|
||||||
|
setTexture(texture.get());
|
||||||
|
drawCoords(m_coordsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::drawFilledRect(const Rect& dest)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addRect(dest);
|
||||||
|
|
||||||
|
setTexture(nullptr);
|
||||||
|
drawCoords(m_coordsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::drawBoundingRect(const Rect& dest, int innerLineWidth)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || innerLineWidth == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addBoudingRect(dest, innerLineWidth);
|
||||||
|
|
||||||
|
setTexture(nullptr);
|
||||||
|
drawCoords(m_coordsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::setMatrixMode(PainterOGL1::MatrixMode matrixMode)
|
||||||
|
{
|
||||||
|
if(m_matrixMode == matrixMode)
|
||||||
|
return;
|
||||||
|
m_matrixMode = matrixMode;
|
||||||
|
updateGlMatrixMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::setProjectionMatrix(const Matrix3& projectionMatrix)
|
||||||
|
{
|
||||||
|
m_projectionMatrix = projectionMatrix;
|
||||||
|
updateGlProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::setTextureMatrix(const Matrix2& textureMatrix)
|
||||||
|
{
|
||||||
|
m_textureMatrix = textureMatrix;
|
||||||
|
updateGlTextureMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::setColor(const Color& color)
|
||||||
|
{
|
||||||
|
if(m_color == color)
|
||||||
|
return;
|
||||||
|
m_color = color;
|
||||||
|
updateGlColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::setOpacity(float opacity)
|
||||||
|
{
|
||||||
|
if(m_opacity == opacity)
|
||||||
|
return;
|
||||||
|
m_opacity = opacity;
|
||||||
|
updateGlColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::updateGlColor()
|
||||||
|
{
|
||||||
|
glColor4f(m_color.rF(), m_color.gF(), m_color.bF(), m_color.aF() * m_opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::updateGlMatrixMode()
|
||||||
|
{
|
||||||
|
glMatrixMode(m_matrixMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::updateGlProjectionMatrix()
|
||||||
|
{
|
||||||
|
float glProjectionMatrix[] = {
|
||||||
|
m_projectionMatrix(1,1), m_projectionMatrix(1,2), 0.0f, m_projectionMatrix(1,3),
|
||||||
|
m_projectionMatrix(2,1), m_projectionMatrix(2,2), 0.0f, m_projectionMatrix(2,3),
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
m_projectionMatrix(3,1), m_projectionMatrix(3,2), 0.0f, m_projectionMatrix(3,3),
|
||||||
|
};
|
||||||
|
|
||||||
|
setMatrixMode(MatrixProjection);
|
||||||
|
glLoadMatrixf(glProjectionMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::updateGlTextureMatrix()
|
||||||
|
{
|
||||||
|
float glTextureMatrix[] = {
|
||||||
|
m_textureMatrix(1,1), m_textureMatrix(1,2), 0.0f, 0.0f,
|
||||||
|
m_textureMatrix(2,1), m_textureMatrix(2,2), 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
setMatrixMode(MatrixTexture);
|
||||||
|
glLoadMatrixf(glTextureMatrix);
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 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 PAINTEROGL1_H
|
||||||
|
#define PAINTEROGL1_H
|
||||||
|
|
||||||
|
#include "painter.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Painter using OpenGL 1.0 fixed-function rendering pipeline,
|
||||||
|
* compatible with OpenGL ES 1.0 and intended to be used on
|
||||||
|
* older graphics cards. Shaders are not available
|
||||||
|
* for this painter engine.
|
||||||
|
*/
|
||||||
|
class PainterOGL1 : public Painter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum MatrixMode {
|
||||||
|
MatrixProjection = GL_PROJECTION,
|
||||||
|
MatrixTexture = GL_TEXTURE
|
||||||
|
};
|
||||||
|
|
||||||
|
PainterOGL1();
|
||||||
|
|
||||||
|
void bind();
|
||||||
|
void unbind();
|
||||||
|
|
||||||
|
void refreshState();
|
||||||
|
|
||||||
|
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||||
|
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
||||||
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawFilledRect(const Rect& dest);
|
||||||
|
void drawBoundingRect(const Rect& dest, int innerLineWidth);
|
||||||
|
|
||||||
|
void setMatrixMode(MatrixMode matrixMode);
|
||||||
|
void setProjectionMatrix(const Matrix3& projectionMatrix);
|
||||||
|
void setTextureMatrix(const Matrix2& textureMatrix);
|
||||||
|
void setColor(const Color& color);
|
||||||
|
void setOpacity(float opacity);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateGlColor();
|
||||||
|
void updateGlMatrixMode();
|
||||||
|
void updateGlProjectionMatrix();
|
||||||
|
void updateGlTextureMatrix();
|
||||||
|
|
||||||
|
GLenum m_matrixMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PainterOGL1 *g_painterOGL1;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 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 "painterogl2.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "paintershadermanager.h"
|
||||||
|
|
||||||
|
PainterOGL2 *g_painterOGL2 = nullptr;
|
||||||
|
|
||||||
|
PainterOGL2::PainterOGL2()
|
||||||
|
{
|
||||||
|
m_drawProgram = nullptr;
|
||||||
|
resetState();
|
||||||
|
|
||||||
|
g_shaders.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
PainterOGL2::~PainterOGL2()
|
||||||
|
{
|
||||||
|
g_shaders.terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::bind()
|
||||||
|
{
|
||||||
|
Painter::bind();
|
||||||
|
|
||||||
|
// vertex and texture coord attributes are always enabled
|
||||||
|
// to avoid massive enable/disables, thus improving frame rate
|
||||||
|
PainterShaderProgram::enableAttributeArray(PainterShaderProgram::VERTEX_ATTR);
|
||||||
|
PainterShaderProgram::enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::unbind()
|
||||||
|
{
|
||||||
|
PainterShaderProgram::disableAttributeArray(PainterShaderProgram::VERTEX_ATTR);
|
||||||
|
PainterShaderProgram::disableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR);
|
||||||
|
PainterShaderProgram::release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||||
|
{
|
||||||
|
int vertexCount = coordsBuffer.getVertexCount();
|
||||||
|
if(vertexCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool textured = coordsBuffer.getTextureCoordCount() > 0;
|
||||||
|
|
||||||
|
// update shader with the current painter state
|
||||||
|
m_drawProgram->bind();
|
||||||
|
m_drawProgram->setProjectionMatrix(m_projectionMatrix);
|
||||||
|
if(textured)
|
||||||
|
m_drawProgram->setTextureMatrix(m_textureMatrix);
|
||||||
|
m_drawProgram->setOpacity(m_opacity);
|
||||||
|
m_drawProgram->setColor(m_color);
|
||||||
|
m_drawProgram->updateTime();
|
||||||
|
|
||||||
|
// update coords buffer hardware caches if enabled
|
||||||
|
coordsBuffer.updateCaches();
|
||||||
|
bool hardwareCached = coordsBuffer.isHardwareCached();
|
||||||
|
|
||||||
|
// only set texture coords arrays when needed
|
||||||
|
if(textured) {
|
||||||
|
if(hardwareCached) {
|
||||||
|
coordsBuffer.getHardwareTextureCoordArray()->bind();
|
||||||
|
m_drawProgram->setAttributeArray(PainterShaderProgram::TEXCOORD_ATTR, nullptr, 2);
|
||||||
|
} else
|
||||||
|
m_drawProgram->setAttributeArray(PainterShaderProgram::TEXCOORD_ATTR, coordsBuffer.getTextureCoordArray(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set vertex array
|
||||||
|
if(hardwareCached) {
|
||||||
|
coordsBuffer.getHardwareVertexArray()->bind();
|
||||||
|
m_drawProgram->setAttributeArray(PainterShaderProgram::VERTEX_ATTR, nullptr, 2);
|
||||||
|
HardwareBuffer::unbind(HardwareBuffer::VertexBuffer);
|
||||||
|
} else
|
||||||
|
m_drawProgram->setAttributeArray(PainterShaderProgram::VERTEX_ATTR, coordsBuffer.getVertexArray(), 2);
|
||||||
|
|
||||||
|
// draw the element in coords buffers
|
||||||
|
glDrawArrays(drawMode, 0, vertexCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
||||||
|
{
|
||||||
|
if(!texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||||
|
setTexture(texture);
|
||||||
|
drawCoords(coordsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addQuad(dest, src);
|
||||||
|
|
||||||
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||||
|
setTexture(texture);
|
||||||
|
drawCoords(m_coordsBuffer, TriangleStrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addRepeatedRects(dest, src);
|
||||||
|
|
||||||
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||||
|
setTexture(texture);
|
||||||
|
drawCoords(m_coordsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::drawFilledRect(const Rect& dest)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addRect(dest);
|
||||||
|
|
||||||
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawSolidColorProgram().get());
|
||||||
|
drawCoords(m_coordsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::drawBoundingRect(const Rect& dest, int innerLineWidth)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || innerLineWidth == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addBoudingRect(dest, innerLineWidth);
|
||||||
|
|
||||||
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawSolidColorProgram().get());
|
||||||
|
drawCoords(m_coordsBuffer);
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 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 PAINTEROGL2_H
|
||||||
|
#define PAINTEROGL2_H
|
||||||
|
|
||||||
|
#include "painter.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Painter using OpenGL 2.0 programmable rendering pipeline,
|
||||||
|
* compatible with OpenGL ES 2.0. Only recent cards support
|
||||||
|
* this painter engine.
|
||||||
|
*/
|
||||||
|
class PainterOGL2 : public Painter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PainterOGL2();
|
||||||
|
~PainterOGL2();
|
||||||
|
|
||||||
|
void bind();
|
||||||
|
void unbind();
|
||||||
|
|
||||||
|
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||||
|
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
||||||
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawFilledRect(const Rect& dest);
|
||||||
|
void drawBoundingRect(const Rect& dest, int innerLineWidth = 1);
|
||||||
|
|
||||||
|
void setDrawProgram(PainterShaderProgram *drawProgram) { m_drawProgram = drawProgram; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PainterShaderProgram *m_drawProgram;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PainterOGL2 *g_painterOGL2;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const std::string glslMainVertexShader = "\n\
|
||||||
|
highp vec4 calculatePosition();\n\
|
||||||
|
void main() {\n\
|
||||||
|
gl_Position = calculatePosition();\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const std::string glslMainWithTexCoordsVertexShader = "\n\
|
||||||
|
attribute highp vec2 a_texCoord;\n\
|
||||||
|
uniform highp mat2 textureMatrix;\n\
|
||||||
|
varying highp vec2 texCoord;\n\
|
||||||
|
highp vec4 calculatePosition();\n\
|
||||||
|
void main()\n\
|
||||||
|
{\n\
|
||||||
|
gl_Position = calculatePosition();\n\
|
||||||
|
texCoord = textureMatrix * a_texCoord;\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static std::string glslPositionOnlyVertexShader = "\n\
|
||||||
|
attribute highp vec2 a_vertex;\n\
|
||||||
|
uniform highp mat3 projectionMatrix;\n\
|
||||||
|
highp vec4 calculatePosition() {\n\
|
||||||
|
return vec4(projectionMatrix * vec3(a_vertex.xy, 1), 1);\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const std::string glslMainFragmentShader = "\n\
|
||||||
|
uniform lowp float opacity;\n\
|
||||||
|
lowp vec4 calculatePixel();\n\
|
||||||
|
void main()\n\
|
||||||
|
{\n\
|
||||||
|
gl_FragColor = calculatePixel();\n\
|
||||||
|
gl_FragColor.a *= opacity;\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const std::string glslTextureSrcFragmentShader = "\n\
|
||||||
|
varying mediump vec2 texCoord;\n\
|
||||||
|
uniform lowp vec4 color;\n\
|
||||||
|
uniform sampler2D tex0;\n\
|
||||||
|
lowp vec4 calculatePixel() {\n\
|
||||||
|
return texture2D(tex0, texCoord) * color;\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const std::string glslSolidColorFragmentShader = "\n\
|
||||||
|
uniform lowp vec4 color;\n\
|
||||||
|
lowp vec4 calculatePixel() {\n\
|
||||||
|
return color;\n\
|
||||||
|
}\n";
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 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 "paintershadermanager.h"
|
||||||
|
#include "painterogl2.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "painterogl2_shadersources.h"
|
||||||
|
#include "paintershaderprogram.h"
|
||||||
|
#include "shaderprogram.h"
|
||||||
|
#include "graphics.h"
|
||||||
|
|
||||||
|
PainterShaderManager g_shaders;
|
||||||
|
|
||||||
|
void PainterShaderManager::init()
|
||||||
|
{
|
||||||
|
m_drawTexturedProgram = createShader();
|
||||||
|
assert(m_drawTexturedProgram);
|
||||||
|
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||||
|
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader);
|
||||||
|
m_drawTexturedProgram->link();
|
||||||
|
|
||||||
|
m_drawSolidColorProgram = createShader();
|
||||||
|
assert(m_drawSolidColorProgram);
|
||||||
|
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader);
|
||||||
|
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader);
|
||||||
|
m_drawSolidColorProgram->link();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderManager::terminate()
|
||||||
|
{
|
||||||
|
m_drawTexturedProgram = nullptr;
|
||||||
|
m_drawSolidColorProgram = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PainterShaderProgramPtr PainterShaderManager::createShader()
|
||||||
|
{
|
||||||
|
if(!g_graphics.canUseShaders())
|
||||||
|
return nullptr;
|
||||||
|
return PainterShaderProgramPtr(new PainterShaderProgram);
|
||||||
|
}
|
||||||
|
|
||||||
|
PainterShaderProgramPtr PainterShaderManager::createTexturedFragmentShader(const std::string& shaderFile)
|
||||||
|
{
|
||||||
|
PainterShaderProgramPtr shader = createShader();
|
||||||
|
if(!shader)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
shader->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||||
|
shader->addShaderFromSourceFile(Shader::Fragment, shaderFile);
|
||||||
|
|
||||||
|
if(!shader->link())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 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 PAINTERSHADERMANAGER_H
|
||||||
|
#define PAINTERSHADERMANAGER_H
|
||||||
|
|
||||||
|
#include "paintershaderprogram.h"
|
||||||
|
|
||||||
|
class PainterShaderManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void terminate();
|
||||||
|
|
||||||
|
PainterShaderProgramPtr createShader();
|
||||||
|
PainterShaderProgramPtr createTexturedFragmentShader(const std::string& shaderFile);
|
||||||
|
|
||||||
|
const PainterShaderProgramPtr& getDrawTexturedProgram() { return m_drawTexturedProgram; }
|
||||||
|
const PainterShaderProgramPtr& getDrawSolidColorProgram() { return m_drawSolidColorProgram; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PainterShaderProgramPtr m_drawTexturedProgram;
|
||||||
|
PainterShaderProgramPtr m_drawSolidColorProgram;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PainterShaderManager g_shaders;
|
||||||
|
|
||||||
|
#endif
|
|
@ -32,8 +32,6 @@ PainterShaderProgram::PainterShaderProgram()
|
||||||
m_opacity = 1;
|
m_opacity = 1;
|
||||||
m_color = Color::white;
|
m_color = Color::white;
|
||||||
m_time = 0;
|
m_time = 0;
|
||||||
m_lastTexture = -1;
|
|
||||||
m_textures.fill(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PainterShaderProgram::link()
|
bool PainterShaderProgram::link()
|
||||||
|
@ -43,7 +41,7 @@ bool PainterShaderProgram::link()
|
||||||
bindAttributeLocation(TEXCOORD_ATTR, "a_texCoord");
|
bindAttributeLocation(TEXCOORD_ATTR, "a_texCoord");
|
||||||
if(ShaderProgram::link()) {
|
if(ShaderProgram::link()) {
|
||||||
bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "projectionMatrix");
|
bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "projectionMatrix");
|
||||||
bindUniformLocation(TEXTURE_TRANSFORM_MATRIX_UNIFORM, "texTransformMatrix");
|
bindUniformLocation(TEXTURE_MATRIX_UNIFORM, "textureMatrix");
|
||||||
bindUniformLocation(COLOR_UNIFORM, "color");
|
bindUniformLocation(COLOR_UNIFORM, "color");
|
||||||
bindUniformLocation(OPACITY_UNIFORM, "opacity");
|
bindUniformLocation(OPACITY_UNIFORM, "opacity");
|
||||||
bindUniformLocation(TIME_UNIFORM, "time");
|
bindUniformLocation(TIME_UNIFORM, "time");
|
||||||
|
@ -52,15 +50,13 @@ bool PainterShaderProgram::link()
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix);
|
setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix);
|
||||||
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, m_textureTransformMatrix);
|
setUniformValue(TEXTURE_MATRIX_UNIFORM, m_textureMatrix);
|
||||||
setUniformValue(COLOR_UNIFORM, m_color);
|
setUniformValue(COLOR_UNIFORM, m_color);
|
||||||
setUniformValue(OPACITY_UNIFORM, m_opacity);
|
setUniformValue(OPACITY_UNIFORM, m_opacity);
|
||||||
setUniformValue(TIME_UNIFORM, m_time);
|
setUniformValue(TIME_UNIFORM, m_time);
|
||||||
setUniformValue(TEX0_UNIFORM, 0);
|
setUniformValue(TEX0_UNIFORM, 0);
|
||||||
setUniformValue(TEX1_UNIFORM, 1);
|
setUniformValue(TEX1_UNIFORM, 1);
|
||||||
|
release();
|
||||||
enableAttributeArray(PainterShaderProgram::VERTEX_ATTR);
|
|
||||||
enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -76,6 +72,16 @@ void PainterShaderProgram::setProjectionMatrix(const Matrix3& projectionMatrix)
|
||||||
m_projectionMatrix = projectionMatrix;
|
m_projectionMatrix = projectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::setTextureMatrix(const Matrix2& textureMatrix)
|
||||||
|
{
|
||||||
|
if(textureMatrix == m_textureMatrix)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
setUniformValue(TEXTURE_MATRIX_UNIFORM, textureMatrix);
|
||||||
|
m_textureMatrix = textureMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
void PainterShaderProgram::setColor(const Color& color)
|
void PainterShaderProgram::setColor(const Color& color)
|
||||||
{
|
{
|
||||||
if(color == m_color)
|
if(color == m_color)
|
||||||
|
@ -96,68 +102,13 @@ void PainterShaderProgram::setOpacity(float opacity)
|
||||||
m_opacity = opacity;
|
m_opacity = opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterShaderProgram::setTexture(const TexturePtr& texture, int index)
|
void PainterShaderProgram::updateTime()
|
||||||
{
|
{
|
||||||
assert(index >= 0 && index <= 1);
|
float time = g_clock.timeElapsed(m_startTime);
|
||||||
|
if(m_time == time)
|
||||||
uint texId = texture ? texture->getId() : 0;
|
|
||||||
|
|
||||||
if(m_textures[index] == texId)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_textures[index] = texId;
|
|
||||||
m_lastTexture = std::max(m_lastTexture, index);
|
|
||||||
|
|
||||||
if(texture && index == 0) {
|
|
||||||
const Matrix2& textureTransformMatrix = texture->getTransformMatrix();
|
|
||||||
if(m_textureTransformMatrix != textureTransformMatrix) {
|
|
||||||
bind();
|
bind();
|
||||||
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix);
|
|
||||||
m_textureTransformMatrix = textureTransformMatrix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PainterShaderProgram::draw(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
|
||||||
{
|
|
||||||
bind();
|
|
||||||
|
|
||||||
float time = g_clock.timeElapsed(m_startTime);
|
|
||||||
if(m_time != time) {
|
|
||||||
setUniformValue(TIME_UNIFORM, time);
|
setUniformValue(TIME_UNIFORM, time);
|
||||||
m_time = time;
|
m_time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vertexCount = coordsBuffer.getVertexCount();
|
|
||||||
if(vertexCount == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
coordsBuffer.updateCaches();
|
|
||||||
bool hardwareCached = coordsBuffer.isHardwareCached();
|
|
||||||
|
|
||||||
if(hardwareCached)
|
|
||||||
coordsBuffer.getHardwareVertexBuffer()->bind();
|
|
||||||
setAttributeArray(PainterShaderProgram::VERTEX_ATTR, hardwareCached ? 0 : coordsBuffer.getVertexBuffer(), 2);
|
|
||||||
|
|
||||||
bool hasTexture = coordsBuffer.getTextureVertexCount() != 0;
|
|
||||||
if(hasTexture) {
|
|
||||||
if(hardwareCached)
|
|
||||||
coordsBuffer.getHardwareTextureVertexBuffer()->bind();
|
|
||||||
setAttributeArray(PainterShaderProgram::TEXCOORD_ATTR, hardwareCached ? 0 : coordsBuffer.getTextureVertexBuffer(), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hardwareCached)
|
|
||||||
HardwareBuffer::unbind(HardwareBuffer::VertexBuffer);
|
|
||||||
|
|
||||||
if(m_lastTexture == 0) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_textures[0]);
|
|
||||||
} else {
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_textures[1]);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_textures[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDrawArrays(drawMode, 0, vertexCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,12 @@
|
||||||
|
|
||||||
class PainterShaderProgram : public ShaderProgram
|
class PainterShaderProgram : public ShaderProgram
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
enum {
|
enum {
|
||||||
VERTEX_ATTR = 0,
|
VERTEX_ATTR = 0,
|
||||||
TEXCOORD_ATTR = 1,
|
TEXCOORD_ATTR = 1,
|
||||||
PROJECTION_MATRIX_UNIFORM = 0,
|
PROJECTION_MATRIX_UNIFORM = 0,
|
||||||
TEXTURE_TRANSFORM_MATRIX_UNIFORM = 1,
|
TEXTURE_MATRIX_UNIFORM = 1,
|
||||||
COLOR_UNIFORM = 2,
|
COLOR_UNIFORM = 2,
|
||||||
OPACITY_UNIFORM = 3,
|
OPACITY_UNIFORM = 3,
|
||||||
TIME_UNIFORM = 4,
|
TIME_UNIFORM = 4,
|
||||||
|
@ -42,34 +43,28 @@ class PainterShaderProgram : public ShaderProgram
|
||||||
//TEX2_UNIFORM = 7,
|
//TEX2_UNIFORM = 7,
|
||||||
//TEX3_UNIFORM = 8,
|
//TEX3_UNIFORM = 8,
|
||||||
};
|
};
|
||||||
public:
|
|
||||||
enum DrawMode {
|
|
||||||
Triangles = GL_TRIANGLES,
|
|
||||||
TriangleStrip = GL_TRIANGLE_STRIP
|
|
||||||
};
|
|
||||||
|
|
||||||
|
friend class PainterOGL2;
|
||||||
|
|
||||||
|
public:
|
||||||
PainterShaderProgram();
|
PainterShaderProgram();
|
||||||
|
|
||||||
bool link();
|
bool link();
|
||||||
|
|
||||||
void setProjectionMatrix(const Matrix3& projectionMatrix);
|
void setProjectionMatrix(const Matrix3& projectionMatrix);
|
||||||
|
void setTextureMatrix(const Matrix2& textureMatrix);
|
||||||
void setColor(const Color& color);
|
void setColor(const Color& color);
|
||||||
void setOpacity(float opacity);
|
void setOpacity(float opacity);
|
||||||
void setTexture(const TexturePtr& texture, int index = 0);
|
void updateTime();
|
||||||
void setUniformTexture(int location, const TexturePtr& texture, int index);
|
|
||||||
void draw(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DrawMode m_drawMode;
|
|
||||||
float m_startTime;
|
float m_startTime;
|
||||||
std::array<uint, 2> m_textures;
|
|
||||||
|
|
||||||
Color m_color;
|
Color m_color;
|
||||||
float m_opacity;
|
float m_opacity;
|
||||||
Matrix3 m_projectionMatrix;
|
Matrix3 m_projectionMatrix;
|
||||||
Matrix2 m_textureTransformMatrix;
|
Matrix2 m_textureMatrix;
|
||||||
float m_time;
|
float m_time;
|
||||||
int m_lastTexture;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,14 +45,14 @@ Particle::Particle(const Point& pos, const Size& startSize, const Size& finalSiz
|
||||||
|
|
||||||
void Particle::render()
|
void Particle::render()
|
||||||
{
|
{
|
||||||
g_painter.setColor(m_color);
|
g_painter->setColor(m_color);
|
||||||
|
|
||||||
if(!m_texture)
|
if(!m_texture)
|
||||||
g_painter.drawFilledRect(m_rect);
|
g_painter->drawFilledRect(m_rect);
|
||||||
else {
|
else {
|
||||||
g_painter.setCompositionMode(m_compositionMode);
|
g_painter->setCompositionMode(m_compositionMode);
|
||||||
g_painter.drawTexturedRect(m_rect, m_texture);
|
g_painter->drawTexturedRect(m_rect, m_texture);
|
||||||
g_painter.setCompositionMode(Painter::CompositionMode_Normal);
|
g_painter->setCompositionMode(Painter::CompositionMode_Normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,8 @@ public:
|
||||||
static void release();
|
static void release();
|
||||||
std::string log();
|
std::string log();
|
||||||
|
|
||||||
void disableAttributeArray(int location) { glDisableVertexAttribArray(location); }
|
static void disableAttributeArray(int location) { glDisableVertexAttribArray(location); }
|
||||||
void enableAttributeArray(int location) { glEnableVertexAttribArray(location); }
|
static void enableAttributeArray(int location) { glEnableVertexAttribArray(location); }
|
||||||
void disableAttributeArray(const char *name) { glDisableVertexAttribArray(getAttributeLocation(name)); }
|
void disableAttributeArray(const char *name) { glDisableVertexAttribArray(getAttributeLocation(name)); }
|
||||||
void enableAttributeArray(const char *name) { glEnableVertexAttribArray(getAttributeLocation(name)); }
|
void enableAttributeArray(const char *name) { glEnableVertexAttribArray(getAttributeLocation(name)); }
|
||||||
|
|
||||||
|
|
|
@ -99,20 +99,23 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
||||||
|
|
||||||
void Texture::generateMipmaps()
|
void Texture::generateMipmaps()
|
||||||
{
|
{
|
||||||
if(g_graphics.canGenerateHardwareMipmaps())
|
if(!generateHardwareMipmaps()) {
|
||||||
generateHardwareMipmaps();
|
|
||||||
else {
|
|
||||||
// fallback to software mipmaps generation, this can be slow
|
// fallback to software mipmaps generation, this can be slow
|
||||||
//FIXME: disable because mipmaps size needs to be in base of 2,
|
//FIXME: disabled because mipmaps size needs to be in base of 2,
|
||||||
// and the current algorithmn does not support that
|
// and the current algorithmn does not support that
|
||||||
//generateSoftwareMipmaps(getPixels());
|
//generateSoftwareMipmaps(getPixels());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::generateHardwareMipmaps()
|
bool Texture::generateHardwareMipmaps()
|
||||||
{
|
{
|
||||||
if(!g_graphics.canGenerateHardwareMipmaps())
|
if(!g_graphics.canUseHardwareMipmaps())
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
|
#ifndef OPENGL_ES2
|
||||||
|
if(!GLEW_ARB_framebuffer_object)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
|
@ -122,6 +125,7 @@ void Texture::generateHardwareMipmaps()
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setSmooth(bool smooth)
|
void Texture::setSmooth(bool smooth)
|
||||||
|
@ -146,10 +150,10 @@ std::vector<uint8> Texture::getPixels()
|
||||||
FrameBufferPtr fb(new FrameBuffer(m_size));
|
FrameBufferPtr fb(new FrameBuffer(m_size));
|
||||||
fb->bind();
|
fb->bind();
|
||||||
fb->clear(Color::alpha);
|
fb->clear(Color::alpha);
|
||||||
g_painter.saveAndResetState();
|
g_painter->saveAndResetState();
|
||||||
g_painter.drawTexturedRect(Rect(0,0,m_size), shared_from_this());
|
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]);
|
glReadPixels(0, 0, m_size.width(), m_size.height(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
|
||||||
g_painter.restoreSavedState();
|
g_painter->restoreSavedState();
|
||||||
fb->release();
|
fb->release();
|
||||||
#else
|
#else
|
||||||
// copy pixels from opengl memory
|
// copy pixels from opengl memory
|
||||||
|
|
|
@ -36,15 +36,16 @@ public:
|
||||||
|
|
||||||
/// Tries to generate mipmaps via hardware, otherwise fallback to software implementation
|
/// Tries to generate mipmaps via hardware, otherwise fallback to software implementation
|
||||||
void generateMipmaps();
|
void generateMipmaps();
|
||||||
/// Generate mipmaps via hardware
|
/// Generate mipmaps via hardware if supported
|
||||||
void generateHardwareMipmaps();
|
bool generateHardwareMipmaps();
|
||||||
/// Generate mipmaps via software, which has a special algorithm for combining alpha pixels
|
/// Generate mipmaps via software, which has a special algorithm for combining alpha pixels
|
||||||
void generateSoftwareMipmaps(std::vector<uint8> inPixels);
|
void generateSoftwareMipmaps(std::vector<uint8> inPixels);
|
||||||
|
|
||||||
/// Activate texture altialising
|
/// Activate texture anti-aliasing giving a better look when they are resized
|
||||||
void setSmooth(bool smooth);
|
void setSmooth(bool smooth);
|
||||||
GLuint getId() { return m_textureId; }
|
GLuint getId() { return m_textureId; }
|
||||||
|
|
||||||
|
/// Return actual texture pixels
|
||||||
std::vector<uint8> getPixels();
|
std::vector<uint8> getPixels();
|
||||||
|
|
||||||
int getWidth() { return m_size.width(); }
|
int getWidth() { return m_size.width(); }
|
||||||
|
|
|
@ -47,7 +47,7 @@ void UIFrameCounter::drawSelf()
|
||||||
}
|
}
|
||||||
m_frameCount++;
|
m_frameCount++;
|
||||||
|
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
m_font->drawText(m_fpsText, m_rect, m_align);
|
m_font->drawText(m_fpsText, m_rect, m_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,9 @@ void UITextEdit::drawSelf()
|
||||||
int textLength = m_text.length();
|
int textLength = m_text.length();
|
||||||
const TexturePtr& texture = m_font->getTexture();
|
const TexturePtr& texture = m_font->getTexture();
|
||||||
|
|
||||||
g_painter.setColor(m_color);
|
g_painter->setColor(m_color);
|
||||||
for(int i=0;i<textLength;++i)
|
for(int i=0;i<textLength;++i)
|
||||||
g_painter.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||||
|
|
||||||
// render cursor
|
// render cursor
|
||||||
if(isExplicitlyEnabled() && (isActive() || m_alwaysActive) && m_cursorPos >= 0) {
|
if(isExplicitlyEnabled() && (isActive() || m_alwaysActive) && m_cursorPos >= 0) {
|
||||||
|
@ -69,7 +69,7 @@ void UITextEdit::drawSelf()
|
||||||
cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight());
|
cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight());
|
||||||
else
|
else
|
||||||
cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight());
|
cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight());
|
||||||
g_painter.drawFilledRect(cursorRect);
|
g_painter->drawFilledRect(cursorRect);
|
||||||
} else if(g_clock.ticksElapsed(m_cursorTicks) >= 2*delay) {
|
} else if(g_clock.ticksElapsed(m_cursorTicks) >= 2*delay) {
|
||||||
m_cursorTicks = g_clock.ticks();
|
m_cursorTicks = g_clock.ticks();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,19 +54,19 @@ UIWidget::~UIWidget()
|
||||||
void UIWidget::draw(const Rect& visibleRect)
|
void UIWidget::draw(const Rect& visibleRect)
|
||||||
{
|
{
|
||||||
if(m_clipping)
|
if(m_clipping)
|
||||||
g_painter.setClipRect(visibleRect);
|
g_painter->setClipRect(visibleRect);
|
||||||
|
|
||||||
drawSelf();
|
drawSelf();
|
||||||
|
|
||||||
if(m_children.size() > 0) {
|
if(m_children.size() > 0) {
|
||||||
if(m_clipping)
|
if(m_clipping)
|
||||||
g_painter.setClipRect(visibleRect.intersection(getClippingRect()));
|
g_painter->setClipRect(visibleRect.intersection(getClippingRect()));
|
||||||
|
|
||||||
drawChildren(visibleRect);
|
drawChildren(visibleRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_clipping)
|
if(m_clipping)
|
||||||
g_painter.resetClipRect();
|
g_painter->resetClipRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::drawSelf()
|
void UIWidget::drawSelf()
|
||||||
|
@ -97,22 +97,22 @@ void UIWidget::drawChildren(const Rect& visibleRect)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// store current graphics opacity
|
// store current graphics opacity
|
||||||
float oldOpacity = g_painter.getOpacity();
|
float oldOpacity = g_painter->getOpacity();
|
||||||
|
|
||||||
// decrease to self opacity
|
// decrease to self opacity
|
||||||
if(child->getOpacity() < oldOpacity)
|
if(child->getOpacity() < oldOpacity)
|
||||||
g_painter.setOpacity(child->getOpacity());
|
g_painter->setOpacity(child->getOpacity());
|
||||||
|
|
||||||
child->draw(childVisibleRect);
|
child->draw(childVisibleRect);
|
||||||
|
|
||||||
// debug draw box
|
// debug draw box
|
||||||
if(g_ui.isDrawingDebugBoxes()) {
|
if(g_ui.isDrawingDebugBoxes()) {
|
||||||
g_painter.setColor(Color::green);
|
g_painter->setColor(Color::green);
|
||||||
g_painter.drawBoundingRect(child->getRect());
|
g_painter->drawBoundingRect(child->getRect());
|
||||||
}
|
}
|
||||||
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Color::red);
|
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Color::red);
|
||||||
|
|
||||||
g_painter.setOpacity(oldOpacity);
|
g_painter->setOpacity(oldOpacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,8 +323,8 @@ void UIWidget::drawBackground(const Rect& screenCoords)
|
||||||
drawRect.translate(m_backgroundRect.topLeft());
|
drawRect.translate(m_backgroundRect.topLeft());
|
||||||
if(m_backgroundRect.isValid())
|
if(m_backgroundRect.isValid())
|
||||||
drawRect.resize(m_backgroundRect.size());
|
drawRect.resize(m_backgroundRect.size());
|
||||||
g_painter.setColor(m_backgroundColor);
|
g_painter->setColor(m_backgroundColor);
|
||||||
g_painter.drawFilledRect(drawRect);
|
g_painter->drawFilledRect(drawRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,31 +332,31 @@ void UIWidget::drawBorder(const Rect& screenCoords)
|
||||||
{
|
{
|
||||||
// top
|
// top
|
||||||
if(m_borderWidth.top > 0) {
|
if(m_borderWidth.top > 0) {
|
||||||
g_painter.setColor(m_borderColor.top);
|
g_painter->setColor(m_borderColor.top);
|
||||||
|
|
||||||
Rect borderRect(screenCoords.topLeft(), screenCoords.width(), m_borderWidth.top);
|
Rect borderRect(screenCoords.topLeft(), screenCoords.width(), m_borderWidth.top);
|
||||||
g_painter.drawFilledRect(borderRect);
|
g_painter->drawFilledRect(borderRect);
|
||||||
}
|
}
|
||||||
// right
|
// right
|
||||||
if(m_borderWidth.right > 0) {
|
if(m_borderWidth.right > 0) {
|
||||||
g_painter.setColor(m_borderColor.right);
|
g_painter->setColor(m_borderColor.right);
|
||||||
|
|
||||||
Rect borderRect(screenCoords.topRight() - Point(m_borderWidth.right - 1, 0), m_borderWidth.right, screenCoords.height());
|
Rect borderRect(screenCoords.topRight() - Point(m_borderWidth.right - 1, 0), m_borderWidth.right, screenCoords.height());
|
||||||
g_painter.drawFilledRect(borderRect);
|
g_painter->drawFilledRect(borderRect);
|
||||||
}
|
}
|
||||||
// bottom
|
// bottom
|
||||||
if(m_borderWidth.bottom > 0) {
|
if(m_borderWidth.bottom > 0) {
|
||||||
g_painter.setColor(m_borderColor.bottom);
|
g_painter->setColor(m_borderColor.bottom);
|
||||||
|
|
||||||
Rect borderRect(screenCoords.bottomLeft() - Point(0, m_borderWidth.bottom - 1), screenCoords.width(), m_borderWidth.bottom);
|
Rect borderRect(screenCoords.bottomLeft() - Point(0, m_borderWidth.bottom - 1), screenCoords.width(), m_borderWidth.bottom);
|
||||||
g_painter.drawFilledRect(borderRect);
|
g_painter->drawFilledRect(borderRect);
|
||||||
}
|
}
|
||||||
// left
|
// left
|
||||||
if(m_borderWidth.left > 0) {
|
if(m_borderWidth.left > 0) {
|
||||||
g_painter.setColor(m_borderColor.left);
|
g_painter->setColor(m_borderColor.left);
|
||||||
|
|
||||||
Rect borderRect(screenCoords.topLeft(), m_borderWidth.left, screenCoords.height());
|
Rect borderRect(screenCoords.topLeft(), m_borderWidth.left, screenCoords.height());
|
||||||
g_painter.drawFilledRect(borderRect);
|
g_painter->drawFilledRect(borderRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,8 +372,8 @@ void UIWidget::drawIcon(const Rect& screenCoords)
|
||||||
drawRect.resize(m_icon->getSize());
|
drawRect.resize(m_icon->getSize());
|
||||||
drawRect.moveCenter(screenCoords.center());
|
drawRect.moveCenter(screenCoords.center());
|
||||||
}
|
}
|
||||||
g_painter.setColor(m_iconColor);
|
g_painter->setColor(m_iconColor);
|
||||||
g_painter.drawTexturedRect(drawRect, m_icon);
|
g_painter->drawTexturedRect(drawRect, m_icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,8 +167,8 @@ void UIWidget::drawImage(const Rect& screenCoords)
|
||||||
|
|
||||||
m_imageTexture->setSmooth(m_imageSmooth);
|
m_imageTexture->setSmooth(m_imageSmooth);
|
||||||
|
|
||||||
g_painter.setColor(m_imageColor);
|
g_painter->setColor(m_imageColor);
|
||||||
g_painter.drawTextureCoords(m_imageCoordsBuffer, m_imageTexture);
|
g_painter->drawTextureCoords(m_imageCoordsBuffer, m_imageTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::setImageSource(const std::string& source)
|
void UIWidget::setImageSource(const std::string& source)
|
||||||
|
|
|
@ -87,8 +87,8 @@ void UIWidget::drawText(const Rect& screenCoords)
|
||||||
m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_drawText, screenCoords.translated(m_textOffset), m_textAlign);
|
m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_drawText, screenCoords.translated(m_textOffset), m_textAlign);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_painter.setColor(m_color);
|
g_painter->setColor(m_color);
|
||||||
g_painter.drawTextureCoords(m_textCoordsBuffer, m_font->getTexture());
|
g_painter->drawTextureCoords(m_textCoordsBuffer, m_font->getTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::onTextChange(const std::string& text, const std::string& oldText)
|
void UIWidget::onTextChange(const std::string& text, const std::string& oldText)
|
||||||
|
|
|
@ -23,7 +23,16 @@
|
||||||
#ifndef __COMPILER_H__
|
#ifndef __COMPILER_H__
|
||||||
#define __COMPILER_H__
|
#define __COMPILER_H__
|
||||||
|
|
||||||
|
#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||||
|
#error "sorry, you need gcc 4.6 or greater to compile"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
#error "sorry, you must enable C++0x to compile"
|
||||||
|
#endif
|
||||||
|
|
||||||
// hack to enable std::thread on mingw32 4.6
|
// hack to enable std::thread on mingw32 4.6
|
||||||
|
/*
|
||||||
#if !defined(_GLIBCXX_HAS_GTHREADS) && defined(__GNUG__)
|
#if !defined(_GLIBCXX_HAS_GTHREADS) && defined(__GNUG__)
|
||||||
#include <boost/thread/thread.hpp>
|
#include <boost/thread/thread.hpp>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
|
@ -45,5 +54,6 @@ namespace std {
|
||||||
using boost::condition_variable_any;
|
using boost::condition_variable_any;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,12 +40,11 @@ typedef int32_t int32;
|
||||||
typedef int16_t int16;
|
typedef int16_t int16;
|
||||||
typedef int8_t int8;
|
typedef int8_t int8;
|
||||||
|
|
||||||
// note that on 32 bit platforms the max ticks will overflow for valeus above 2,147,483,647
|
// note that on 32 bit platforms the max ticks will overflow for values above 2,147,483,647
|
||||||
// thus this means that the app may crash after running 24 days without restarting
|
// thus this means that the app may cause unknown behavior after running 24 days without restarting
|
||||||
typedef long ticks_t;
|
typedef long ticks_t;
|
||||||
|
|
||||||
typedef std::function<void()> SimpleCallback;
|
typedef std::function<void()> SimpleCallback;
|
||||||
typedef std::function<bool()> BooleanCallback;
|
|
||||||
|
|
||||||
// boolean with default value initializer
|
// boolean with default value initializer
|
||||||
template<bool def>
|
template<bool def>
|
||||||
|
|
|
@ -40,7 +40,7 @@ void AnimatedText::draw(const Point& dest, const Rect& visibleRect)
|
||||||
|
|
||||||
if(visibleRect.contains(rect)) {
|
if(visibleRect.contains(rect)) {
|
||||||
//TODO: cache into a framebuffer
|
//TODO: cache into a framebuffer
|
||||||
g_painter.setColor(m_color);
|
g_painter->setColor(m_color);
|
||||||
m_font->drawText(m_text, rect, Fw::AlignLeft);
|
m_font->drawText(m_text, rect, Fw::AlignLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <framework/core/clock.h>
|
#include <framework/core/clock.h>
|
||||||
|
|
||||||
#include <framework/graphics/paintershaderprogram.h>
|
#include <framework/graphics/paintershaderprogram.h>
|
||||||
#include <framework/graphics/paintershadersources.h>
|
#include <framework/graphics/painterogl2_shadersources.h>
|
||||||
#include <framework/graphics/texturemanager.h>
|
#include <framework/graphics/texturemanager.h>
|
||||||
#include <framework/graphics/framebuffer.h>
|
#include <framework/graphics/framebuffer.h>
|
||||||
#include "spritemanager.h"
|
#include "spritemanager.h"
|
||||||
|
@ -59,25 +59,27 @@ Creature::Creature() : Thing()
|
||||||
m_informationFont = g_fonts.getFont("verdana-11px-rounded");
|
m_informationFont = g_fonts.getFont("verdana-11px-rounded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
PainterShaderProgramPtr outfitProgram;
|
PainterShaderProgramPtr outfitProgram;
|
||||||
int HEAD_COLOR_UNIFORM = 10;
|
int HEAD_COLOR_UNIFORM = 10;
|
||||||
int BODY_COLOR_UNIFORM = 11;
|
int BODY_COLOR_UNIFORM = 11;
|
||||||
int LEGS_COLOR_UNIFORM = 12;
|
int LEGS_COLOR_UNIFORM = 12;
|
||||||
int FEET_COLOR_UNIFORM = 13;
|
int FEET_COLOR_UNIFORM = 13;
|
||||||
int MASK_TEXTURE_UNIFORM = 14;
|
int MASK_TEXTURE_UNIFORM = 14;
|
||||||
|
*/
|
||||||
|
|
||||||
void Creature::draw(const Point& dest, float scaleFactor, bool animate)
|
void Creature::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
{
|
{
|
||||||
Point animationOffset = animate ? m_walkOffset : Point(0,0);
|
Point animationOffset = animate ? m_walkOffset : Point(0,0);
|
||||||
|
|
||||||
if(m_showTimedSquare && animate) {
|
if(m_showTimedSquare && animate) {
|
||||||
g_painter.setColor(m_timedSquareColor);
|
g_painter->setColor(m_timedSquareColor);
|
||||||
g_painter.drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 3)*scaleFactor, Size(28, 28)*scaleFactor), std::max((int)(2*scaleFactor), 1));
|
g_painter->drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 3)*scaleFactor, Size(28, 28)*scaleFactor), std::max((int)(2*scaleFactor), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_showStaticSquare && animate) {
|
if(m_showStaticSquare && animate) {
|
||||||
g_painter.setColor(m_staticSquareColor);
|
g_painter->setColor(m_staticSquareColor);
|
||||||
g_painter.drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 1)*scaleFactor, Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS)*scaleFactor), std::max((int)(2*scaleFactor), 1));
|
g_painter->drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 1)*scaleFactor, Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS)*scaleFactor), std::max((int)(2*scaleFactor), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
internalDrawOutfit(dest + animationOffset * scaleFactor, scaleFactor, animate, animate, m_direction);
|
internalDrawOutfit(dest + animationOffset * scaleFactor, scaleFactor, animate, animate, m_direction);
|
||||||
|
@ -86,7 +88,8 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
|
|
||||||
void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction)
|
void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction)
|
||||||
{
|
{
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
|
/*
|
||||||
if(!outfitProgram) {
|
if(!outfitProgram) {
|
||||||
outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||||
outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||||
|
@ -97,6 +100,7 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
|
||||||
outfitProgram->bindUniformLocation(LEGS_COLOR_UNIFORM, "legsColor");
|
outfitProgram->bindUniformLocation(LEGS_COLOR_UNIFORM, "legsColor");
|
||||||
outfitProgram->bindUniformLocation(FEET_COLOR_UNIFORM, "feetColor");
|
outfitProgram->bindUniformLocation(FEET_COLOR_UNIFORM, "feetColor");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
int xPattern = 0, yPattern = 0, zPattern = 0;
|
int xPattern = 0, yPattern = 0, zPattern = 0;
|
||||||
|
|
||||||
|
@ -124,13 +128,15 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
|
||||||
if(yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern-1))))
|
if(yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern-1))))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
g_painter.setCustomProgram(outfitProgram);
|
/*
|
||||||
|
g_painter->setShaderProgram(outfitProgram);
|
||||||
|
|
||||||
outfitProgram->bind();
|
outfitProgram->bind();
|
||||||
outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
|
outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
|
||||||
outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
|
outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
|
||||||
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
|
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
|
||||||
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
|
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
|
||||||
|
*/
|
||||||
|
|
||||||
for(int h = 0; h < getDimensionHeight(); h++) {
|
for(int h = 0; h < getDimensionHeight(); h++) {
|
||||||
for(int w = 0; w < getDimensionWidth(); w++) {
|
for(int w = 0; w < getDimensionWidth(); w++) {
|
||||||
|
@ -140,14 +146,14 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
|
||||||
int maskId = getSpriteId(w, h, 1, xPattern, yPattern, zPattern, animationPhase);
|
int maskId = getSpriteId(w, h, 1, xPattern, yPattern, zPattern, animationPhase);
|
||||||
maskTex = g_sprites.getSpriteTexture(maskId);
|
maskTex = g_sprites.getSpriteTexture(maskId);
|
||||||
}
|
}
|
||||||
outfitProgram->setTexture(maskTex, 1);
|
//outfitProgram->setTexture(maskTex, 1);
|
||||||
|
|
||||||
internalDraw(dest + (-Point(w,h)*Otc::TILE_PIXELS)*scaleFactor,
|
internalDraw(dest + (-Point(w,h)*Otc::TILE_PIXELS)*scaleFactor,
|
||||||
scaleFactor, w, h, xPattern, yPattern, zPattern, 0, animationPhase);
|
scaleFactor, w, h, xPattern, yPattern, zPattern, 0, animationPhase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_painter.releaseCustomProgram();
|
//g_painter->resetShaderProgram();
|
||||||
}
|
}
|
||||||
// outfit is a creature imitating an item or the invisible effect
|
// outfit is a creature imitating an item or the invisible effect
|
||||||
} else {
|
} else {
|
||||||
|
@ -182,12 +188,12 @@ void Creature::drawOutfit(const Rect& destRect, bool resize)
|
||||||
if(!outfitBuffer)
|
if(!outfitBuffer)
|
||||||
outfitBuffer = FrameBufferPtr(new FrameBuffer(Size(2*Otc::TILE_PIXELS, 2*Otc::TILE_PIXELS)));
|
outfitBuffer = FrameBufferPtr(new FrameBuffer(Size(2*Otc::TILE_PIXELS, 2*Otc::TILE_PIXELS)));
|
||||||
|
|
||||||
g_painter.saveAndResetState();
|
g_painter->saveAndResetState();
|
||||||
outfitBuffer->bind();
|
outfitBuffer->bind();
|
||||||
outfitBuffer->clear(Color::alpha);
|
outfitBuffer->clear(Color::alpha);
|
||||||
internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South);
|
internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South);
|
||||||
outfitBuffer->release();
|
outfitBuffer->release();
|
||||||
g_painter.restoreSavedState();
|
g_painter->restoreSavedState();
|
||||||
|
|
||||||
if(resize) {
|
if(resize) {
|
||||||
Rect srcRect;
|
Rect srcRect;
|
||||||
|
@ -227,26 +233,26 @@ void Creature::drawInformation(const Point& point, bool useGray, const Rect& par
|
||||||
healthRect.setWidth((m_healthPercent / 100.0) * 25);
|
healthRect.setWidth((m_healthPercent / 100.0) * 25);
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
g_painter.setColor(Color::black);
|
g_painter->setColor(Color::black);
|
||||||
g_painter.drawFilledRect(backgroundRect);
|
g_painter->drawFilledRect(backgroundRect);
|
||||||
|
|
||||||
g_painter.setColor(fillColor);
|
g_painter->setColor(fillColor);
|
||||||
g_painter.drawFilledRect(healthRect);
|
g_painter->drawFilledRect(healthRect);
|
||||||
|
|
||||||
if(m_informationFont)
|
if(m_informationFont)
|
||||||
m_informationFont->drawText(m_name, textRect, Fw::AlignTopCenter);
|
m_informationFont->drawText(m_name, textRect, Fw::AlignTopCenter);
|
||||||
|
|
||||||
if(m_skull != Otc::SkullNone && m_skullTexture) {
|
if(m_skull != Otc::SkullNone && m_skullTexture) {
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
g_painter.drawTexturedRect(Rect(point.x + 12, point.y + 5, m_skullTexture->getSize()), m_skullTexture);
|
g_painter->drawTexturedRect(Rect(point.x + 12, point.y + 5, m_skullTexture->getSize()), m_skullTexture);
|
||||||
}
|
}
|
||||||
if(m_shield != Otc::ShieldNone && m_shieldTexture && m_showShieldTexture) {
|
if(m_shield != Otc::ShieldNone && m_shieldTexture && m_showShieldTexture) {
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
g_painter.drawTexturedRect(Rect(point.x, point.y + 5, m_shieldTexture->getSize()), m_shieldTexture);
|
g_painter->drawTexturedRect(Rect(point.x, point.y + 5, m_shieldTexture->getSize()), m_shieldTexture);
|
||||||
}
|
}
|
||||||
if(m_emblem != Otc::EmblemNone && m_emblemTexture) {
|
if(m_emblem != Otc::EmblemNone && m_emblemTexture) {
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
g_painter.drawTexturedRect(Rect(point.x + 12, point.y + 16, m_emblemTexture->getSize()), m_emblemTexture);
|
g_painter->drawTexturedRect(Rect(point.x + 12, point.y + 16, m_emblemTexture->getSize()), m_emblemTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
#include <framework/graphics/paintershaderprogram.h>
|
#include <framework/graphics/paintershaderprogram.h>
|
||||||
#include <framework/graphics/paintershadersources.h>
|
#include <framework/graphics/painterogl2_shadersources.h>
|
||||||
|
|
||||||
Item::Item() : Thing()
|
Item::Item() : Thing()
|
||||||
{
|
{
|
||||||
|
@ -50,9 +50,10 @@ ItemPtr Item::create(int id)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
PainterShaderProgramPtr itemProgram;
|
PainterShaderProgramPtr itemProgram;
|
||||||
int ITEM_ID_UNIFORM = 10;
|
int ITEM_ID_UNIFORM = 10;
|
||||||
|
*/
|
||||||
void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
{
|
{
|
||||||
if(m_id == 0)
|
if(m_id == 0)
|
||||||
|
@ -165,6 +166,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup item drawing shader
|
// setup item drawing shader
|
||||||
|
/*
|
||||||
if(!itemProgram) {
|
if(!itemProgram) {
|
||||||
itemProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
itemProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||||
itemProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
itemProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||||
|
@ -172,15 +174,16 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||||
itemProgram->link();
|
itemProgram->link();
|
||||||
itemProgram->bindUniformLocation(ITEM_ID_UNIFORM, "itemId");
|
itemProgram->bindUniformLocation(ITEM_ID_UNIFORM, "itemId");
|
||||||
}
|
}
|
||||||
g_painter.setCustomProgram(itemProgram);
|
g_painter->setShaderProgram(itemProgram);
|
||||||
//itemProgram->bind();
|
//itemProgram->bind();
|
||||||
//itemProgram->setUniformValue(ITEM_ID_UNIFORM, (int)m_id);
|
//itemProgram->setUniformValue(ITEM_ID_UNIFORM, (int)m_id);
|
||||||
|
*/
|
||||||
|
|
||||||
// now we can draw the item
|
// now we can draw the item
|
||||||
internalDraw(dest, scaleFactor, xPattern, yPattern, zPattern, animationPhase);
|
internalDraw(dest, scaleFactor, xPattern, yPattern, zPattern, animationPhase);
|
||||||
|
|
||||||
// release draw shader
|
// release draw shader
|
||||||
g_painter.releaseCustomProgram();
|
g_painter->resetShaderProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::setId(uint32 id)
|
void Item::setId(uint32 id)
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
|
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
#include <framework/graphics/framebuffer.h>
|
#include <framework/graphics/framebuffer.h>
|
||||||
#include <framework/graphics/paintershaderprogram.h>
|
#include <framework/graphics/paintershadermanager.h>
|
||||||
#include <framework/graphics/paintershadersources.h>
|
|
||||||
#include "creature.h"
|
#include "creature.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
@ -34,8 +33,6 @@
|
||||||
#include "missile.h"
|
#include "missile.h"
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
|
||||||
//int AWARE_AREA_UNIFORM = 10;
|
|
||||||
|
|
||||||
MapView::MapView()
|
MapView::MapView()
|
||||||
{
|
{
|
||||||
m_viewMode = NEAR_VIEW;
|
m_viewMode = NEAR_VIEW;
|
||||||
|
@ -47,11 +44,7 @@ MapView::MapView()
|
||||||
m_framebuffer = FrameBufferPtr(new FrameBuffer());
|
m_framebuffer = FrameBufferPtr(new FrameBuffer());
|
||||||
setVisibleDimension(Size(15, 11));
|
setVisibleDimension(Size(15, 11));
|
||||||
|
|
||||||
m_shaderProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
m_shaderProgram = g_shaders.createTexturedFragmentShader("/game_shaders/map.frag");
|
||||||
m_shaderProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
|
||||||
m_shaderProgram->addShaderFromSourceFile(Shader::Fragment, "/game_shaders/map.frag");
|
|
||||||
m_shaderProgram->link();
|
|
||||||
//m_shaderProgram->bindUniformLocation(AWARE_AREA_UNIFORM, "awareArea");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView::draw(const Rect& rect)
|
void MapView::draw(const Rect& rect)
|
||||||
|
@ -78,16 +71,15 @@ void MapView::draw(const Rect& rect)
|
||||||
|
|
||||||
Size tileSize = Size(1,1) * m_tileSize;
|
Size tileSize = Size(1,1) * m_tileSize;
|
||||||
if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) {
|
if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) {
|
||||||
g_painter.saveAndResetState();
|
|
||||||
m_framebuffer->bind();
|
m_framebuffer->bind();
|
||||||
|
|
||||||
if(m_mustCleanFramebuffer) {
|
if(m_mustCleanFramebuffer) {
|
||||||
Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize);
|
Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize);
|
||||||
|
|
||||||
// drawing a black rect is actually faster than FrameBuffer::clear()
|
// drawing a black rect is actually faster than FrameBuffer::clear()
|
||||||
g_painter.setColor(Color::black);
|
g_painter->setColor(Color::black);
|
||||||
g_painter.drawFilledRect(clearRect);
|
g_painter->drawFilledRect(clearRect);
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
|
|
||||||
// m_framebuffer->clear(Color::black);
|
// m_framebuffer->clear(Color::black);
|
||||||
}
|
}
|
||||||
|
@ -105,8 +97,8 @@ void MapView::draw(const Rect& rect)
|
||||||
if(!m_drawMinimapColors)
|
if(!m_drawMinimapColors)
|
||||||
tile->draw(transformPositionTo2D(tile->getPosition()), scaleFactor, drawFlags);
|
tile->draw(transformPositionTo2D(tile->getPosition()), scaleFactor, drawFlags);
|
||||||
else {
|
else {
|
||||||
g_painter.setColor(tile->getMinimapColor());
|
g_painter->setColor(tile->getMinimapColor());
|
||||||
g_painter.drawFilledRect(Rect(transformPositionTo2D(tile->getPosition()), tileSize));
|
g_painter->drawFilledRect(Rect(transformPositionTo2D(tile->getPosition()), tileSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +110,6 @@ void MapView::draw(const Rect& rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_framebuffer->release();
|
m_framebuffer->release();
|
||||||
g_painter.restoreSavedState();
|
|
||||||
|
|
||||||
// generating mipmaps each frame can be slow in older cards
|
// generating mipmaps each frame can be slow in older cards
|
||||||
//m_framebuffer->getTexture()->generateHardwareMipmaps();
|
//m_framebuffer->getTexture()->generateHardwareMipmaps();
|
||||||
|
@ -126,7 +117,7 @@ void MapView::draw(const Rect& rect)
|
||||||
m_mustDrawVisibleTilesCache = false;
|
m_mustDrawVisibleTilesCache = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_painter.setCustomProgram(m_shaderProgram);
|
//g_painter->setShaderProgram(m_shaderProgram);
|
||||||
|
|
||||||
Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * m_tileSize;
|
Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * m_tileSize;
|
||||||
if(m_followingCreature)
|
if(m_followingCreature)
|
||||||
|
@ -139,39 +130,20 @@ void MapView::draw(const Rect& rect)
|
||||||
drawOffset.y += (srcVisible.height() - srcSize.height()) / 2;
|
drawOffset.y += (srcVisible.height() - srcSize.height()) / 2;
|
||||||
Rect srcRect = Rect(drawOffset, srcSize);
|
Rect srcRect = Rect(drawOffset, srcSize);
|
||||||
|
|
||||||
/*
|
|
||||||
// pass aware area to the shader program
|
|
||||||
Rect awareRect;
|
|
||||||
if(m_followingCreature) {
|
|
||||||
Point awareOffset = transformPositionTo2D(m_followingCreature->getPosition().translated(-Otc::AWARE_X_LEFT_TILES + 1, -Otc::AWARE_Y_TOP_TILES + 1));
|
|
||||||
awareOffset += m_followingCreature->getWalkOffset() * scaleFactor;
|
|
||||||
|
|
||||||
awareRect.setTopLeft(awareOffset);
|
|
||||||
awareRect.resize(Otc::VISIBLE_X_TILES * m_tileSize, Otc::VISIBLE_Y_TILES * m_tileSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_shaderProgram->bind();
|
|
||||||
m_shaderProgram->setUniformValue(AWARE_AREA_UNIFORM,
|
|
||||||
awareRect.left()/(float)m_framebuffer->getSize().width(),
|
|
||||||
awareRect.top()/(float)m_framebuffer->getSize().height(),
|
|
||||||
awareRect.right()/(float)m_framebuffer->getSize().width(),
|
|
||||||
awareRect.bottom()/(float)m_framebuffer->getSize().height());
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// debug source area
|
// debug source area
|
||||||
g_painter.saveAndResetState();
|
g_painter->saveAndResetState();
|
||||||
m_framebuffer->bind();
|
m_framebuffer->bind();
|
||||||
g_painter.setColor(Color::green);
|
g_painter->setColor(Color::green);
|
||||||
g_painter.drawBoundingRect(srcRect, 2);
|
g_painter->drawBoundingRect(srcRect, 2);
|
||||||
m_framebuffer->release();
|
m_framebuffer->release();
|
||||||
g_painter.restoreSavedState();
|
g_painter->restoreSavedState();
|
||||||
m_framebuffer->draw(rect);
|
m_framebuffer->draw(rect);
|
||||||
#else
|
#else
|
||||||
m_framebuffer->draw(rect, srcRect);
|
m_framebuffer->draw(rect, srcRect);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_painter.releaseCustomProgram();
|
g_painter->resetShaderProgram();
|
||||||
|
|
||||||
// this could happen if the player position is not known yet
|
// this could happen if the player position is not known yet
|
||||||
if(!cameraPosition.isValid())
|
if(!cameraPosition.isValid())
|
||||||
|
@ -231,9 +203,9 @@ void MapView::draw(const Rect& rect)
|
||||||
Rect hRect(0, 0, 10, 2);
|
Rect hRect(0, 0, 10, 2);
|
||||||
vRect.moveCenter(rect.center());
|
vRect.moveCenter(rect.center());
|
||||||
hRect.moveCenter(rect.center());
|
hRect.moveCenter(rect.center());
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
g_painter.drawFilledRect(vRect);
|
g_painter->drawFilledRect(vRect);
|
||||||
g_painter.drawFilledRect(hRect);
|
g_painter->drawFilledRect(hRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ 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);
|
||||||
|
|
||||||
if(g_graphics.canGenerateMipmaps())
|
if(g_graphics.canUseMipmaps())
|
||||||
spriteTex->generateSoftwareMipmaps(pixels);
|
spriteTex->generateSoftwareMipmaps(pixels);
|
||||||
|
|
||||||
return spriteTex;
|
return spriteTex;
|
||||||
|
|
|
@ -40,7 +40,7 @@ void StaticText::draw(const Point& dest, const Rect& parentRect)
|
||||||
// draw only if the real center is not too far from the parent center, or its a yell
|
// draw only if the real center is not too far from the parent center, or its a yell
|
||||||
if((boundRect.center() - rect.center()).length() < parentRect.width() / 15 || isYell()) {
|
if((boundRect.center() - rect.center()).length() < parentRect.width() / 15 || isYell()) {
|
||||||
//TODO: cache into a framebuffer
|
//TODO: cache into a framebuffer
|
||||||
g_painter.setColor(m_color);
|
g_painter->setColor(m_color);
|
||||||
m_font->drawText(m_text, boundRect, Fw::AlignCenter);
|
m_font->drawText(m_text, boundRect, Fw::AlignCenter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,8 @@ void Thing::internalDraw(const Point& dest, float scaleFactor, int w, int h, int
|
||||||
int spriteId = getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animationPhase);
|
int spriteId = getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animationPhase);
|
||||||
if(spriteId) {
|
if(spriteId) {
|
||||||
Rect drawRect(dest - getDisplacement()*scaleFactor, Size(scaledSize, scaledSize));
|
Rect drawRect(dest - getDisplacement()*scaleFactor, Size(scaledSize, scaledSize));
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
g_painter.drawTexturedRect(drawRect, g_sprites.getSpriteTexture(spriteId));
|
g_painter->drawTexturedRect(drawRect, g_sprites.getSpriteTexture(spriteId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ void UICreature::drawSelf()
|
||||||
UIWidget::drawSelf();
|
UIWidget::drawSelf();
|
||||||
|
|
||||||
if(m_creature) {
|
if(m_creature) {
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
Rect drawRect = getClippingRect();
|
Rect drawRect = getClippingRect();
|
||||||
m_creature->drawOutfit(drawRect, !m_fixedCreatureSize);
|
m_creature->drawOutfit(drawRect, !m_fixedCreatureSize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,12 @@ void UIItem::drawSelf()
|
||||||
dest += (1 - scaleFactor)*32;
|
dest += (1 - scaleFactor)*32;
|
||||||
dest += m_item->getDisplacement() * scaleFactor;
|
dest += m_item->getDisplacement() * scaleFactor;
|
||||||
|
|
||||||
g_painter.setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
m_item->draw(dest, scaleFactor, true);
|
m_item->draw(dest, scaleFactor, true);
|
||||||
|
|
||||||
if(m_font && m_item->isStackable() && m_item->getCount() > 1) {
|
if(m_font && m_item->isStackable() && m_item->getCount() > 1) {
|
||||||
std::string count = Fw::tostring(m_item->getCount());
|
std::string count = Fw::tostring(m_item->getCount());
|
||||||
g_painter.setColor(Color(231, 231, 231));
|
g_painter->setColor(Color(231, 231, 231));
|
||||||
m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight);
|
m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight);
|
||||||
}
|
}
|
||||||
//m_font->drawText(Fw::tostring(m_item->getId()), m_rect, Fw::AlignBottomRight);
|
//m_font->drawText(Fw::tostring(m_item->getId()), m_rect, Fw::AlignBottomRight);
|
||||||
|
|
|
@ -49,9 +49,10 @@ void UIMap::drawSelf()
|
||||||
UIWidget::drawSelf();
|
UIWidget::drawSelf();
|
||||||
|
|
||||||
// draw map border
|
// draw map border
|
||||||
g_painter.setColor(Color::black);
|
g_painter->setColor(Color::black);
|
||||||
g_painter.drawBoundingRect(m_mapRect.expanded(1));
|
g_painter->drawBoundingRect(m_mapRect.expanded(1));
|
||||||
|
|
||||||
|
g_painter->setColor(Color::white);
|
||||||
m_mapView->draw(m_mapRect);
|
m_mapView->draw(m_mapRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue