OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2010, Google Inc. | 2 * Copyright 2010, Google Inc. |
fbarchard
2011/01/19 18:51:20
update to 2011
Tristan Schmelcher 2
2011/01/20 00:26:16
Done.
| |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * * Redistributions in binary form must reproduce the above | 11 * * Redistributions in binary form must reproduce the above |
12 * copyright notice, this list of conditions and the following disclaimer | 12 * copyright notice, this list of conditions and the following disclaimer |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 // Sort layers by z value. | 88 // Sort layers by z value. |
89 // TODO(tschmelcher): Only sort when changes are made. | 89 // TODO(tschmelcher): Only sort when changes are made. |
90 layer_list_.sort(LayerZValueLessThan); | 90 layer_list_.sort(LayerZValueLessThan); |
91 | 91 |
92 // Paint the background. | 92 // Paint the background. |
93 PaintBackground(current_drawing); | 93 PaintBackground(current_drawing); |
94 | 94 |
95 // Core process of painting. | 95 // Core process of painting. |
96 for (LayerList::iterator i = layer_list_.begin(); | 96 for (LayerList::iterator i = layer_list_.begin(); |
97 i != layer_list_.end(); i++) { | 97 i != layer_list_.end(); i++) { |
98 // Put the state with no mask to the stack. | 98 Layer* cur = *i; |
99 if (!cur->ShouldPaint()) continue; | |
100 | |
101 Pattern* pattern = cur->pattern(); | |
102 | |
103 // Save the current drawing state. | |
99 cairo_save(current_drawing); | 104 cairo_save(current_drawing); |
100 | 105 |
101 // Preparing and updating the Layer. | 106 // Clip areas that will be obscured anyway. |
102 Layer* cur = *i; | 107 LayerList::iterator start_mask_it = i; |
103 Pattern* pattern = cur->pattern(); | 108 start_mask_it++; |
104 if (!pattern) { | 109 ClipArea(current_drawing, start_mask_it); |
105 // Skip layers with no pattern assigned. | 110 |
106 continue; | 111 // Define the region to fill. |
112 cairo_rectangle(current_drawing, | |
113 cur->x(), | |
114 cur->y(), | |
115 cur->width(), | |
116 cur->height()); | |
117 | |
118 // Transform the pattern to fit into the fill region. | |
119 cairo_translate(current_drawing, cur->x(), cur->y()); | |
120 cairo_scale(current_drawing, cur->scale_x(), cur->scale_y()); | |
121 | |
122 // Set source pattern. | |
123 cairo_set_source(current_drawing, pattern->pattern()); | |
124 | |
125 // Paint the pattern to the off-screen surface. | |
126 switch (cur->paint_operator()) { | |
127 case Layer::BLEND: | |
128 cairo_fill(current_drawing); | |
129 break; | |
130 | |
131 case Layer::BLEND_WITH_TRANSPARENCY: | |
132 { | |
133 cairo_pattern_t* mask = cairo_pattern_create_rgba(0.0, | |
134 0.0, | |
135 0.0, | |
136 cur->alpha()); | |
fbarchard
2011/01/19 18:51:20
Can transparency be done with flat shading?
provid
Tristan Schmelcher 2
2011/01/20 00:26:16
That's basically what this is. The "mask" is an AR
fbarchard
2011/01/20 18:06:05
shading, not shaders.
flat shading is like Gouraud
Tristan Schmelcher 2
2011/01/20 20:43:32
I'm pretty sure it's right. You can look up the do
| |
137 cairo_mask(current_drawing, mask); | |
138 cairo_pattern_destroy(mask); | |
139 } | |
140 break; | |
141 | |
142 case Layer::COPY: | |
143 case Layer::COPY_WITH_FADING: // Not implemented yet; treat as COPY | |
fbarchard
2011/01/19 18:51:20
mark as todo?
Can also be done with shading?
or at
Tristan Schmelcher 2
2011/01/20 00:26:16
Done.
| |
144 // Set Cairo to copy the pattern's alpha content instead of blending. | |
145 cairo_set_operator(current_drawing, CAIRO_OPERATOR_SOURCE); | |
146 cairo_fill(current_drawing); | |
147 break; | |
107 } | 148 } |
108 | 149 |
109 // Masking areas for other scene. | 150 // Restore to a clean state. |
110 LayerList::iterator start_mask_it = i; | |
111 start_mask_it++; | |
112 MaskArea(current_drawing, start_mask_it); | |
113 | |
114 cairo_translate(current_drawing, cur->x(), cur->y()); | |
115 | |
116 cairo_scale(current_drawing, cur->scale_x(), cur->scale_y()); | |
117 | |
118 // Painting the image to the surface. | |
119 cairo_set_source(current_drawing, pattern->pattern()); | |
120 | |
121 cairo_paint_with_alpha(current_drawing, cur->alpha()); | |
122 | |
123 // Restore to the state with no mask. | |
124 cairo_restore(current_drawing); | 151 cairo_restore(current_drawing); |
125 } | 152 } |
126 | 153 |
127 // Finish off-screen drawing and make the off-screen surface the source for | 154 // Finish off-screen drawing and make the off-screen surface the source for |
128 // paints to the screen. | 155 // paints to the screen. |
129 cairo_pop_group_to_source(current_drawing); | 156 cairo_pop_group_to_source(current_drawing); |
130 | 157 |
131 // Paint the off-screen surface to the screen. | 158 // Paint the off-screen surface to the screen. |
132 cairo_paint(current_drawing); | 159 cairo_paint(current_drawing); |
133 | 160 |
134 cairo_destroy(current_drawing); | 161 cairo_destroy(current_drawing); |
135 } | 162 } |
136 | 163 |
137 void RendererCairo::PaintBackground(cairo_t* cr) { | 164 void RendererCairo::PaintBackground(cairo_t* cr) { |
138 cairo_save(cr); | 165 cairo_save(cr); |
139 MaskArea(cr, layer_list_.begin()); | 166 ClipArea(cr, layer_list_.begin()); |
140 | 167 |
141 cairo_rectangle(cr, 0, 0, display_width(), display_height()); | 168 cairo_rectangle(cr, 0, 0, display_width(), display_height()); |
142 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); | 169 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); |
143 cairo_fill(cr); | 170 cairo_fill(cr); |
144 cairo_restore(cr); | 171 cairo_restore(cr); |
145 } | 172 } |
146 | 173 |
147 void RendererCairo::MaskArea(cairo_t* cr, LayerList::iterator it) { | 174 void RendererCairo::ClipArea(cairo_t* cr, LayerList::iterator it) { |
148 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); | 175 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); |
149 | 176 |
150 for (LayerList::iterator i = it; i != layer_list_.end(); i++) { | 177 for (LayerList::iterator i = it; i != layer_list_.end(); i++) { |
151 // Preparing and updating the Layer. | 178 // Preparing and updating the Layer. |
152 Layer* cur_mask = *i; | 179 Layer* cur = *i; |
180 if (!cur->ShouldClip()) continue; | |
153 | 181 |
154 cairo_rectangle(cr, 0, 0, display_width(), display_height()); | 182 cairo_rectangle(cr, 0, 0, display_width(), display_height()); |
155 cairo_rectangle(cr, | 183 cairo_rectangle(cr, |
156 cur_mask->x(), | 184 cur->x(), |
157 cur_mask->y(), | 185 cur->y(), |
158 cur_mask->width(), | 186 cur->width(), |
159 cur_mask->height()); | 187 cur->height()); |
160 cairo_clip(cr); | 188 cairo_clip(cr); |
161 } | 189 } |
162 } | 190 } |
163 | 191 |
164 void RendererCairo::AddLayer(Layer* image) { | 192 void RendererCairo::AddLayer(Layer* image) { |
165 layer_list_.push_front(image); | 193 layer_list_.push_front(image); |
166 } | 194 } |
167 | 195 |
168 void RendererCairo::RemoveLayer(Layer* image) { | 196 void RendererCairo::RemoveLayer(Layer* image) { |
169 layer_list_.remove(image); | 197 layer_list_.remove(image); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 NOTIMPLEMENTED(); | 460 NOTIMPLEMENTED(); |
433 } | 461 } |
434 | 462 |
435 void RendererCairo::PopRenderStates() { | 463 void RendererCairo::PopRenderStates() { |
436 NOTIMPLEMENTED(); | 464 NOTIMPLEMENTED(); |
437 } | 465 } |
438 | 466 |
439 } // namespace o2d | 467 } // namespace o2d |
440 | 468 |
441 } // namespace o3d | 469 } // namespace o3d |
OLD | NEW |