Fix light masks for dark towns

This commit is contained in:
2014-04-18 01:26:05 -04:00
parent dca3c3c18f
commit 55c3f83d22
5 changed files with 40 additions and 36 deletions

View File

@@ -1062,7 +1062,7 @@ void draw_terrain(short mode)
draw_pcs(center,0); draw_pcs(center,0);
// Now do the light mask thing // Now do the light mask thing
apply_light_mask(); apply_light_mask(false);
apply_unseen_mask(); apply_unseen_mask();
terrain_screen_gworld.display(); terrain_screen_gworld.display();
@@ -1587,6 +1587,7 @@ void redraw_terrain()
to_rect = win_to_rects[0]; to_rect = win_to_rects[0];
rect_draw_some_item(terrain_screen_gworld.getTexture(), win_from_rects[0], to_rect,ul); rect_draw_some_item(terrain_screen_gworld.getTexture(), win_from_rects[0], to_rect,ul);
apply_light_mask(true);
// Now place arrows // Now place arrows

View File

@@ -78,9 +78,6 @@ extern cScenario scenario;
extern cUniverse univ; extern cUniverse univ;
//extern talking_record_type talking; //extern talking_record_type talking;
// TODO: Arbitrary region support
std::shared_ptr<Region> oval_region,dark_mask_region,temp_rect_rgn;
// Talk vars // Talk vars
extern word_rect_type store_words[50]; extern word_rect_type store_words[50];
extern eGameMode store_pre_talk_mode; extern eGameMode store_pre_talk_mode;
@@ -186,8 +183,9 @@ void apply_unseen_mask()
} }
} }
void apply_light_mask() void apply_light_mask(bool onWindow)
{ {
static Region dark_mask_region;
RECT temp = {0,0,108,84},paint_rect,base_rect = {0,0,36,28}; RECT temp = {0,0,108,84},paint_rect,base_rect = {0,0,36,28};
RECT big_to = {13,13,337,265}; RECT big_to = {13,13,337,265};
short i,j; short i,j;
@@ -199,11 +197,10 @@ void apply_light_mask()
if (univ.town->lighting_type == 0) if (univ.town->lighting_type == 0)
return; return;
if (oval_region == NULL) { if(onWindow) {
temp_rect_rgn.reset(new Region); mainPtr.setActive();
dark_mask_region.reset(new Region); fill_region(mainPtr, dark_mask_region, sf::Color::Black);
oval_region.reset(new Region); return;
oval_region->addEllipse(temp);
} }
// Process the light array // Process the light array
@@ -244,13 +241,10 @@ void apply_light_mask()
same_mask = false; same_mask = false;
if (same_mask == true) { if (same_mask == true) {
fill_region(terrain_screen_gworld, *dark_mask_region, sf::Color::Black);
mainPtr.setActive();
return; return;
} }
// TODO: Are these regions even used outside this function? If not, they should be local variables. dark_mask_region.clear();
dark_mask_region->clear(); dark_mask_region.addRect(big_to);
dark_mask_region->addRect(big_to);
for (i = 0; i < 13; i++) for (i = 0; i < 13; i++)
for (j = 0; j < 13; j++) for (j = 0; j < 13; j++)
last_light_mask[i][j] = light_area[i][j]; last_light_mask[i][j] = light_area[i][j];
@@ -258,25 +252,25 @@ void apply_light_mask()
for (j = 1; j < 12; j++) { for (j = 1; j < 12; j++) {
if (light_area[i][j] == 2) { if (light_area[i][j] == 2) {
int xOffset = 13 + 28 * (i - 3), yOffset = 13 + 36 * (j - 3); int xOffset = 13 + 28 * (i - 3), yOffset = 13 + 36 * (j - 3);
oval_region->offset(xOffset, yOffset); Region oval_region;
*dark_mask_region -= *oval_region; oval_region.addEllipse(temp);
oval_region->offset(-xOffset, -yOffset); oval_region.offset(xOffset, yOffset);
dark_mask_region -= oval_region;
} }
if (light_area[i][j] == 3) { if (light_area[i][j] == 3) {
paint_rect = base_rect; paint_rect = base_rect;
paint_rect.offset(13 + 28 * (i - 2),13 + 36 * (j - 2)); paint_rect.offset(13 + 28 * (i - 2),13 + 36 * (j - 2));
temp_rect_rgn->clear(); Region temp_rect_rgn;
temp_rect_rgn->addRect(paint_rect); temp_rect_rgn.addRect(paint_rect);
*dark_mask_region -= *temp_rect_rgn; dark_mask_region -= temp_rect_rgn;
if (light_area[i + 1][j] == 3) light_area[i + 1][j] = 0; if (light_area[i + 1][j] == 3) light_area[i + 1][j] = 0;
if (light_area[i + 1][j + 1] == 3) light_area[i + 1][j + 1] = 0; if (light_area[i + 1][j + 1] == 3) light_area[i + 1][j + 1] = 0;
if (light_area[i][j + 1] == 3) light_area[i][j + 1] = 0; if (light_area[i][j + 1] == 3) light_area[i][j + 1] = 0;
} }
} }
//rect_draw_some_item(light_mask_gworld,big_from,terrain_screen_gworld,big_to,0,0); dark_mask_region.offset(5,5);
fill_region(terrain_screen_gworld, *dark_mask_region, sf::Color::Black); dark_mask_region.offset(ul);
} }
void start_missile_anim() void start_missile_anim()

View File

@@ -9,7 +9,7 @@ typedef struct {
} hold_responses; } hold_responses;
void apply_unseen_mask(); void apply_unseen_mask();
void apply_light_mask(); void apply_light_mask(bool onWindow);
void end_anim(); void end_anim();
void init_anim(short which_anim); void init_anim(short which_anim);
void run_anim(); void run_anim();

View File

@@ -918,13 +918,14 @@ void frame_circle(sf::RenderTarget& target, RECT rect, sf::Color colour) {
frame_shape(target, frame, rect.left, rect.top, colour); frame_shape(target, frame, rect.left, rect.top, colour);
} }
void fill_region(sf::RenderTarget& target, Region& region, sf::Color colour) { void fill_region(sf::RenderWindow& target, Region& region, sf::Color colour) {
clip_region(target, region); clip_region(target, region);
fill_rect(target, RECT(target), colour); fill_rect(target, RECT(target), colour);
undo_clip(target); undo_clip(target);
} }
void frame_region(sf::RenderTarget& target, Region& region, sf::Color colour) { void frame_region(sf::RenderWindow& target, Region& region, sf::Color colour) {
// TODO: Uh, actually, this won't do what it says. Eh, I'll fix it if I ever use it.
clip_region(target, region); clip_region(target, region);
frame_rect(target, RECT(target), colour); frame_rect(target, RECT(target), colour);
undo_clip(target); undo_clip(target);
@@ -957,17 +958,25 @@ void Region::offset(location off) {
offset(off.x, off.y); offset(off.x, off.y);
} }
void Region::setStencil(sf::RenderTarget& where) { // We can only use stencil buffer in the main window
setActiveRenderTarget(where); // Could request it in dialogs, but currently don't
// SFML does not appear to allow requesting it for render textures
void Region::setStencil(sf::RenderWindow& where) {
where.setActive();
glClearStencil(0); glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 1); glStencilFunc(GL_ALWAYS, 1, 1);
for(auto shape : shapes) { for(auto shape : shapes) {
if(shape->getFillColor() == sf::Color::Black) // Save the colour in case we need to reuse this region
sf::Color colour = shape->getFillColor();
if(colour == sf::Color::Black)
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
else glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); else glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
// Make transparent so we don't overwrite important stuff
shape->setFillColor(sf::Color::Transparent);
where.draw(*shape); where.draw(*shape);
shape->setFillColor(colour);
} }
glStencilFunc(GL_EQUAL, 1, 1); glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@@ -980,7 +989,7 @@ void clip_rect(sf::RenderTarget& where, RECT rect) {
glScissor(rect.left, RECT(where).height() - rect.bottom, rect.width(), rect.height()); glScissor(rect.left, RECT(where).height() - rect.bottom, rect.width(), rect.height());
} }
void clip_region(sf::RenderTarget& where, Region& region) { void clip_region(sf::RenderWindow& where, Region& region) {
region.setStencil(where); region.setStencil(where);
} }

View File

@@ -61,8 +61,8 @@ struct TextStyle {
class Region { class Region {
std::vector<std::shared_ptr<sf::Shape>> shapes; std::vector<std::shared_ptr<sf::Shape>> shapes;
void setStencil(sf::RenderTarget& where); void setStencil(sf::RenderWindow& where);
friend void clip_region(sf::RenderTarget& where, Region& region); friend void clip_region(sf::RenderWindow& where, Region& region);
public: public:
void addEllipse(RECT frame); void addEllipse(RECT frame);
void addRect(RECT rect); void addRect(RECT rect);
@@ -115,11 +115,11 @@ void fill_circle(sf::RenderTarget& target, RECT rect, sf::Color colour);
void frame_circle(sf::RenderTarget& target, RECT rect, sf::Color colour); void frame_circle(sf::RenderTarget& target, RECT rect, sf::Color colour);
void fill_roundrect(sf::RenderTarget& target, RECT rect, int rad, sf::Color colour); void fill_roundrect(sf::RenderTarget& target, RECT rect, int rad, sf::Color colour);
void frame_roundrect(sf::RenderTarget& target, RECT rect, int rad, sf::Color colour); void frame_roundrect(sf::RenderTarget& target, RECT rect, int rad, sf::Color colour);
void fill_region(sf::RenderTarget& target, Region& region, sf::Color colour); void fill_region(sf::RenderWindow& target, Region& region, sf::Color colour);
void frame_region(sf::RenderTarget& target, Region& region, sf::Color colour); void frame_region(sf::RenderWindow& target, Region& region, sf::Color colour);
void clip_rect(sf::RenderTarget& where, RECT rect); void clip_rect(sf::RenderTarget& where, RECT rect);
void clip_region(sf::RenderTarget& where, Region& region); void clip_region(sf::RenderWindow& where, Region& region);
void undo_clip(sf::RenderTarget& where); void undo_clip(sf::RenderTarget& where);
#ifndef GRAPHTOOL_CPP #ifndef GRAPHTOOL_CPP