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; }
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)) ); }
/* * 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; }
/* 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; }
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; }
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(); }
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); } }
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; }
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()); } }
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; } }
/// Show Poker card suit and point. void PokerCard::show() { LOG_INFO("Suit: %s, Point: %s", enum2str(suit()), enum2str(point())); }
bool KCardInfo::operator==( const KCardInfo& c ) const { return ( c.card() == card() && c.suit() == suit() ); }
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); }
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; }