Ejemplo n.º 1
0
Archivo: hand.c Proyecto: dblack/ccards
int hand_has_flush(Hand *hand)
{
    int i;
    for (i = 1; i < hand->len; i++) 
	if (strcmp(suit(0), suit(i))) 
	    return 0;	
    return 1;
}
Ejemplo n.º 2
0
Archivo: war.c Proyecto: LihuaWu/recipe
testcards(){
	int i;				/* counter */
	char suit(), value();		/* reconstructed card */

	for (i=0; i<NCARDS; i++)
		printf(" i=%d card[i]=%c%c rank=%d\n", i, value(i),
			suit(i), rank_card(value(i),suit(i)) );
}
Ejemplo n.º 3
0
/*
 * Function to determine whether the hand should get 
 * an extra point for having the right jack.
 */
score_t right_jack(hand_t * hand) 
{
    Suits_t cs = suit(hand->crib);
    for(card_t i = 0; i < HAND_SIZE; i++) {
        if (type(hand->cards[i]) == Jack 
                && suit(hand->cards[i]) == cs) {
            return 1;
        }
    }
    return 0;
}
Ejemplo n.º 4
0
/* Helper function to transform a single card to a string. */
char * ntoh_h(card_t card) 
{
    char *n = calloc(MAX_NTOH, sizeof(char));
    strncpy(n, TYPES[type(card)], MAX_SUITS);
    strncpy(n, SUITS[suit(card)], MAX_TYPES);
    return n;
}
Ejemplo n.º 5
0
bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const
{
	if (!anyChecked) {
		return true;
	}

	// Checked means 'Show', Unchecked means 'Hide'.
	QString suit(d->suit);
	// only show empty suit dives if the user checked that.
	if (suit.isEmpty()) {
		if (rowCount() > 0)
			return checkState[rowCount() - 1];
		else
			return true;
	}

	// there is a suit selected
	QStringList suitList = stringList();
	if (!suitList.isEmpty()) {
		suitList.removeLast(); // remove the "Show Empty Suits";
		for (int i = 0; i < rowCount(); i++) {
			if (checkState[i] && (suit.indexOf(stringList()[i]) != -1)) {
				return true;
			}
		}
	}
	return false;
}
Ejemplo n.º 6
0
void Pnj::IA() {
    if (id == 3) {
        if (gpJeu->getJoueur()->getAvancement()==4) {
            if (y<30*16) {direction=N; moveY(1);}
            else if (x>28*16) {direction=N; moveX(-1);}
        } else if (x>=gpJeu->getJoueur()->getX()) direction=O;
        else direction=E;
    }
    
    if (id == 15 && !immo && gpJeu->getZone()==9 && gpJeu->getJoueur()->getAvancement()==6) {
        if (x>74*16-8) {direction=O; x-=1;}
        else if (y<22*16) {direction=S; y+=1;}
        else if (x>66*16-8) {direction=O; x-=1;}
        else {gpJeu->getJoueur()->setImmo(false); vie=0;gpJeu->getJoueur()->setAvancement(7);
            gpJeu->getMonde()->setValeur(64*16, 20*16, 923, -1, LIBRE, 0);
            gpJeu->getMonde()->setValeur(65*16, 20*16, 924, -1, LIBRE, 0);
            gpJeu->getMonde()->setValeur(64*16, 21*16, 925, -1, LIBRE, 0);
            gpJeu->getMonde()->setValeur(65*16, 21*16, 926, -1, LIBRE, 0);
        }
        return;
    }
    
    
    if (immo) return;
    if (parle()) return;
    if (typeIA==IA_SUIT) suit();
    if (typeIA==IA_RANDOM) bouge();
}
Ejemplo n.º 7
0
void SuitsFilterModel::repopulate()
{
	QStringList list;
	struct dive *dive;
	int i = 0;
	for_each_dive (i, dive) {
		QString suit(dive->suit);
		if (!suit.isEmpty() && !list.contains(suit)) {
			list.append(suit);
		}
	}
Ejemplo n.º 8
0
QString KCardInfo::svgName() const
{
    QString s;
    if( card() == KCardInfo::Ace )
        s += QLatin1String( "1_" );
    if( card() == KCardInfo::King )
        s += QLatin1String( "king_" );
    if( card() == KCardInfo::Queen )
        s += QLatin1String( "queen_" );
    if( card() == KCardInfo::Jack )
        s += QLatin1String( "jack_" );
    if( card() == KCardInfo::Ten )
        s += QLatin1String( "10_" );
    if( card() == KCardInfo::Nine )
        s += QLatin1String( "9_" );
    if( card() == KCardInfo::Eight )
        s += QLatin1String( "8_" );
    if( card() == KCardInfo::Seven )
        s += QLatin1String( "7_" );
    if( card() == KCardInfo::Six )
        s += QLatin1String( "6_" );
    if( card() == KCardInfo::Five )
        s += QLatin1String( "5_" );
    if( card() == KCardInfo::Four )
        s += QLatin1String( "4_" );
    if( card() == KCardInfo::Three )
        s += QLatin1String( "3_" );
    if( card() == KCardInfo::Two )
        s += QLatin1String( "2_" );
    if( suit() == KCardInfo::Club )
        s += QLatin1String( "club" );
    if( suit() == KCardInfo::Spade )
        s += QLatin1String( "spade" );
    if( suit() == KCardInfo::Diamond )
        s += QLatin1String( "diamond" );
    if( suit() == KCardInfo::Heart )
        s += QLatin1String( "heart" );
    return s;
}
Ejemplo n.º 9
0
void Manager::handleClaimMaster(ValueEvent<ClaimMasterMsg>* e)
{
    auto v = e->value();
    Seat* s = seat(v.seat());
    Card::Suit suit = (Card::Suit)v.suit();
    if (mStatus != Deal && mStatus != DealWait &&
        mStatus != DealFinish && mStatus != ChangeDealer) {
        notifyClaimMasterFail(s, ErrorCode::StatusError);
        return;
    }
    try {
        mChecker->claimMaster(mMaster, s, suit);
        notifyFixMaster(mMaster);
    } catch (Exception& excp) {
        notifyClaimMasterFail(s, excp.code());
    }
}
Ejemplo n.º 10
0
void shuffle(Card* cards) {
int a,b,c;
Card tmp;

for(a = 0; a < N; a++) {
	suit(a + 1, cards[a].suit);
        symbol(a + 1, cards[a].symbol);
}

for(b = 0; b < N; b++) {
	c = rand() % 52;
        tmp = cards[b];
        cards[b] = cards[c];
        cards[c] = tmp;
}

}
Ejemplo n.º 11
0
///	Show Poker card suit and point.
void PokerCard::show()
{
	LOG_INFO("Suit: %s, Point: %s", enum2str(suit()), enum2str(point()));
}
Ejemplo n.º 12
0
bool KCardInfo::operator==( const KCardInfo& c ) const
{
    return ( c.card() == card() && c.suit() == suit() );
}
Ejemplo n.º 13
0
Card DefenceAi::play_card(FateAi const& ai) {
    // TODO: Rethink this function for partnership contracts
    Trick const& trick = ai.tricks().back();
    //Cards const& hand = ai.hand();
    Cards const plays = ai.legal_plays();
    boost::optional<Card> bird = ai.relevant_bird();

    // If there's only one legal play, play it
    if (plays.size() == 1) {
        return *plays.begin();
    }

    if (trick.played() == 0) {
        // We're leading
        if (guess_master_defender_) {
            // Lead a long suit
            for (SuitProfiles::reverse_iterator it = suit_profiles_.rbegin();
                    it != suit_profiles_.rend(); ++it) {
                if (it->suit == Suit::trumps) continue;
                auto playable = plays.equal_range(it->suit);
                if (!boost::empty(playable)) {
                    return *playable.first;
                }
            }
        } else {
            // Lead a short suit
            for (SuitProfiles::iterator it = suit_profiles_.begin();
                    it != suit_profiles_.end(); ++it) {
                if (it->suit == Suit::trumps) continue;
                auto playable = plays.equal_range(it->suit);
                if (!boost::empty(playable)) {
                    return *playable.first;
                }
            }
        }
        // At this point we must be playing trumps; play low
        assert(plays.begin()->trump());
        auto candidate = plays.begin();
        // Avoid leading a bird that might cause us to lose game points
        if (bird && *candidate == *bird) ++candidate;
        return *candidate;
    } else {
        // We're following
        Suit s = trick.suit();
        bool const playing_trump = plays.begin()->trump();
        bool const roughing = playing_trump && s != Suit::trump;

        const int declarers_position_in_trick =
            (ai.declarer() - trick.leader() + 4)%4;
        const bool declarer_has_played =
            trick.played() > declarers_position_in_trick;

        if (declarer_has_played) {
            bool const declarer_is_winning =
                trick.winner() == ai.declarer();

            if (declarer_is_winning) {
                auto winning_play = plays.lower_bound(trick.winning_card());
                if (winning_play != plays.end() && !winning_play->trump() &&
                        winning_play->suit() != s) {
                    winning_play = plays.end();
                }

                if (roughing) {
                    // If I'm last to play then make an effort to win
                    if (trick.played() == 3 && winning_play != plays.end()) {
                        return *winning_play;
                    }
                    // Otherwise just play low
                    return *plays.begin();
                } else if (playing_trump) {
                    // Following in trumps
                    if (winning_play != plays.end()) {
                        // Win minimally
                        return *winning_play;
                    } else {
                        // Can't win; play low
                        return *plays.begin();
                    }
                } else {
                    // Declarer is winning and I'm following suit or discarding
                    if (winning_play != plays.end()) {
                        // We can win in a side suit; play card worth most points, or least
                        // valuable winning pip card
                        auto most_points = std::max_element(
                                               winning_play, plays.end(), Card::CompareRanksReversePips()
                                           );
                        return *most_points;
                    }

                    // Can't win, so play low
                    /** \bug Discarding something valuable sometimes under these
                     * circumstances is pretty vital */
                    auto smallest_rank = std::min_element(
                                             plays.begin(), plays.end(), Card::CompareSuitRanks()
                                         );
                    return *smallest_rank;
                }
            } else {
                if (roughing) {
                    // Play smallest trump
                    return *plays.begin();
                } else if (playing_trump) {
                    // I'm following in trumps, but the defense is already going to win,
                    // so just play low
                    /** \bug Really person before declarer should deliberately beat
                     * the other defenders sometimes */
                    return *plays.begin();
                } else {
                    // Play card worth most points, or least valuable pip card
                    auto most_points = std::max_element(
                                           plays.begin(), plays.end(), Card::CompareRanksReversePips()
                                       );
                    return *most_points;
                }
            }
        } else {
            // Declarer hasn't played yet.
            bool const defence_will_win =
                ai.guaranteed_to_win_against(trick.winning_card(), ai.declarer());
            if (defence_will_win) {
                if (playing_trump) {
                    // We're winning anyway, so play a low trump
                    return *plays.begin();
                } else {
                    // Play something worth points
                    auto most_points = std::max_element(
                                           plays.begin(), plays.end(), Card::CompareRanksReversePips()
                                       );
                    return *most_points;
                }
            } else {
                // Defence not guaranteed to win, so declarer probably will.  Play
                // something worthless
                if (playing_trump) {
                    return *plays.begin();
                } else {
                    return *boost::range::min_element(
                               plays, Card::CompareSuitRanks()
                           );
                }
            }
        }
    }

    KONIG_FATAL("unimplimented (" << ai.tricks().size() << "): " << trick);
}
Ejemplo n.º 14
0
int main() {

	// Dimensions 
	const GLuint WIDTH = 1080;
	const GLuint HEIGHT = 720;
	const GLuint SWIDTH = 1024; // Shadow map
	const GLuint SHEIGHT = 1024;
	// End dimensions

	// GLFW setup
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Only use OpenGL version 3
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Lock window size
	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "MEng Project SSAO", nullptr, nullptr); // Create window
	if (window == nullptr) { // Error Check
		std::cout << "ERROR: Failed to create window" << std::endl;
		glfwTerminate();
		return -1;
	} 
	glfwMakeContextCurrent(window);
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Bind mouse to window
	glfwSetKeyCallback(window, keyPress); // Add input handling functions
	glfwSetCursorPosCallback(window, mouseMove);
	// End GLFW setup

	// GLEW setup
	glewExperimental = GL_TRUE; // Ensures access to up to date opengl functions
	if (glewInit() != GLEW_OK) { // Error check
		std::cout << "ERROR: Failed to initialise GLEW" << std::endl;
		return -1;
	}
	// End GLEW setup

	// OpenGL setup
	glViewport(0, 0, WIDTH, HEIGHT); // Pass window dimensions 
	glEnable(GL_DEPTH_TEST); // Required for proper depth testing
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black back drop
	// End OpenGL setup

	// Loading and object creation
	Camera camera = Camera(); // Create camera
	Shader gShader("geometry.vs", "geometry.frag"); // Shader loading
	Shader lightShader("light.vs", "light.frag");
	Shader shadowShader("shadow.vs", "shadow.frag", "shadow.gs");
	Model suit("nanosuit/nanosuit.obj"); // Model loading
	Model bunny("bunny/bunny.obj");
	Model armadillo("armadillo/armadillo.obj");
	// End loading and object creation	

	// Geometry input
	GLfloat verticesFloor[] = { // Geometry for floor object (Just a cube that we flatten out)
		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 0.0f, 0.0f,
		0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 1.0f, 0.0f,
		0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 1.0f, 1.0f,
		0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 1.0f, 1.0f,
		-0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 0.0f, 1.0f,
		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 0.0f, 0.0f,

		-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f, 0.0f, 0.0f,
		0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f, 1.0f, 0.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f, 1.0f, 1.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f, 1.0f, 1.0f,
		-0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f, 0.0f, 1.0f,
		-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f, 0.0f, 0.0f,

		-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f, 1.0f, 0.0f,
		-0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f, 1.0f, 1.0f,
		-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f, 0.0f, 1.0f,
		-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f, 0.0f, 1.0f,
		-0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f, 0.0f, 0.0f,
		-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f, 1.0f, 0.0f,

		0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f, 1.0f, 0.0f,
		0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f, 1.0f, 1.0f,
		0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f, 0.0f, 1.0f,
		0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f, 0.0f, 1.0f,
		0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f, 0.0f, 0.0f,
		0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f, 1.0f, 0.0f,

		-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f, 0.0f, 1.0f,
		0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f, 1.0f, 1.0f,
		0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f, 1.0f, 0.0f,
		0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f, 1.0f, 0.0f,
		-0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f, 0.0f, 0.0f,
		-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f, 0.0f, 1.0f,

		-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f, 0.0f, 1.0f,
		0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f, 1.0f, 1.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f, 1.0f, 0.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f, 1.0f, 0.0f,
		-0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f, 0.0f, 0.0f,
		-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f
	};
	GLfloat verticesQuad[] = { // Quad that we render to for screen space techniques
		-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
		-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
		1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
		1.0f, -1.0f, 0.0f, 1.0f, 0.0f
	};
	glm::vec3 lightPosition = glm::vec3(10.0f, 10.0f, 10.0f); // Initial position of point light
	glm::mat4 bunnyModel1, bunnyModel2, suitModel, armaModel, floorModel; // Sets up uniforms for location of models in world
	bunnyModel1 = glm::translate(bunnyModel1, glm::vec3(0.0f, 0.15f, 0.0f));
	bunnyModel2 = glm::translate(bunnyModel2, glm::vec3(5.0f, 0.15f, 0.0f));
	suitModel = glm::translate(suitModel, glm::vec3(15.0f, 0.0f, 0.0f));
	armaModel = glm::translate(armaModel, glm::vec3(5.0f, 0.5f, 5.0f));
	floorModel = glm::scale(floorModel, glm::vec3(100.0f, 0.1f, 100.0f));
	// End geometry input

	// Shader texture uniforms
	lightShader.Use();
	glUniform1i(glGetUniformLocation(lightShader.pID, "gPosition"), 0);
	glUniform1i(glGetUniformLocation(lightShader.pID, "gNormal"), 1);
	glUniform1i(glGetUniformLocation(lightShader.pID, "gColour"), 2);
	gShader.Use();
	glUniform1i(glGetUniformLocation(gShader.pID, "shadowMap"), 0);
	// End shader texture uniforms

	// Shadow mapping setup
	GLuint shadowMap, shadowBuffer;
	glGenFramebuffers(1, &shadowBuffer);
	glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer);
	glGenTextures(1, &shadowMap);
	glBindTexture(GL_TEXTURE_CUBE_MAP, shadowMap);
	for (GLuint i = 0; i < 6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SWIDTH, SHEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMap, 0);
	glDrawBuffer(GL_NONE);
	glReadBuffer(GL_NONE);
	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "ERROR: Shadow buffer not complete" << std::endl; // Error check
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	// End shadow mapping setup


	// gBuffer for deferred rendering
	GLuint gBuffer, gPosition, gNormal, gColour, gDepth;
	glGenFramebuffers(1, &gBuffer);
	glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
	glGenTextures(1, &gPosition); // Set up position data storage
	glBindTexture(GL_TEXTURE_2D, gPosition);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);
	glGenTextures(1, &gNormal); // Set up normal data storage
	glBindTexture(GL_TEXTURE_2D, gNormal);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, WIDTH, HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0);
	glGenTextures(1, &gColour); // Set up colour data storage
	glBindTexture(GL_TEXTURE_2D, gColour);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gColour, 0);
	GLuint attach[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
	glDrawBuffers(3, attach);
	glGenRenderbuffers(1, &gDepth); // Set up depth
	glBindRenderbuffer(GL_RENDERBUFFER, gDepth);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WIDTH, HEIGHT);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gDepth);
	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "ERROR: Geometry framebuffer not complete" << std::endl; // Error check
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	// End GBuffer

	// Quad buffer object
	GLuint qVBO, qVAO;
	glGenVertexArrays(1, &qVAO);
	glGenBuffers(1, &qVBO);
	glBindVertexArray(qVAO);
	glBindBuffer(GL_ARRAY_BUFFER, qVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verticesQuad), verticesQuad, GL_STATIC_DRAW); // Pass in quad geometry
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); // Set stepping for vertices
	glEnableVertexAttribArray(0); 
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); // Set stepping for texture coordinates
	glEnableVertexAttribArray(1);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
	// End quad buffer object

	// Light buffer object
	GLuint lVBO, lVAO; 
	glGenVertexArrays(1, &lVAO);
	glGenBuffers(1, &lVBO);
	glBindVertexArray(lVAO); 
	glBindBuffer(GL_ARRAY_BUFFER, lVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verticesFloor), verticesFloor, GL_STATIC_DRAW); // Pass in floor geometry
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); // Be careful setting stride and size here (3 values) position
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); // normals
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));  // Textures
	glEnableVertexAttribArray(2);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
	// End light buffer object

	while (!glfwWindowShouldClose(window)) { // The "game loop"

		// Handle user input
		glfwPollEvents(); 
		GLfloat curFrame = glfwGetTime();
		delta = curFrame - lastFrame; // Frame smoothing
		lastFrame = curFrame;
		camera.setSpeed(delta * 10.0f);
		camera.update(activeKeys, pitch, yaw);
		// End user input

		// Light update
		//lightPosition.x = sin(glfwGetTime())*20.0f; // Uncomment to enable rotation of light around scene
		//lightPosition.z = cos(glfwGetTime())*20.0f;
		// End light update

		// View and projection matrix setup
		glm::mat4 view, projection;
		view = glm::lookAt(camera.getPos(), camera.getPos() + camera.getForward(), camera.getUp()); // the sum on the middle argument ensures the camera remains focussed on where we are looking
		projection = glm::perspective(glm::radians(45.0f), GLfloat(WIDTH)/ GLfloat(HEIGHT), 0.1f, 100.0f);
		
		// End view and projection matrix setup

		// Shadow pass
		glm::mat4 shadowProjection = glm::perspective(glm::radians(90.0f), 1.0f, 1.0f, 100.0f);
		std::vector<glm::mat4> shadowViews;
		shadowViews.push_back(shadowProjection * glm::lookAt(lightPosition, lightPosition + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
		shadowViews.push_back(shadowProjection * glm::lookAt(lightPosition, lightPosition + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
		shadowViews.push_back(shadowProjection * glm::lookAt(lightPosition, lightPosition + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
		shadowViews.push_back(shadowProjection * glm::lookAt(lightPosition, lightPosition + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
		shadowViews.push_back(shadowProjection * glm::lookAt(lightPosition, lightPosition + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
		shadowViews.push_back(shadowProjection * glm::lookAt(lightPosition, lightPosition + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
		glViewport(0, 0, SWIDTH, SHEIGHT);
		glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer); // Bind gBuffer to fill with geometry data from the scene
		glClear(GL_DEPTH_BUFFER_BIT);
		shadowShader.Use();
		glUniform3f(glGetUniformLocation(shadowShader.pID, "lightPosition"), lightPosition.x, lightPosition.y, lightPosition.z);
		for (GLuint i = 0; i < 6; ++i) glUniformMatrix4fv(glGetUniformLocation(shadowShader.pID, ("shadowViews[" + std::to_string(i) + "]").c_str()), 1, GL_FALSE, glm::value_ptr(shadowViews[i]));
		glBindVertexArray(lVAO);
		glUniformMatrix4fv(glGetUniformLocation(shadowShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(floorModel)); // Render floor
		glDrawArrays(GL_TRIANGLES, 0, 36);
		glBindVertexArray(0);
		glUniformMatrix4fv(glGetUniformLocation(shadowShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(bunnyModel1)); // Render rabbit 1
		bunny.Draw(shadowShader);
		glUniformMatrix4fv(glGetUniformLocation(shadowShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(bunnyModel2)); // Render rabbit 2
		bunny.Draw(shadowShader);
		glUniformMatrix4fv(glGetUniformLocation(shadowShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(armaModel)); // Render armadillo
		armadillo.Draw(shadowShader);
		glUniformMatrix4fv(glGetUniformLocation(shadowShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(suitModel)); // Render suit
		suit.Draw(shadowShader);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);

		glViewport(0, 0, WIDTH, HEIGHT); // Back to normal viewport
		// End shadow pass




		// Geometry pass	
		glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); // Bind gBuffer to fill with geometry data from the scene
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gShader.Use();
		glActiveTexture(GL_TEXTURE0); // Shadow map for shadow calculation
		glBindTexture(GL_TEXTURE_CUBE_MAP, shadowMap);
		glUniform3f(glGetUniformLocation(gShader.pID, "lightPosition"), lightPosition.x, lightPosition.y, lightPosition.z);
		glUniformMatrix4fv(glGetUniformLocation(gShader.pID, "view"), 1, GL_FALSE, glm::value_ptr(view));
		glUniformMatrix4fv(glGetUniformLocation(gShader.pID, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
		glBindVertexArray(lVAO);
		glUniform3f(glGetUniformLocation(gShader.pID, "colour"), 0.5f, 0.2f, 0.2f);
		glUniform1f(glGetUniformLocation(gShader.pID, "specular"), 0.1f);
		glUniformMatrix4fv(glGetUniformLocation(gShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(floorModel)); // Render floor
		glDrawArrays(GL_TRIANGLES, 0, 36);
		glBindVertexArray(0);
		glUniform3f(glGetUniformLocation(gShader.pID, "colour"), 0.1f, 0.5f, 0.5f);
		glUniform1f(glGetUniformLocation(gShader.pID, "specular"), 0.5f);
		glUniformMatrix4fv(glGetUniformLocation(gShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(bunnyModel1)); // Render rabbit 1
		bunny.Draw(gShader);
		glUniform3f(glGetUniformLocation(gShader.pID, "colour"), 0.1f, 0.5f, 0.5f);
		glUniform1f(glGetUniformLocation(gShader.pID, "specular"), 0.7f);
		glUniformMatrix4fv(glGetUniformLocation(gShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(bunnyModel2)); // Render rabbit 2
		bunny.Draw(gShader);
		glUniform3f(glGetUniformLocation(gShader.pID, "colour"), 0.9f, 0.1f, 0.1f);
		glUniform1f(glGetUniformLocation(gShader.pID, "specular"), 0.3f);
		glUniformMatrix4fv(glGetUniformLocation(gShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(armaModel)); // Render armadillo
		armadillo.Draw(gShader);
		glUniform3f(glGetUniformLocation(gShader.pID, "colour"), 0.1f, 0.9f, 0.1f);
		glUniform1f(glGetUniformLocation(gShader.pID, "specular"), 0.2f);
		glUniformMatrix4fv(glGetUniformLocation(gShader.pID, "model"), 1, GL_FALSE, glm::value_ptr(suitModel)); // Render suit
		suit.Draw(gShader);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		// End geometry pass

		

		// Lighting pass
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		lightShader.Use();
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, gPosition);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, gNormal);
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, gColour);
		glUniform3f(glGetUniformLocation(lightShader.pID, "camPosition"), camera.getPos().x, camera.getPos().y, camera.getPos().z);
		glUniform3f(glGetUniformLocation(lightShader.pID, "lightPosition"), lightPosition.x, lightPosition.y, lightPosition.z);
		glBindVertexArray(qVAO);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
		glBindVertexArray(0);
		// End lighting pass

		glfwSwapBuffers(window); // Push new data to screen (this uses double buffering to avoid flickering)

	}

	// Clean up
	glDeleteVertexArrays(1, &lVAO);
	glDeleteBuffers(1, &lVBO);
	glDeleteVertexArrays(1, &qVAO);
	glDeleteBuffers(1, &qVBO);
	glfwTerminate();
	// End clean up

	return 0;
}