[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog backend/render_handler_ogl.cpp
From: |
Bastiaan Jacques |
Subject: |
[Gnash-commit] gnash ChangeLog backend/render_handler_ogl.cpp |
Date: |
Fri, 23 Nov 2007 22:55:17 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Bastiaan Jacques <bjacques> 07/11/23 22:55:17
Modified files:
. : ChangeLog
backend : render_handler_ogl.cpp
Log message:
Implement nested masks. Also take advantage of changes to type 'point'
in trace_curve.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4946&r2=1.4947
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/render_handler_ogl.cpp?cvsroot=gnash&r1=1.89&r2=1.90
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4946
retrieving revision 1.4947
diff -u -b -r1.4946 -r1.4947
--- ChangeLog 23 Nov 2007 22:23:24 -0000 1.4946
+++ ChangeLog 23 Nov 2007 22:55:16 -0000 1.4947
@@ -1,3 +1,8 @@
+2007-11-23 Bastiaan Jacques <address@hidden>
+
+ * backend/render_handler_ogl.cpp: Implement nested masks. Also take
+ advantage of changes to type 'point' in trace_curve.
+
2007-11-23 Sandro Santilli <address@hidden>
* server/: Makefile.am, impl.cpp, parser/sound_definition.{cpp,h}
Index: backend/render_handler_ogl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/render_handler_ogl.cpp,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -b -r1.89 -r1.90
--- backend/render_handler_ogl.cpp 10 Nov 2007 14:39:52 -0000 1.89
+++ backend/render_handler_ogl.cpp 23 Nov 2007 22:55:17 -0000 1.90
@@ -42,6 +42,7 @@
#include "render_handler_ogl.h"
#include <boost/utility.hpp>
+#include <boost/bind.hpp>
/// \file render_handler_ogl.cpp
/// \brief The OpenGL renderer and related code.
@@ -83,9 +84,10 @@
// TODO:
// - Implement:
-// * Nested masks
// * Alpha images
-// * Real antialiasing
+// * Real antialiasing: Currently, we just draw an anti-aliased outline around
+// solid shapes and fonts. Besides not anti-aliasing other types of shapes,
+// this makes fonts a bit bigger than intended.
//
// - Profiling!
// - Optimize code:
@@ -233,9 +235,7 @@
// Midpoint on the curve.
point q = middle(mid, controlP);
- float dist = std::abs(mid.x - q.x) + std::abs(mid.y - q.y);
-
- if (dist < 0.1 /*error tolerance*/) {
+ if (mid.distance(q) < 0.1 /*error tolerance*/) {
coords.push_back(oglVertex(endP));
} else {
// Error is too large; subdivide.
@@ -534,7 +534,8 @@
public:
render_handler_ogl()
: _xscale(1.0),
- _yscale(1.0)
+ _yscale(1.0),
+ _drawing_mask(false)
{
}
@@ -818,28 +819,79 @@
virtual void begin_submit_mask()
{
+ PathVec mask;
+ _masks.push_back(mask);
+
+ _drawing_mask = true;
+ }
+
+ virtual void end_submit_mask()
+ {
+ _drawing_mask = false;
+
+ apply_mask();
+ }
+
+ /// Apply the current mask; nesting is supported.
+ ///
+ /// This method marks the stencil buffer by incrementing every stencil pixel
+ /// by one every time a solid from one of the current masks is drawn. When
+ /// all the mask solids are drawn, we change the stencil operation to permit
+ /// only drawing where all masks have drawn, in other words, where all masks
+ /// intersect, or in even other words, where the stencil pixel buffer equals
+ /// the number of masks.
+ void apply_mask()
+ {
+ if (_masks.empty()) {
+ return;
+ }
+
glEnable(GL_STENCIL_TEST);
+
glClearStencil(0x0); // FIXME: default is zero, methinks
glClear(GL_STENCIL_BUFFER_BIT);
- // Since we are marking the stencil, the stencil function test should
- // always succeed.
+ // GL_NEVER means the stencil test will never succeed, so OpenGL wil never
+ // continue to the drawing stage.
glStencilFunc (GL_NEVER, 0x1, 0x1);
- glStencilOp (GL_REPLACE /* Stencil test fails */ ,
- GL_ZERO /* Value is ignored */ ,
- GL_REPLACE /* Stencil test passes */);
+ glStencilOp (GL_INCR /* Stencil test fails */,
+ GL_KEEP /* ignored */,
+ GL_KEEP /* Stencil test passes; never happens */);
+
+ // Call add_paths for each mask.
+ std::for_each(_masks.begin(), _masks.end(),
+ boost::bind(&render_handler_ogl::add_paths, boost::ref(this), _1));
+
+ glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
+ glStencilFunc(GL_EQUAL, _masks.size(), _masks.size());
}
- virtual void end_submit_mask()
+ void
+ add_paths(const PathVec& path_vec)
{
- glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilFunc(GL_EQUAL, 0x1, 0x1);
+ cxform dummy_cx;
+ std::vector<fill_style> dummy_fs;
+
+ fill_style coloring;
+ coloring.setSolid(rgba(0,0,0,0));
+
+ dummy_fs.push_back(coloring);
+
+ std::vector<line_style> dummy_ls;
+
+ draw_subshape(path_vec, matrix::identity, dummy_cx, 1.0, dummy_fs,
dummy_ls);
}
virtual void disable_mask()
{
+ _masks.pop_back();
+
+ if (_masks.empty()) {
glDisable(GL_STENCIL_TEST);
+ } else {
+ apply_mask();
+ }
}
#if 0
@@ -1241,7 +1293,17 @@
}
+ void draw_mask(const PathVec& path_vec)
+ {
+ for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
+ it != end; ++it) {
+ const path& cur_path = *it;
+ if (cur_path.m_fill0 || cur_path.m_fill1) {
+ _masks.back().push_back(cur_path);
+ }
+ }
+ }
PathPtrVec
get_paths_by_style(const PathVec& path_vec, unsigned int style)
@@ -1290,6 +1352,51 @@
return subshapes;
}
+ /// Takes a path and translates it using the given matrix. The new path
+ /// is stored in paths_out.
+ /// Taken from render_handler_agg.cpp.
+ void apply_matrix_to_paths(const std::vector<path> &paths_in,
+ std::vector<path> &paths_out, const matrix& mat) {
+
+ int pcount, ecount;
+ int pno, eno;
+
+ // copy path
+ paths_out = paths_in;
+ pcount = paths_out.size();
+
+ for (pno=0; pno<pcount; pno++) {
+
+ path &the_path = paths_out[pno];
+ point oldpnt(the_path.ap.x, the_path.ap.y);
+ point newpnt;
+ mat.transform(&newpnt, oldpnt);
+ the_path.ap.x = newpnt.x;
+ the_path.ap.y = newpnt.y;
+
+ ecount = the_path.m_edges.size();
+ for (eno=0; eno<ecount; eno++) {
+
+ edge &the_edge = the_path.m_edges[eno];
+
+ oldpnt.x = the_edge.ap.x;
+ oldpnt.y = the_edge.ap.y;
+ mat.transform(&newpnt, oldpnt);
+ the_edge.ap.x = newpnt.x;
+ the_edge.ap.y = newpnt.y;
+
+ oldpnt.x = the_edge.cp.x;
+ oldpnt.y = the_edge.cp.y;
+ mat.transform(&newpnt, oldpnt);
+ the_edge.cp.x = newpnt.x;
+ the_edge.cp.y = newpnt.y;
+
+ }
+
+ }
+
+ }
+
void
draw_subshape(const PathVec& path_vec,
@@ -1391,6 +1498,14 @@
return;
}
+ if (_drawing_mask) {
+ PathVec scaled_path_vec;
+
+ apply_matrix_to_paths(path_vec, scaled_path_vec, mat);
+ draw_mask(scaled_path_vec);
+ return;
+ }
+
bool have_shape, have_outline;
analyze_paths(path_vec, have_shape, have_outline);
@@ -1423,6 +1538,7 @@
virtual void draw_glyph(shape_character_def *def, const matrix& mat,
const rgba& c, float pixel_scale)
{
+ if (_drawing_mask) abort();
cxform dummy_cx;
std::vector<fill_style> glyph_fs;
@@ -1484,6 +1600,10 @@
Tesselator _tesselator;
float _xscale;
float _yscale;
+
+ std::vector<PathVec> _masks;
+ bool _drawing_mask;
+
#ifdef OSMESA_TESTING
std::auto_ptr<OSRenderMesa> _offscreen;
#endif
- [Gnash-commit] gnash ChangeLog backend/render_handler_ogl.cpp,
Bastiaan Jacques <=