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
|
||||
//uniform vec4 awareArea;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(tex0, texCoord);
|
||||
|
@ -84,3 +85,21 @@ void main()
|
|||
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/graphics.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/framebuffer.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/shaderprogram.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershadermanager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/coordsbuffer.cpp
|
||||
|
||||
# framework sound
|
||||
|
|
|
@ -45,7 +45,6 @@ ticks_t Clock::asyncTicks()
|
|||
return std::chrono::duration_cast<std::chrono::milliseconds>(timeNow - m_startupTime).count();
|
||||
}
|
||||
|
||||
|
||||
void Clock::sleep(int ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
|
|
|
@ -23,13 +23,7 @@
|
|||
#ifndef FRAMEWORK_GLOBAL_H
|
||||
#define FRAMEWORK_GLOBAL_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
|
||||
#include "util/compiler.h"
|
||||
|
||||
// common C/C++ headers
|
||||
#include "pch.h"
|
||||
|
@ -38,7 +32,6 @@
|
|||
#include "const.h"
|
||||
|
||||
// additional utilities
|
||||
#include "util/compiler.h"
|
||||
#include "util/types.h"
|
||||
#include "util/tools.h"
|
||||
#include "math/point.h"
|
||||
|
|
|
@ -26,18 +26,18 @@
|
|||
CoordsBuffer::CoordsBuffer()
|
||||
{
|
||||
m_hardwareCacheMode = HardwareBuffer::DynamicDraw;
|
||||
m_hardwareVertexBuffer = nullptr;
|
||||
m_hardwareTextureVertexBuffer = nullptr;
|
||||
m_hardwareVertexArray = nullptr;
|
||||
m_hardwareTextureCoordArray = nullptr;
|
||||
m_hardwareCached = false;
|
||||
m_hardwareCaching = false;
|
||||
}
|
||||
|
||||
CoordsBuffer::~CoordsBuffer()
|
||||
{
|
||||
if(m_hardwareVertexBuffer)
|
||||
delete m_hardwareVertexBuffer;
|
||||
if(m_hardwareTextureVertexBuffer)
|
||||
delete m_hardwareTextureVertexBuffer;
|
||||
if(m_hardwareVertexArray)
|
||||
delete m_hardwareVertexArray;
|
||||
if(m_hardwareTextureCoordArray)
|
||||
delete m_hardwareTextureCoordArray;
|
||||
}
|
||||
|
||||
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());
|
||||
m_vertexBuffer.addRect(partialDest);
|
||||
m_textureVertexBuffer.addRect(partialSrc);
|
||||
m_vertexArray.addRect(partialDest);
|
||||
m_textureCoordArray.addRect(partialSrc);
|
||||
}
|
||||
}
|
||||
m_hardwareCached = false;
|
||||
|
@ -90,10 +90,6 @@ void CoordsBuffer::enableHardwareCaching(HardwareBuffer::UsagePattern usagePatte
|
|||
if(!g_graphics.canUseHardwareBuffers())
|
||||
return;
|
||||
|
||||
#ifndef OPENGL_ES2
|
||||
if(!GL_ARB_vertex_buffer_object)
|
||||
return;
|
||||
#endif
|
||||
m_hardwareCacheMode = usagePattern;
|
||||
m_hardwareCaching = true;
|
||||
m_hardwareCached = false;
|
||||
|
@ -104,18 +100,18 @@ void CoordsBuffer::updateCaches()
|
|||
if(!m_hardwareCaching || m_hardwareCached)
|
||||
return;
|
||||
|
||||
if(m_vertexBuffer.vertexCount() > 0) {
|
||||
if(!m_hardwareVertexBuffer && m_vertexBuffer.vertexCount() > 0)
|
||||
m_hardwareVertexBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||
m_hardwareVertexBuffer->bind();
|
||||
m_hardwareVertexBuffer->write((void*)m_vertexBuffer.vertices(), m_vertexBuffer.size() * sizeof(float), m_hardwareCacheMode);
|
||||
if(m_vertexArray.vertexCount() > 0) {
|
||||
if(!m_hardwareVertexArray && m_vertexArray.vertexCount() > 0)
|
||||
m_hardwareVertexArray = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||
m_hardwareVertexArray->bind();
|
||||
m_hardwareVertexArray->write((void*)m_vertexArray.vertices(), m_vertexArray.size() * sizeof(float), m_hardwareCacheMode);
|
||||
}
|
||||
|
||||
if(m_textureVertexBuffer.vertexCount() > 0) {
|
||||
if(!m_hardwareTextureVertexBuffer && m_textureVertexBuffer.vertexCount() > 0)
|
||||
m_hardwareTextureVertexBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||
m_hardwareTextureVertexBuffer->bind();
|
||||
m_hardwareTextureVertexBuffer->write((void*)m_textureVertexBuffer.vertices(), m_textureVertexBuffer.size() * sizeof(float), m_hardwareCacheMode);
|
||||
if(m_textureCoordArray.vertexCount() > 0) {
|
||||
if(!m_hardwareTextureCoordArray && m_textureCoordArray.vertexCount() > 0)
|
||||
m_hardwareTextureCoordArray = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||
m_hardwareTextureCoordArray->bind();
|
||||
m_hardwareTextureCoordArray->write((void*)m_textureCoordArray.vertices(), m_textureCoordArray.size() * sizeof(float), m_hardwareCacheMode);
|
||||
}
|
||||
|
||||
m_hardwareCached = true;
|
||||
|
|
|
@ -33,23 +33,23 @@ public:
|
|||
~CoordsBuffer();
|
||||
|
||||
void clear() {
|
||||
m_textureVertexBuffer.clear();
|
||||
m_vertexBuffer.clear();
|
||||
m_textureCoordArray.clear();
|
||||
m_vertexArray.clear();
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
|
||||
void addRect(const Rect& dest) {
|
||||
m_vertexBuffer.addRect(dest);
|
||||
m_vertexArray.addRect(dest);
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
void addRect(const Rect& dest, const Rect& src) {
|
||||
m_vertexBuffer.addRect(dest);
|
||||
m_textureVertexBuffer.addRect(src);
|
||||
m_vertexArray.addRect(dest);
|
||||
m_textureCoordArray.addRect(src);
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
void addQuad(const Rect& dest, const Rect& src) {
|
||||
m_vertexBuffer.addQuad(dest);
|
||||
m_textureVertexBuffer.addQuad(src);
|
||||
m_vertexArray.addQuad(dest);
|
||||
m_textureCoordArray.addQuad(src);
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
|
||||
|
@ -60,20 +60,20 @@ public:
|
|||
void updateCaches();
|
||||
bool isHardwareCached() { return m_hardwareCached; }
|
||||
|
||||
float *getVertexBuffer() const { return m_vertexBuffer.vertices(); }
|
||||
float *getTextureVertexBuffer() const { return m_textureVertexBuffer.vertices(); }
|
||||
int getVertexCount() const { return m_vertexBuffer.vertexCount(); }
|
||||
int getTextureVertexCount() const { return m_textureVertexBuffer.vertexCount(); }
|
||||
float *getVertexArray() const { return m_vertexArray.vertices(); }
|
||||
float *getTextureCoordArray() const { return m_textureCoordArray.vertices(); }
|
||||
int getVertexCount() const { return m_vertexArray.vertexCount(); }
|
||||
int getTextureCoordCount() const { return m_textureCoordArray.vertexCount(); }
|
||||
|
||||
HardwareBuffer *getHardwareVertexBuffer() { return m_hardwareVertexBuffer; }
|
||||
HardwareBuffer *getHardwareTextureVertexBuffer() { return m_hardwareTextureVertexBuffer; }
|
||||
HardwareBuffer *getHardwareVertexArray() { return m_hardwareVertexArray; }
|
||||
HardwareBuffer *getHardwareTextureCoordArray() { return m_hardwareTextureCoordArray; }
|
||||
|
||||
private:
|
||||
HardwareBuffer *m_hardwareVertexBuffer;
|
||||
HardwareBuffer *m_hardwareTextureVertexBuffer;
|
||||
HardwareBuffer *m_hardwareVertexArray;
|
||||
HardwareBuffer *m_hardwareTextureCoordArray;
|
||||
HardwareBuffer::UsagePattern m_hardwareCacheMode;
|
||||
VertexArray m_vertexBuffer;
|
||||
VertexArray m_textureVertexBuffer;
|
||||
VertexArray m_vertexArray;
|
||||
VertexArray m_textureCoordArray;
|
||||
bool m_hardwareCached;
|
||||
bool m_hardwareCaching;
|
||||
};
|
||||
|
|
|
@ -77,7 +77,7 @@ void Font::drawText(const std::string& text, const Rect& screenCoords, Fw::Align
|
|||
coordsBuffer.clear();
|
||||
|
||||
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)
|
||||
|
|
|
@ -105,43 +105,44 @@ void FrameBuffer::clear(const Color& color, const Rect& rect)
|
|||
{
|
||||
bool clip = rect.isValid();
|
||||
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());
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if(clip)
|
||||
g_painter.resetClipRect();
|
||||
g_painter->resetClipRect();
|
||||
}
|
||||
|
||||
void FrameBuffer::bind()
|
||||
{
|
||||
internalBind();
|
||||
|
||||
Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f,
|
||||
0.0f, 2.0f/m_texture->getHeight(), 0.0f,
|
||||
-1.0f, -1.0f, 0.0f };
|
||||
-1.0f, -1.0f, 1.0f };
|
||||
g_painter->saveAndResetState();
|
||||
g_painter->setProjectionMatrix(projectionMatrix);
|
||||
|
||||
m_oldProjectionMatrix = g_painter.getProjectionMatrix();
|
||||
m_oldViewportSize = g_graphics.getViewportSize();
|
||||
g_painter.setProjectionMatrix(projectionMatrix);
|
||||
g_graphics.setViewportSize(m_texture->getSize());
|
||||
}
|
||||
|
||||
void FrameBuffer::release()
|
||||
{
|
||||
internalRelease();
|
||||
g_painter.setProjectionMatrix(m_oldProjectionMatrix);
|
||||
g_painter->restoreSavedState();
|
||||
g_graphics.setViewportSize(m_oldViewportSize);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
g_painter.drawTexturedRect(dest, m_texture, Rect(0,0, getSize()));
|
||||
g_painter->drawTexturedRect(dest, m_texture, Rect(0,0, getSize()));
|
||||
}
|
||||
|
||||
void FrameBuffer::internalBind()
|
||||
|
|
|
@ -50,7 +50,6 @@ private:
|
|||
|
||||
TexturePtr m_texture;
|
||||
TexturePtr m_screenBackup;
|
||||
Matrix3 m_oldProjectionMatrix;
|
||||
Size m_oldViewportSize;
|
||||
uint m_fbo;
|
||||
uint m_prevBoundFbo;
|
||||
|
|
|
@ -27,12 +27,9 @@
|
|||
#ifndef OPENGL_ES2
|
||||
#define GLEW_STATIC
|
||||
#include <GL/glew.h>
|
||||
//#include <GL/gl.h>
|
||||
//#include <GL/glext.h>
|
||||
#else
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
//#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
*/
|
||||
|
||||
#include "fontmanager.h"
|
||||
#include "painterogl1.h"
|
||||
#include "painterogl2.h"
|
||||
|
||||
#include <framework/graphics/graphics.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);
|
||||
}
|
||||
|
||||
Graphics::Graphics()
|
||||
{
|
||||
m_maxTextureSize = -1;
|
||||
}
|
||||
|
||||
void Graphics::init()
|
||||
{
|
||||
logInfo("GPU ", glGetString(GL_RENDERER));
|
||||
|
@ -50,29 +57,7 @@ void Graphics::init()
|
|||
glDebugMessageCallbackARB(oglDebugCallback, NULL);
|
||||
#endif
|
||||
|
||||
const char *requiredExtensions[] = {
|
||||
"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));
|
||||
|
||||
// overwrite framebuffer API if needed
|
||||
if(GLEW_EXT_framebuffer_object && !GLEW_ARB_framebuffer_object) {
|
||||
glGenFramebuffers = glGenFramebuffersEXT;
|
||||
glDeleteFramebuffers = glDeleteFramebuffersEXT;
|
||||
|
@ -82,41 +67,105 @@ void Graphics::init()
|
|||
glGenerateMipmap = glGenerateMipmapEXT;
|
||||
}
|
||||
|
||||
m_useFBO = m_useFBO && (GLEW_ARB_framebuffer_object || GLEW_EXT_framebuffer_object);
|
||||
m_generateHardwareMipmaps = m_generateHardwareMipmaps; // glGenerateMipmap is supported when framebuffers are
|
||||
// opengl 1 is always supported
|
||||
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
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
// determine max texture size
|
||||
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);
|
||||
|
||||
g_painter.init();
|
||||
}
|
||||
|
||||
void Graphics::terminate()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
else if(option == "-no-mipmapping")
|
||||
m_generateMipmaps = false;
|
||||
else if(option == "-no-smoothing")
|
||||
else if(option == "-no-mipmaps")
|
||||
m_useMipmaps = false;
|
||||
else if(option == "-no-hardware-mipmaps")
|
||||
m_useHardwareMipmaps = false;
|
||||
else if(option == "-no-smooth")
|
||||
m_useBilinearFiltering = false;
|
||||
else if(option == "-no-hardware-buffering")
|
||||
else if(option == "-no-hardware-buffers")
|
||||
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
|
||||
return false;
|
||||
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)
|
||||
{
|
||||
setViewportSize(size);
|
||||
|
@ -128,17 +177,21 @@ void Graphics::resize(const Size& size)
|
|||
//
|
||||
// This results in the Projection matrix below.
|
||||
//
|
||||
// Projection Matrix Painter Coord GL Coord
|
||||
// ------------------------------------------------ --------- ---------
|
||||
// | 2.0 / width | 0.0 | -1.0 | | x | | x' |
|
||||
// | 0.0 | -2.0 / height | 1.0 | * | y | = | y' |
|
||||
// | 0.0 | 0.0 | 0.0 | | 1 | | 0 |
|
||||
// ------------------------------------------------ --------- ---------
|
||||
Matrix3 projectionMatrix = { 2.0f/size.width(), 0.0f, -1.0f,
|
||||
0.0f, -2.0f/size.height(), 1.0f,
|
||||
0.0f, 0.0f, 0.0f };
|
||||
projectionMatrix.transpose();
|
||||
g_painter.setProjectionMatrix(projectionMatrix);
|
||||
// Projection Matrix
|
||||
// Painter Coord ------------------------------------------------ GL Coord
|
||||
// ------------- | 2.0 / width | 0.0 | 0.0 | ---------------
|
||||
// | x y 1 | * | 0.0 | -2.0 / height | 0.0 | = | x' y' 1 |
|
||||
// ------------- | -1.0 | 1.0 | 1.0 | ---------------
|
||||
// ------------------------------------------------
|
||||
Matrix3 projectionMatrix = { 2.0f/size.width(), 0.0f, 0.0f,
|
||||
0.0f, -2.0f/size.height(), 0.0f,
|
||||
-1.0f, 1.0f, 1.0f };
|
||||
|
||||
if(g_painterOGL1)
|
||||
g_painterOGL1->setProjectionMatrix(projectionMatrix);
|
||||
|
||||
if(g_painterOGL2)
|
||||
g_painterOGL2->setProjectionMatrix(projectionMatrix);
|
||||
}
|
||||
|
||||
void Graphics::beginRender()
|
||||
|
@ -149,16 +202,6 @@ void Graphics::beginRender()
|
|||
|
||||
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)
|
||||
|
@ -167,10 +210,71 @@ void Graphics::setViewportSize(const Size& size)
|
|||
m_viewportSize = size;
|
||||
}
|
||||
|
||||
int Graphics::getMaxTextureSize()
|
||||
bool Graphics::canUseDrawArrays()
|
||||
{
|
||||
static GLint maxTexSize = -1;
|
||||
if(maxTexSize == -1)
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
|
||||
return maxTexSize;
|
||||
#ifndef OPENGL_ES2
|
||||
if(!GLEW_VERSION_1_1)
|
||||
return false;
|
||||
#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
|
||||
{
|
||||
public:
|
||||
Graphics();
|
||||
|
||||
enum PainterEngine {
|
||||
Painter_Any,
|
||||
Painter_OpenGL1,
|
||||
Painter_OpenGL2
|
||||
};
|
||||
|
||||
void init();
|
||||
void terminate();
|
||||
bool parseOption(const std::string& option);
|
||||
|
||||
bool canUseFBO() { return m_useFBO; }
|
||||
bool canUseBilinearFiltering() { return m_useBilinearFiltering; }
|
||||
bool canUseHardwareBuffers() { return m_useHardwareBuffers; }
|
||||
bool canGenerateMipmaps() { return m_generateMipmaps; }
|
||||
bool canGenerateHardwareMipmaps() { return m_generateHardwareMipmaps; }
|
||||
bool selectPainterEngine(PainterEngine painterEngine);
|
||||
PainterEngine getPainterEngine();
|
||||
|
||||
void resize(const Size& size);
|
||||
void beginRender();
|
||||
|
@ -45,19 +50,32 @@ public:
|
|||
|
||||
void setViewportSize(const Size& size);
|
||||
|
||||
int getMaxTextureSize();
|
||||
int getMaxTextureSize() { return m_maxTextureSize; }
|
||||
const Size& getViewportSize() { return m_viewportSize; }
|
||||
TexturePtr& getEmptyTexture() { return m_emptyTexture; }
|
||||
|
||||
bool canUseDrawArrays();
|
||||
bool canUseShaders();
|
||||
bool canUseFBO();
|
||||
bool canUseBilinearFiltering();
|
||||
bool canUseHardwareBuffers();
|
||||
bool canUseNonPowerOfTwoTextures();
|
||||
bool canUseMipmaps();
|
||||
bool canUseHardwareMipmaps();
|
||||
|
||||
private:
|
||||
Size m_viewportSize;
|
||||
TexturePtr m_emptyTexture;
|
||||
|
||||
int m_maxTextureSize;
|
||||
Boolean<true> m_useDrawArrays;
|
||||
Boolean<true> m_useFBO;
|
||||
Boolean<true> m_useHardwareBuffers;
|
||||
Boolean<true> m_useBilinearFiltering;
|
||||
Boolean<true> m_generateMipmaps;
|
||||
Boolean<true> m_generateHardwareMipmaps;
|
||||
Boolean<true> m_useNonPowerOfTwoTextures;
|
||||
Boolean<true> m_useMipmaps;
|
||||
Boolean<true> m_useHardwareMipmaps;
|
||||
PainterEngine m_prefferedPainterEngine;
|
||||
};
|
||||
|
||||
extern Graphics g_graphics;
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
DynamicDraw = GL_DYNAMIC_DRAW
|
||||
};
|
||||
|
||||
HardwareBuffer(Type type ) {
|
||||
HardwareBuffer(Type type) {
|
||||
m_type = type;
|
||||
m_id = 0;
|
||||
glGenBuffers(1, &m_id);
|
||||
|
@ -53,7 +53,6 @@ public:
|
|||
void bind() { glBindBuffer(m_type, m_id); }
|
||||
static void unbind(Type type) { glBindBuffer(type, 0); }
|
||||
void write(void *data, int count, UsagePattern usage) { glBufferData(m_type, count, data, usage); }
|
||||
//void read(void *data, int count);
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
|
|
|
@ -21,102 +21,108 @@
|
|||
*/
|
||||
|
||||
#include "painter.h"
|
||||
#include "texture.h"
|
||||
#include "paintershadersources.h"
|
||||
#include "paintershaderprogram.h"
|
||||
#include "shaderprogram.h"
|
||||
#include "graphics.h"
|
||||
#include "vertexarray.h"
|
||||
|
||||
Painter g_painter;
|
||||
Painter *g_painter = nullptr;
|
||||
|
||||
void Painter::init()
|
||||
Painter::Painter()
|
||||
{
|
||||
setColor(Color::white);
|
||||
setOpacity(1.0f);
|
||||
setCompositionMode(CompositionMode_Normal);
|
||||
releaseCustomProgram();
|
||||
|
||||
m_drawTexturedProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
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();
|
||||
m_glTextureId = 0;
|
||||
m_oldStateIndex = 0;
|
||||
m_color = Color::white;
|
||||
m_opacity = 1.0f;
|
||||
m_compositionMode = CompositionMode_Normal;
|
||||
m_shaderProgram = nullptr;
|
||||
m_texture = nullptr;
|
||||
}
|
||||
|
||||
void Painter::terminate()
|
||||
void Painter::resetState()
|
||||
{
|
||||
m_drawTexturedProgram.reset();
|
||||
m_drawSolidColorProgram.reset();
|
||||
resetColor();
|
||||
resetOpacity();
|
||||
resetCompositionMode();
|
||||
resetClipRect();
|
||||
resetShaderProgram();
|
||||
resetTexture();
|
||||
}
|
||||
|
||||
void Painter::drawProgram(PainterShaderProgram *program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode)
|
||||
void Painter::refreshState()
|
||||
{
|
||||
if(coordsBuffer.getVertexCount() == 0)
|
||||
return;
|
||||
|
||||
program->setProjectionMatrix(m_projectionMatrix);
|
||||
program->setOpacity(m_opacity);
|
||||
program->setColor(m_color);
|
||||
program->draw(coordsBuffer, drawMode);
|
||||
updateGlCompositionMode();
|
||||
updateGlClipRect();
|
||||
updateGlTexture();
|
||||
}
|
||||
|
||||
void Painter::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
||||
void Painter::saveAndResetState()
|
||||
{
|
||||
PainterShaderProgram *program = m_customProgram ? m_customProgram : m_drawTexturedProgram.get();
|
||||
program->setTexture(texture);
|
||||
drawProgram(program, coordsBuffer);
|
||||
assert(m_oldStateIndex<10);
|
||||
m_olderStates[m_oldStateIndex].projectionMatrix = m_projectionMatrix;
|
||||
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())
|
||||
return;
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addQuad(dest, src);
|
||||
PainterShaderProgram *program = m_customProgram ? m_customProgram : m_drawTexturedProgram.get();
|
||||
program->setTexture(texture);
|
||||
drawProgram(program, m_coordsBuffer, PainterShaderProgram::TriangleStrip);
|
||||
}
|
||||
|
||||
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);
|
||||
m_oldStateIndex--;
|
||||
setProjectionMatrix(m_olderStates[m_oldStateIndex].projectionMatrix);
|
||||
setTextureMatrix(m_olderStates[m_oldStateIndex].textureMatrix);
|
||||
setColor(m_olderStates[m_oldStateIndex].color);
|
||||
setOpacity(m_olderStates[m_oldStateIndex].opacity);
|
||||
setCompositionMode(m_olderStates[m_oldStateIndex].compositionMode);
|
||||
setClipRect(m_olderStates[m_oldStateIndex].clipRect);
|
||||
setShaderProgram(m_olderStates[m_oldStateIndex].shaderProgram);
|
||||
setTexture(m_olderStates[m_oldStateIndex].texture);
|
||||
}
|
||||
|
||||
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:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
|
@ -133,50 +139,14 @@ void Painter::setCompositionMode(Painter::CompositionMode compositionMode)
|
|||
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
|
||||
break;
|
||||
}
|
||||
m_compostionMode = compositionMode;
|
||||
}
|
||||
|
||||
void Painter::setClipRect(const Rect& clipRect)
|
||||
void Painter::updateGlClipRect()
|
||||
{
|
||||
if(m_clipRect == clipRect)
|
||||
return;
|
||||
|
||||
if(clipRect.isValid()) {
|
||||
if(m_clipRect.isValid()) {
|
||||
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 {
|
||||
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
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/util/databuffer.h>
|
||||
#include "coordsbuffer.h"
|
||||
#include "paintershaderprogram.h"
|
||||
#include "texture.h"
|
||||
|
@ -39,58 +38,90 @@ public:
|
|||
CompositionMode_Replace,
|
||||
CompositionMode_DestBlending
|
||||
};
|
||||
enum DrawMode {
|
||||
Triangles = GL_TRIANGLES,
|
||||
TriangleStrip = GL_TRIANGLE_STRIP
|
||||
};
|
||||
|
||||
void init();
|
||||
void terminate();
|
||||
struct PainterState {
|
||||
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);
|
||||
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
||||
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);
|
||||
Painter();
|
||||
virtual ~Painter() { }
|
||||
|
||||
void setColor(const Color& color) { m_color = color; }
|
||||
Color getColor() { return m_color; }
|
||||
|
||||
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; }
|
||||
virtual void bind() { refreshState(); }
|
||||
virtual void unbind() { }
|
||||
|
||||
void resetState();
|
||||
virtual void refreshState();
|
||||
void saveAndResetState();
|
||||
void restoreSavedState();
|
||||
|
||||
private:
|
||||
PainterShaderProgramPtr m_drawTexturedProgram;
|
||||
PainterShaderProgramPtr m_drawSolidColorProgram;
|
||||
PainterShaderProgram *m_customProgram;
|
||||
virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0;
|
||||
virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0;
|
||||
virtual void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
||||
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;
|
||||
Matrix2 m_textureMatrix;
|
||||
Color m_color;
|
||||
float m_opacity;
|
||||
CompositionMode m_compostionMode;
|
||||
CoordsBuffer m_coordsBuffer;
|
||||
CompositionMode m_compositionMode;
|
||||
Rect m_clipRect;
|
||||
Texture *m_texture;
|
||||
PainterShaderProgram *m_shaderProgram;
|
||||
|
||||
PainterShaderProgram *m_oldCustomProgram;
|
||||
Matrix3 m_oldProjectionMatrix;
|
||||
Color m_oldColor;
|
||||
float m_oldOpacity;
|
||||
Rect m_oldClipRect;
|
||||
CompositionMode m_oldCompostionMode;
|
||||
PainterState m_olderStates[10];
|
||||
int m_oldStateIndex;
|
||||
|
||||
GLuint m_glTextureId;
|
||||
};
|
||||
|
||||
extern Painter g_painter;
|
||||
extern Painter *g_painter;
|
||||
|
||||
#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_color = Color::white;
|
||||
m_time = 0;
|
||||
m_lastTexture = -1;
|
||||
m_textures.fill(0);
|
||||
}
|
||||
|
||||
bool PainterShaderProgram::link()
|
||||
|
@ -43,7 +41,7 @@ bool PainterShaderProgram::link()
|
|||
bindAttributeLocation(TEXCOORD_ATTR, "a_texCoord");
|
||||
if(ShaderProgram::link()) {
|
||||
bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "projectionMatrix");
|
||||
bindUniformLocation(TEXTURE_TRANSFORM_MATRIX_UNIFORM, "texTransformMatrix");
|
||||
bindUniformLocation(TEXTURE_MATRIX_UNIFORM, "textureMatrix");
|
||||
bindUniformLocation(COLOR_UNIFORM, "color");
|
||||
bindUniformLocation(OPACITY_UNIFORM, "opacity");
|
||||
bindUniformLocation(TIME_UNIFORM, "time");
|
||||
|
@ -52,15 +50,13 @@ bool PainterShaderProgram::link()
|
|||
|
||||
bind();
|
||||
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(OPACITY_UNIFORM, m_opacity);
|
||||
setUniformValue(TIME_UNIFORM, m_time);
|
||||
setUniformValue(TEX0_UNIFORM, 0);
|
||||
setUniformValue(TEX1_UNIFORM, 1);
|
||||
|
||||
enableAttributeArray(PainterShaderProgram::VERTEX_ATTR);
|
||||
enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR);
|
||||
release();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -76,6 +72,16 @@ void PainterShaderProgram::setProjectionMatrix(const Matrix3& 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)
|
||||
{
|
||||
if(color == m_color)
|
||||
|
@ -96,68 +102,13 @@ void PainterShaderProgram::setOpacity(float opacity)
|
|||
m_opacity = opacity;
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setTexture(const TexturePtr& texture, int index)
|
||||
void PainterShaderProgram::updateTime()
|
||||
{
|
||||
assert(index >= 0 && index <= 1);
|
||||
|
||||
uint texId = texture ? texture->getId() : 0;
|
||||
|
||||
if(m_textures[index] == texId)
|
||||
float time = g_clock.timeElapsed(m_startTime);
|
||||
if(m_time == time)
|
||||
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();
|
||||
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);
|
||||
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
|
||||
{
|
||||
protected:
|
||||
enum {
|
||||
VERTEX_ATTR = 0,
|
||||
TEXCOORD_ATTR = 1,
|
||||
PROJECTION_MATRIX_UNIFORM = 0,
|
||||
TEXTURE_TRANSFORM_MATRIX_UNIFORM = 1,
|
||||
TEXTURE_MATRIX_UNIFORM = 1,
|
||||
COLOR_UNIFORM = 2,
|
||||
OPACITY_UNIFORM = 3,
|
||||
TIME_UNIFORM = 4,
|
||||
|
@ -42,34 +43,28 @@ class PainterShaderProgram : public ShaderProgram
|
|||
//TEX2_UNIFORM = 7,
|
||||
//TEX3_UNIFORM = 8,
|
||||
};
|
||||
public:
|
||||
enum DrawMode {
|
||||
Triangles = GL_TRIANGLES,
|
||||
TriangleStrip = GL_TRIANGLE_STRIP
|
||||
};
|
||||
|
||||
friend class PainterOGL2;
|
||||
|
||||
public:
|
||||
PainterShaderProgram();
|
||||
|
||||
bool link();
|
||||
|
||||
void setProjectionMatrix(const Matrix3& projectionMatrix);
|
||||
void setTextureMatrix(const Matrix2& textureMatrix);
|
||||
void setColor(const Color& color);
|
||||
void setOpacity(float opacity);
|
||||
void setTexture(const TexturePtr& texture, int index = 0);
|
||||
void setUniformTexture(int location, const TexturePtr& texture, int index);
|
||||
void draw(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||
void updateTime();
|
||||
|
||||
private:
|
||||
DrawMode m_drawMode;
|
||||
float m_startTime;
|
||||
std::array<uint, 2> m_textures;
|
||||
|
||||
Color m_color;
|
||||
float m_opacity;
|
||||
Matrix3 m_projectionMatrix;
|
||||
Matrix2 m_textureTransformMatrix;
|
||||
Matrix2 m_textureMatrix;
|
||||
float m_time;
|
||||
int m_lastTexture;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,14 +45,14 @@ Particle::Particle(const Point& pos, const Size& startSize, const Size& finalSiz
|
|||
|
||||
void Particle::render()
|
||||
{
|
||||
g_painter.setColor(m_color);
|
||||
g_painter->setColor(m_color);
|
||||
|
||||
if(!m_texture)
|
||||
g_painter.drawFilledRect(m_rect);
|
||||
g_painter->drawFilledRect(m_rect);
|
||||
else {
|
||||
g_painter.setCompositionMode(m_compositionMode);
|
||||
g_painter.drawTexturedRect(m_rect, m_texture);
|
||||
g_painter.setCompositionMode(Painter::CompositionMode_Normal);
|
||||
g_painter->setCompositionMode(m_compositionMode);
|
||||
g_painter->drawTexturedRect(m_rect, m_texture);
|
||||
g_painter->setCompositionMode(Painter::CompositionMode_Normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,8 @@ public:
|
|||
static void release();
|
||||
std::string log();
|
||||
|
||||
void disableAttributeArray(int location) { glDisableVertexAttribArray(location); }
|
||||
void enableAttributeArray(int location) { glEnableVertexAttribArray(location); }
|
||||
static void disableAttributeArray(int location) { glDisableVertexAttribArray(location); }
|
||||
static void enableAttributeArray(int location) { glEnableVertexAttribArray(location); }
|
||||
void disableAttributeArray(const char *name) { glDisableVertexAttribArray(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()
|
||||
{
|
||||
if(g_graphics.canGenerateHardwareMipmaps())
|
||||
generateHardwareMipmaps();
|
||||
else {
|
||||
if(!generateHardwareMipmaps()) {
|
||||
// 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
|
||||
//generateSoftwareMipmaps(getPixels());
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::generateHardwareMipmaps()
|
||||
bool Texture::generateHardwareMipmaps()
|
||||
{
|
||||
if(!g_graphics.canGenerateHardwareMipmaps())
|
||||
return;
|
||||
if(!g_graphics.canUseHardwareMipmaps())
|
||||
return false;
|
||||
|
||||
#ifndef OPENGL_ES2
|
||||
if(!GLEW_ARB_framebuffer_object)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
bind();
|
||||
|
||||
|
@ -122,6 +125,7 @@ void Texture::generateHardwareMipmaps()
|
|||
}
|
||||
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Texture::setSmooth(bool smooth)
|
||||
|
@ -146,10 +150,10 @@ std::vector<uint8> Texture::getPixels()
|
|||
FrameBufferPtr fb(new FrameBuffer(m_size));
|
||||
fb->bind();
|
||||
fb->clear(Color::alpha);
|
||||
g_painter.saveAndResetState();
|
||||
g_painter.drawTexturedRect(Rect(0,0,m_size), shared_from_this());
|
||||
g_painter->saveAndResetState();
|
||||
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]);
|
||||
g_painter.restoreSavedState();
|
||||
g_painter->restoreSavedState();
|
||||
fb->release();
|
||||
#else
|
||||
// copy pixels from opengl memory
|
||||
|
|
|
@ -36,15 +36,16 @@ public:
|
|||
|
||||
/// Tries to generate mipmaps via hardware, otherwise fallback to software implementation
|
||||
void generateMipmaps();
|
||||
/// Generate mipmaps via hardware
|
||||
void generateHardwareMipmaps();
|
||||
/// Generate mipmaps via hardware if supported
|
||||
bool generateHardwareMipmaps();
|
||||
/// Generate mipmaps via software, which has a special algorithm for combining alpha pixels
|
||||
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);
|
||||
GLuint getId() { return m_textureId; }
|
||||
|
||||
/// Return actual texture pixels
|
||||
std::vector<uint8> getPixels();
|
||||
|
||||
int getWidth() { return m_size.width(); }
|
||||
|
|
|
@ -47,7 +47,7 @@ void UIFrameCounter::drawSelf()
|
|||
}
|
||||
m_frameCount++;
|
||||
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter->setColor(Color::white);
|
||||
m_font->drawText(m_fpsText, m_rect, m_align);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,9 +53,9 @@ void UITextEdit::drawSelf()
|
|||
int textLength = m_text.length();
|
||||
const TexturePtr& texture = m_font->getTexture();
|
||||
|
||||
g_painter.setColor(m_color);
|
||||
g_painter->setColor(m_color);
|
||||
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
|
||||
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());
|
||||
else
|
||||
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) {
|
||||
m_cursorTicks = g_clock.ticks();
|
||||
}
|
||||
|
|
|
@ -54,19 +54,19 @@ UIWidget::~UIWidget()
|
|||
void UIWidget::draw(const Rect& visibleRect)
|
||||
{
|
||||
if(m_clipping)
|
||||
g_painter.setClipRect(visibleRect);
|
||||
g_painter->setClipRect(visibleRect);
|
||||
|
||||
drawSelf();
|
||||
|
||||
if(m_children.size() > 0) {
|
||||
if(m_clipping)
|
||||
g_painter.setClipRect(visibleRect.intersection(getClippingRect()));
|
||||
g_painter->setClipRect(visibleRect.intersection(getClippingRect()));
|
||||
|
||||
drawChildren(visibleRect);
|
||||
}
|
||||
|
||||
if(m_clipping)
|
||||
g_painter.resetClipRect();
|
||||
g_painter->resetClipRect();
|
||||
}
|
||||
|
||||
void UIWidget::drawSelf()
|
||||
|
@ -97,22 +97,22 @@ void UIWidget::drawChildren(const Rect& visibleRect)
|
|||
continue;
|
||||
|
||||
// store current graphics opacity
|
||||
float oldOpacity = g_painter.getOpacity();
|
||||
float oldOpacity = g_painter->getOpacity();
|
||||
|
||||
// decrease to self opacity
|
||||
if(child->getOpacity() < oldOpacity)
|
||||
g_painter.setOpacity(child->getOpacity());
|
||||
g_painter->setOpacity(child->getOpacity());
|
||||
|
||||
child->draw(childVisibleRect);
|
||||
|
||||
// debug draw box
|
||||
if(g_ui.isDrawingDebugBoxes()) {
|
||||
g_painter.setColor(Color::green);
|
||||
g_painter.drawBoundingRect(child->getRect());
|
||||
g_painter->setColor(Color::green);
|
||||
g_painter->drawBoundingRect(child->getRect());
|
||||
}
|
||||
//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());
|
||||
if(m_backgroundRect.isValid())
|
||||
drawRect.resize(m_backgroundRect.size());
|
||||
g_painter.setColor(m_backgroundColor);
|
||||
g_painter.drawFilledRect(drawRect);
|
||||
g_painter->setColor(m_backgroundColor);
|
||||
g_painter->drawFilledRect(drawRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,31 +332,31 @@ void UIWidget::drawBorder(const Rect& screenCoords)
|
|||
{
|
||||
// top
|
||||
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);
|
||||
g_painter.drawFilledRect(borderRect);
|
||||
g_painter->drawFilledRect(borderRect);
|
||||
}
|
||||
// right
|
||||
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());
|
||||
g_painter.drawFilledRect(borderRect);
|
||||
g_painter->drawFilledRect(borderRect);
|
||||
}
|
||||
// bottom
|
||||
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);
|
||||
g_painter.drawFilledRect(borderRect);
|
||||
g_painter->drawFilledRect(borderRect);
|
||||
}
|
||||
// left
|
||||
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());
|
||||
g_painter.drawFilledRect(borderRect);
|
||||
g_painter->drawFilledRect(borderRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,8 +372,8 @@ void UIWidget::drawIcon(const Rect& screenCoords)
|
|||
drawRect.resize(m_icon->getSize());
|
||||
drawRect.moveCenter(screenCoords.center());
|
||||
}
|
||||
g_painter.setColor(m_iconColor);
|
||||
g_painter.drawTexturedRect(drawRect, m_icon);
|
||||
g_painter->setColor(m_iconColor);
|
||||
g_painter->drawTexturedRect(drawRect, m_icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -167,8 +167,8 @@ void UIWidget::drawImage(const Rect& screenCoords)
|
|||
|
||||
m_imageTexture->setSmooth(m_imageSmooth);
|
||||
|
||||
g_painter.setColor(m_imageColor);
|
||||
g_painter.drawTextureCoords(m_imageCoordsBuffer, m_imageTexture);
|
||||
g_painter->setColor(m_imageColor);
|
||||
g_painter->drawTextureCoords(m_imageCoordsBuffer, m_imageTexture);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
g_painter.setColor(m_color);
|
||||
g_painter.drawTextureCoords(m_textCoordsBuffer, m_font->getTexture());
|
||||
g_painter->setColor(m_color);
|
||||
g_painter->drawTextureCoords(m_textCoordsBuffer, m_font->getTexture());
|
||||
}
|
||||
|
||||
void UIWidget::onTextChange(const std::string& text, const std::string& oldText)
|
||||
|
|
|
@ -23,7 +23,16 @@
|
|||
#ifndef __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
|
||||
/*
|
||||
#if !defined(_GLIBCXX_HAS_GTHREADS) && defined(__GNUG__)
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
@ -45,5 +54,6 @@ namespace std {
|
|||
using boost::condition_variable_any;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,12 +40,11 @@ typedef int32_t int32;
|
|||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
|
||||
// note that on 32 bit platforms the max ticks will overflow for valeus above 2,147,483,647
|
||||
// thus this means that the app may crash after running 24 days without restarting
|
||||
// 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 cause unknown behavior after running 24 days without restarting
|
||||
typedef long ticks_t;
|
||||
|
||||
typedef std::function<void()> SimpleCallback;
|
||||
typedef std::function<bool()> BooleanCallback;
|
||||
|
||||
// boolean with default value initializer
|
||||
template<bool def>
|
||||
|
|
|
@ -40,7 +40,7 @@ void AnimatedText::draw(const Point& dest, const Rect& visibleRect)
|
|||
|
||||
if(visibleRect.contains(rect)) {
|
||||
//TODO: cache into a framebuffer
|
||||
g_painter.setColor(m_color);
|
||||
g_painter->setColor(m_color);
|
||||
m_font->drawText(m_text, rect, Fw::AlignLeft);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <framework/core/clock.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/framebuffer.h>
|
||||
#include "spritemanager.h"
|
||||
|
@ -59,25 +59,27 @@ Creature::Creature() : Thing()
|
|||
m_informationFont = g_fonts.getFont("verdana-11px-rounded");
|
||||
}
|
||||
|
||||
/*
|
||||
PainterShaderProgramPtr outfitProgram;
|
||||
int HEAD_COLOR_UNIFORM = 10;
|
||||
int BODY_COLOR_UNIFORM = 11;
|
||||
int LEGS_COLOR_UNIFORM = 12;
|
||||
int FEET_COLOR_UNIFORM = 13;
|
||||
int MASK_TEXTURE_UNIFORM = 14;
|
||||
*/
|
||||
|
||||
void Creature::draw(const Point& dest, float scaleFactor, bool animate)
|
||||
{
|
||||
Point animationOffset = animate ? m_walkOffset : Point(0,0);
|
||||
|
||||
if(m_showTimedSquare && animate) {
|
||||
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->setColor(m_timedSquareColor);
|
||||
g_painter->drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 3)*scaleFactor, Size(28, 28)*scaleFactor), std::max((int)(2*scaleFactor), 1));
|
||||
}
|
||||
|
||||
if(m_showStaticSquare && animate) {
|
||||
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->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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter->setColor(Color::white);
|
||||
/*
|
||||
if(!outfitProgram) {
|
||||
outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
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(FEET_COLOR_UNIFORM, "feetColor");
|
||||
}
|
||||
*/
|
||||
|
||||
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))))
|
||||
continue;
|
||||
|
||||
g_painter.setCustomProgram(outfitProgram);
|
||||
/*
|
||||
g_painter->setShaderProgram(outfitProgram);
|
||||
|
||||
outfitProgram->bind();
|
||||
outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
|
||||
outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
|
||||
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
|
||||
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
|
||||
*/
|
||||
|
||||
for(int h = 0; h < getDimensionHeight(); h++) {
|
||||
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);
|
||||
maskTex = g_sprites.getSpriteTexture(maskId);
|
||||
}
|
||||
outfitProgram->setTexture(maskTex, 1);
|
||||
//outfitProgram->setTexture(maskTex, 1);
|
||||
|
||||
internalDraw(dest + (-Point(w,h)*Otc::TILE_PIXELS)*scaleFactor,
|
||||
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
|
||||
} else {
|
||||
|
@ -182,12 +188,12 @@ void Creature::drawOutfit(const Rect& destRect, bool resize)
|
|||
if(!outfitBuffer)
|
||||
outfitBuffer = FrameBufferPtr(new FrameBuffer(Size(2*Otc::TILE_PIXELS, 2*Otc::TILE_PIXELS)));
|
||||
|
||||
g_painter.saveAndResetState();
|
||||
g_painter->saveAndResetState();
|
||||
outfitBuffer->bind();
|
||||
outfitBuffer->clear(Color::alpha);
|
||||
internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South);
|
||||
outfitBuffer->release();
|
||||
g_painter.restoreSavedState();
|
||||
g_painter->restoreSavedState();
|
||||
|
||||
if(resize) {
|
||||
Rect srcRect;
|
||||
|
@ -227,26 +233,26 @@ void Creature::drawInformation(const Point& point, bool useGray, const Rect& par
|
|||
healthRect.setWidth((m_healthPercent / 100.0) * 25);
|
||||
|
||||
// draw
|
||||
g_painter.setColor(Color::black);
|
||||
g_painter.drawFilledRect(backgroundRect);
|
||||
g_painter->setColor(Color::black);
|
||||
g_painter->drawFilledRect(backgroundRect);
|
||||
|
||||
g_painter.setColor(fillColor);
|
||||
g_painter.drawFilledRect(healthRect);
|
||||
g_painter->setColor(fillColor);
|
||||
g_painter->drawFilledRect(healthRect);
|
||||
|
||||
if(m_informationFont)
|
||||
m_informationFont->drawText(m_name, textRect, Fw::AlignTopCenter);
|
||||
|
||||
if(m_skull != Otc::SkullNone && m_skullTexture) {
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter.drawTexturedRect(Rect(point.x + 12, point.y + 5, m_skullTexture->getSize()), m_skullTexture);
|
||||
g_painter->setColor(Color::white);
|
||||
g_painter->drawTexturedRect(Rect(point.x + 12, point.y + 5, m_skullTexture->getSize()), m_skullTexture);
|
||||
}
|
||||
if(m_shield != Otc::ShieldNone && m_shieldTexture && m_showShieldTexture) {
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter.drawTexturedRect(Rect(point.x, point.y + 5, m_shieldTexture->getSize()), m_shieldTexture);
|
||||
g_painter->setColor(Color::white);
|
||||
g_painter->drawTexturedRect(Rect(point.x, point.y + 5, m_shieldTexture->getSize()), m_shieldTexture);
|
||||
}
|
||||
if(m_emblem != Otc::EmblemNone && m_emblemTexture) {
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter.drawTexturedRect(Rect(point.x + 12, point.y + 16, m_emblemTexture->getSize()), m_emblemTexture);
|
||||
g_painter->setColor(Color::white);
|
||||
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/graphics/graphics.h>
|
||||
#include <framework/graphics/paintershaderprogram.h>
|
||||
#include <framework/graphics/paintershadersources.h>
|
||||
#include <framework/graphics/painterogl2_shadersources.h>
|
||||
|
||||
Item::Item() : Thing()
|
||||
{
|
||||
|
@ -50,9 +50,10 @@ ItemPtr Item::create(int id)
|
|||
return item;
|
||||
}
|
||||
|
||||
/*
|
||||
PainterShaderProgramPtr itemProgram;
|
||||
int ITEM_ID_UNIFORM = 10;
|
||||
|
||||
*/
|
||||
void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||
{
|
||||
if(m_id == 0)
|
||||
|
@ -165,6 +166,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
|||
}
|
||||
|
||||
// setup item drawing shader
|
||||
/*
|
||||
if(!itemProgram) {
|
||||
itemProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
itemProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
|
@ -172,15 +174,16 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
|||
itemProgram->link();
|
||||
itemProgram->bindUniformLocation(ITEM_ID_UNIFORM, "itemId");
|
||||
}
|
||||
g_painter.setCustomProgram(itemProgram);
|
||||
g_painter->setShaderProgram(itemProgram);
|
||||
//itemProgram->bind();
|
||||
//itemProgram->setUniformValue(ITEM_ID_UNIFORM, (int)m_id);
|
||||
*/
|
||||
|
||||
// now we can draw the item
|
||||
internalDraw(dest, scaleFactor, xPattern, yPattern, zPattern, animationPhase);
|
||||
|
||||
// release draw shader
|
||||
g_painter.releaseCustomProgram();
|
||||
g_painter->resetShaderProgram();
|
||||
}
|
||||
|
||||
void Item::setId(uint32 id)
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/framebuffer.h>
|
||||
#include <framework/graphics/paintershaderprogram.h>
|
||||
#include <framework/graphics/paintershadersources.h>
|
||||
#include <framework/graphics/paintershadermanager.h>
|
||||
#include "creature.h"
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
|
@ -34,8 +33,6 @@
|
|||
#include "missile.h"
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
//int AWARE_AREA_UNIFORM = 10;
|
||||
|
||||
MapView::MapView()
|
||||
{
|
||||
m_viewMode = NEAR_VIEW;
|
||||
|
@ -47,11 +44,7 @@ MapView::MapView()
|
|||
m_framebuffer = FrameBufferPtr(new FrameBuffer());
|
||||
setVisibleDimension(Size(15, 11));
|
||||
|
||||
m_shaderProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
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");
|
||||
m_shaderProgram = g_shaders.createTexturedFragmentShader("/game_shaders/map.frag");
|
||||
}
|
||||
|
||||
void MapView::draw(const Rect& rect)
|
||||
|
@ -78,16 +71,15 @@ void MapView::draw(const Rect& rect)
|
|||
|
||||
Size tileSize = Size(1,1) * m_tileSize;
|
||||
if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) {
|
||||
g_painter.saveAndResetState();
|
||||
m_framebuffer->bind();
|
||||
|
||||
if(m_mustCleanFramebuffer) {
|
||||
Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize);
|
||||
|
||||
// drawing a black rect is actually faster than FrameBuffer::clear()
|
||||
g_painter.setColor(Color::black);
|
||||
g_painter.drawFilledRect(clearRect);
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter->setColor(Color::black);
|
||||
g_painter->drawFilledRect(clearRect);
|
||||
g_painter->setColor(Color::white);
|
||||
|
||||
// m_framebuffer->clear(Color::black);
|
||||
}
|
||||
|
@ -105,8 +97,8 @@ void MapView::draw(const Rect& rect)
|
|||
if(!m_drawMinimapColors)
|
||||
tile->draw(transformPositionTo2D(tile->getPosition()), scaleFactor, drawFlags);
|
||||
else {
|
||||
g_painter.setColor(tile->getMinimapColor());
|
||||
g_painter.drawFilledRect(Rect(transformPositionTo2D(tile->getPosition()), tileSize));
|
||||
g_painter->setColor(tile->getMinimapColor());
|
||||
g_painter->drawFilledRect(Rect(transformPositionTo2D(tile->getPosition()), tileSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,7 +110,6 @@ void MapView::draw(const Rect& rect)
|
|||
}
|
||||
|
||||
m_framebuffer->release();
|
||||
g_painter.restoreSavedState();
|
||||
|
||||
// generating mipmaps each frame can be slow in older cards
|
||||
//m_framebuffer->getTexture()->generateHardwareMipmaps();
|
||||
|
@ -126,7 +117,7 @@ void MapView::draw(const Rect& rect)
|
|||
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;
|
||||
if(m_followingCreature)
|
||||
|
@ -139,39 +130,20 @@ void MapView::draw(const Rect& rect)
|
|||
drawOffset.y += (srcVisible.height() - srcSize.height()) / 2;
|
||||
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
|
||||
// debug source area
|
||||
g_painter.saveAndResetState();
|
||||
g_painter->saveAndResetState();
|
||||
m_framebuffer->bind();
|
||||
g_painter.setColor(Color::green);
|
||||
g_painter.drawBoundingRect(srcRect, 2);
|
||||
g_painter->setColor(Color::green);
|
||||
g_painter->drawBoundingRect(srcRect, 2);
|
||||
m_framebuffer->release();
|
||||
g_painter.restoreSavedState();
|
||||
g_painter->restoreSavedState();
|
||||
m_framebuffer->draw(rect);
|
||||
#else
|
||||
m_framebuffer->draw(rect, srcRect);
|
||||
#endif
|
||||
|
||||
g_painter.releaseCustomProgram();
|
||||
g_painter->resetShaderProgram();
|
||||
|
||||
// this could happen if the player position is not known yet
|
||||
if(!cameraPosition.isValid())
|
||||
|
@ -231,9 +203,9 @@ void MapView::draw(const Rect& rect)
|
|||
Rect hRect(0, 0, 10, 2);
|
||||
vRect.moveCenter(rect.center());
|
||||
hRect.moveCenter(rect.center());
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter.drawFilledRect(vRect);
|
||||
g_painter.drawFilledRect(hRect);
|
||||
g_painter->setColor(Color::white);
|
||||
g_painter->drawFilledRect(vRect);
|
||||
g_painter->drawFilledRect(hRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ TexturePtr SpriteManager::loadSpriteTexture(int id)
|
|||
TexturePtr spriteTex(new Texture(32, 32, 4, &pixels[0]));
|
||||
spriteTex->setSmooth(true);
|
||||
|
||||
if(g_graphics.canGenerateMipmaps())
|
||||
if(g_graphics.canUseMipmaps())
|
||||
spriteTex->generateSoftwareMipmaps(pixels);
|
||||
|
||||
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
|
||||
if((boundRect.center() - rect.center()).length() < parentRect.width() / 15 || isYell()) {
|
||||
//TODO: cache into a framebuffer
|
||||
g_painter.setColor(m_color);
|
||||
g_painter->setColor(m_color);
|
||||
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);
|
||||
if(spriteId) {
|
||||
Rect drawRect(dest - getDisplacement()*scaleFactor, Size(scaledSize, scaledSize));
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter.drawTexturedRect(drawRect, g_sprites.getSpriteTexture(spriteId));
|
||||
g_painter->setColor(Color::white);
|
||||
g_painter->drawTexturedRect(drawRect, g_sprites.getSpriteTexture(spriteId));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ void UICreature::drawSelf()
|
|||
UIWidget::drawSelf();
|
||||
|
||||
if(m_creature) {
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter->setColor(Color::white);
|
||||
Rect drawRect = getClippingRect();
|
||||
m_creature->drawOutfit(drawRect, !m_fixedCreatureSize);
|
||||
}
|
||||
|
|
|
@ -41,12 +41,12 @@ void UIItem::drawSelf()
|
|||
dest += (1 - scaleFactor)*32;
|
||||
dest += m_item->getDisplacement() * scaleFactor;
|
||||
|
||||
g_painter.setColor(Color::white);
|
||||
g_painter->setColor(Color::white);
|
||||
m_item->draw(dest, scaleFactor, true);
|
||||
|
||||
if(m_font && m_item->isStackable() && m_item->getCount() > 1) {
|
||||
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(Fw::tostring(m_item->getId()), m_rect, Fw::AlignBottomRight);
|
||||
|
|
|
@ -49,9 +49,10 @@ void UIMap::drawSelf()
|
|||
UIWidget::drawSelf();
|
||||
|
||||
// draw map border
|
||||
g_painter.setColor(Color::black);
|
||||
g_painter.drawBoundingRect(m_mapRect.expanded(1));
|
||||
g_painter->setColor(Color::black);
|
||||
g_painter->drawBoundingRect(m_mapRect.expanded(1));
|
||||
|
||||
g_painter->setColor(Color::white);
|
||||
m_mapView->draw(m_mapRect);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue