From 040797fd5d87cd6bac2ac476d2e4748664ef6185 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 16 Sep 2013 08:27:59 +0000 Subject: [PATCH] uppsrc: GLDraw git-svn-id: svn://ultimatepp.org/upp/trunk@6352 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/GLDraw/GLDraw.cpp | 164 +++++++++++++++++++++++++++++++++++++++ uppsrc/GLDraw/GLDraw.h | 23 ++++++ uppsrc/GLDraw/GLDraw.upp | 8 ++ uppsrc/GLDraw/init | 5 ++ 4 files changed, 200 insertions(+) create mode 100644 uppsrc/GLDraw/GLDraw.cpp create mode 100644 uppsrc/GLDraw/GLDraw.h create mode 100644 uppsrc/GLDraw/GLDraw.upp create mode 100644 uppsrc/GLDraw/init diff --git a/uppsrc/GLDraw/GLDraw.cpp b/uppsrc/GLDraw/GLDraw.cpp new file mode 100644 index 000000000..e90da8a77 --- /dev/null +++ b/uppsrc/GLDraw/GLDraw.cpp @@ -0,0 +1,164 @@ +#include "GLDraw.h" + +#define LLOG(x) LOG(x) + +namespace Upp { + +struct ImageGLData { +// Image img; + GLuint texture_id; + + void Init(const Image& img); + ~ImageGLData(); +}; + +void ImageGLData::Init(const Image& img) +{ + Size sz = img.GetSize(); + + glGenTextures(1, &texture_id); + glBindTexture(GL_TEXTURE_2D, texture_id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sz.cx, sz.cy, 0, GL_BGRA, GL_UNSIGNED_BYTE, ~img); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + LLOG("Texture id created: " << texture_id); +// SysImageRealized(img); // ? +} + +static LRUCache sTextureCache; +static bool sReset; + +ImageGLData::~ImageGLData() +{ +// SysImageReleased(img); // ? + if(!sReset) + glDeleteTextures(1, &texture_id); + LLOG("Texture id deleted: " << texture_id); +} + +void GLDraw::ClearCache() +{ + sReset = false; + sTextureCache.Clear(); +} + +void GLDraw::ResetCache() +{ + sReset = true; + sTextureCache.Clear(); + sReset = false; +} + +struct ImageGLDataMaker : LRUCache::Maker { + Image img; + + virtual int64 Key() const { return img.GetSerialId(); } + virtual int Make(ImageGLData& object) const { object.Init(img); return img.GetLength(); } +}; + + +void GLDraw::PutImage(Point p, const Image& img, const Rect& src) +{ + if(img.GetLength() == 0) + return; + + LLOG("PutImage " << img.GetSerialId() << ' ' << p.x << ", " << p.y << ", "<< img.GetSize()); + LLOG("SysImage cache pixels " << sTextureCache.GetSize() << ", count " << sTextureCache.GetCount()); + ImageGLDataMaker m; + m.img = img; + ImageGLData& sd = sTextureCache.Get(m); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, sd.texture_id); + + LLOG("Texture ID: " << sd.texture_id); + + glColor3f(1.0f, 1.0f, 1.0f); + + if(src == img.GetSize()) { + Rect r(p, img.GetSize()); + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0, 0); + glVertex2i(r.left, r.top); + glTexCoord2f(1, 0); + glVertex2i(r.right, r.top); + glTexCoord2f(0, 1); + glVertex2i(r.left, r.bottom); + glTexCoord2f(1, 1); + glVertex2i(r.right, r.bottom); + glEnd(); + } + else { + Sizef iszf = img.GetSize(); + Rect s = src & img.GetSize(); + Rect r(p, s.GetSize()); + Rectf h; + h.left = (double)s.left / iszf.cx; + h.right = (double)s.right / iszf.cx; + h.top = (double)s.top / iszf.cy; + h.bottom = (double)s.bottom / iszf.cy; + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(h.left, h.top); + glVertex2i(r.left, r.top); + glTexCoord2f(h.right, h.top); + glVertex2i(r.right, r.top); + glTexCoord2f(h.left, h.bottom); + glVertex2i(r.left, r.bottom); + glTexCoord2f(h.right, h.bottom); + glVertex2i(r.right, r.bottom); + glEnd(); + } + + glDisable(GL_TEXTURE_2D); + + sTextureCache.Shrink(4 * 1024 * 768, 1000); +} + +void GLDraw::SetColor(Color c) +{ + glColor3f(c.GetR() / 255.0, c.GetG() / 255.0, c.GetB() / 255.0); +} + +void GLDraw::PutRect(const Rect& r, Color color) +{ + LLOG("PutRect " << r << " " << color); + if(color == InvertColor()) { + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); + glColor3f(1.0f, 1.0f, 1.0f); + } + else + SetColor(color); + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(r.left, r.top); + glVertex2i(r.right, r.top); + glVertex2i(r.left, r.bottom); + glVertex2i(r.right, r.bottom); + glEnd(); + if(color == InvertColor()) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void GLDraw::InitGL(Size sz) +{ + SDraw::Init(sz); + + glEnable(GL_BLEND); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrtho(0, sz.cx, sz.cy, 0, 0.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +}; diff --git a/uppsrc/GLDraw/GLDraw.h b/uppsrc/GLDraw/GLDraw.h new file mode 100644 index 000000000..a203f645d --- /dev/null +++ b/uppsrc/GLDraw/GLDraw.h @@ -0,0 +1,23 @@ +#ifndef _GlDraw_GlDraw_h_ +#define _GlDraw_GlDraw_h_ + +#include +#include + +namespace Upp { + +struct GLDraw : SDraw { + void SetColor(Color c); + + virtual void PutImage(Point p, const Image& m, const Rect& src); + virtual void PutRect(const Rect& r, Color color); + + void InitGL(Size sz); + + static void ClearCache(); + static void ResetCache(); +}; + +}; + +#endif diff --git a/uppsrc/GLDraw/GLDraw.upp b/uppsrc/GLDraw/GLDraw.upp new file mode 100644 index 000000000..c124260fb --- /dev/null +++ b/uppsrc/GLDraw/GLDraw.upp @@ -0,0 +1,8 @@ +uses + Draw, + Painter; + +file + GLDraw.h, + GLDraw.cpp; + diff --git a/uppsrc/GLDraw/init b/uppsrc/GLDraw/init new file mode 100644 index 000000000..0abc51e21 --- /dev/null +++ b/uppsrc/GLDraw/init @@ -0,0 +1,5 @@ +#ifndef _GLDraw_icpp_init_stub +#define _GLDraw_icpp_init_stub +#include "Draw/init" +#include "Painter/init" +#endif