void GLDriver::drawIndex2(const pm4::DrawIndex2 &data) { if (!checkReadyDraw()) { return; } auto vgt_primitive_type = getRegister<latte::VGT_PRIMITIVE_TYPE>(latte::Register::VGT_PRIMITIVE_TYPE); auto sq_vtx_base_vtx_loc = getRegister<latte::SQ_VTX_BASE_VTX_LOC>(latte::Register::SQ_VTX_BASE_VTX_LOC); auto vgt_dma_index_type = getRegister<latte::VGT_DMA_INDEX_TYPE>(latte::Register::VGT_DMA_INDEX_TYPE); auto vgt_dma_num_instances = getRegister<latte::VGT_DMA_NUM_INSTANCES>(latte::Register::VGT_DMA_NUM_INSTANCES); auto vgt_strmout_en = getRegister<latte::VGT_STRMOUT_EN>(latte::Register::VGT_STRMOUT_EN); // Swap and indexBytes are separate because you can have 32-bit swap, // but 16-bit indices in some cases... This is also why we pre-swap // the data before intercepting QUAD and POLYGON draws. if (vgt_dma_index_type.SWAP_MODE() == latte::VGT_DMA_SWAP_16_BIT) { auto *src = static_cast<uint16_t*>(data.addr.get()); auto indices = std::vector<uint16_t>(data.count); if (vgt_dma_index_type.INDEX_TYPE() != latte::VGT_INDEX_16) { decaf_abort(fmt::format("Unexpected INDEX_TYPE {} for VGT_DMA_SWAP_16_BIT", vgt_dma_index_type.INDEX_TYPE())); } for (auto i = 0u; i < data.count; ++i) { indices[i] = byte_swap(src[i]); } drawPrimitives(data.count, indices.data(), vgt_dma_index_type.INDEX_TYPE()); } else if (vgt_dma_index_type.SWAP_MODE() == latte::VGT_DMA_SWAP_32_BIT) { auto *src = static_cast<uint32_t*>(data.addr.get()); auto indices = std::vector<uint32_t>(data.count); if (vgt_dma_index_type.INDEX_TYPE() != latte::VGT_INDEX_32) { decaf_abort(fmt::format("Unexpected INDEX_TYPE {} for VGT_DMA_SWAP_32_BIT", vgt_dma_index_type.INDEX_TYPE())); } for (auto i = 0u; i < data.count; ++i) { indices[i] = byte_swap(src[i]); } drawPrimitives(data.count, indices.data(), vgt_dma_index_type.INDEX_TYPE()); } else if (vgt_dma_index_type.SWAP_MODE() == latte::VGT_DMA_SWAP_NONE) { drawPrimitives(data.count, data.addr, vgt_dma_index_type.INDEX_TYPE()); } else { decaf_abort(fmt::format("Unimplemented vgt_dma_index_type.SWAP_MODE {}", vgt_dma_index_type.SWAP_MODE())); } }
void flagLayer::draw() { ofFill(); ofPushMatrix(); ofTranslate(center.x, center.y, 0); ofRotate(angle); ofPushMatrix(); ofTranslate(-center.x, -center.y, 0); drawPrimitives(); ofPopMatrix(); ofPopMatrix(); }
void GLDriver::drawIndexAuto(const pm4::DrawIndexAuto &data) { if (!checkReadyDraw()) { return; } drawPrimitives(data.count, nullptr, latte::VGT_INDEX_32); }
void SceneNode::createDisplayList() { bool firstTime = false; if(usesDisplayList) { if(hasDisplayList()) { glCallList(this->displayListIndex); } else { firstTime = true; displayListIndex = glGenLists(1); glNewList(displayListIndex, GL_COMPILE); } } glPushMatrix(); glMultMatrixf(getTransformMatrix()); if(hasAppearance) { addAppearanceToStack(this->appearance); } drawPrimitives(); for(unsigned int i = 0; i < descendants.size(); i++) { descendants.at(i)->createDisplayList(); } if(hasAppearance) { removeAppearanceFromStack(); } glPopMatrix(); if(usesDisplayList && firstTime) { glEndList(); } }
void SceneNode::Display() { if(usingDL && this->usesDisplayList && this->hasDisplayList()) { glCallList(this->displayListIndex); } else { glPushMatrix(); glMultMatrixf(getTransformMatrix()); if(hasAppearance) { addAppearanceToStack(this->appearance); } // TP2 if(hasAnimation) { animation->draw(); } drawPrimitives(); for(unsigned int i = 0; i < descendants.size(); i++) { descendants.at(i)->Display(); } if(hasAppearance) { removeAppearanceFromStack(); } glPopMatrix(); } }
//------------------------------------------------------------------------------------------------------------------------------------ // called when we want to draw the 3D data in our app. //------------------------------------------------------------------------------------------------------------------------------------ void draw3D() { // draw the grid on the floor setColour(0.25f, 0.25f, 0.25f); for(float i = -10.0f; i <= 10.1f; i += 1.0f) { Vec3 zmin(i, 0, -10); Vec3 zmax(i, 0, 10); Vec3 xmin(-10, 0, i); Vec3 xmax(10, 0, i); drawLine(xmin, xmax); drawLine(zmin, zmax); } // If using the GPU to compute the lighting (which is what you want to do!) if(!g_manualLighting) { // turn on lighting enableLighting(); // set the diffuse material colour (this will be modulated by the effect of the lighting) setColour(1.0f, 1.0f, 1.0f); // draw the cube geometry drawPrimitives(g_pointsVN, 24, kQuads); // turn off lighting disableLighting(); } else { // otherwise, compute the lighting manually. Don't ever do this in practice! It's insane! (But it may be useful for educational purposes) // The direction from the vertex to the light (effectively sunlight in this case!). Vec3 L(-0.6f, 1.0f, -0.2f); // make sure L has been normalised! L = normalize(L); // start drawing some quads begin(kQuads); // loop through each vertex normal for(int i = 0; i < 24; ++i) { // compute N.L // Make sure we clamp this to zero (so that we ignore any negative values). float N_dot_L = std::max(dot(L, g_pointsVN[i].n), 0.0f); // the ambient material colour (always gets added to the final colour) Vec3 Ka(0.2f, 0.2f, 0.2f); // the diffuse material colour Vec3 Kd(1.0f, 1.0f, 1.0f); // Compute the final colour Vec3 colour = Ka + (Kd * N_dot_L); // set the vertex colour setColour(colour); // specify the vertex addVertex(g_pointsVN[i].v); } // finish drawing our quads end(); } // if we are displaying normals if(g_displayNormals) { // make colour pink setColour(1.0f, 0.0f, 1.0f); // loop through each vertex for(int i = 0; i < 24; ++i) { // compute an offset (along the normal direction) from the vertex Vec3 pn = g_pointsVN[i].v + (g_pointsVN[i].n * 0.2f); // draw a line to show the normal drawLine(g_pointsVN[i].v, pn); } } }
void GrimEngine::updateDisplayScene() { _doFlip = true; if (_mode == ENGINE_MODE_SMUSH) { if (g_smush->isPlaying()) { //_mode = ENGINE_MODE_NORMAL; ??? _movieTime = g_smush->getMovieTime(); if (g_smush->isUpdateNeeded()) { g_driver->prepareSmushFrame(g_smush->getWidth(), g_smush->getHeight(), g_smush->getDstPtr()); g_smush->clearUpdateNeeded(); } int frame = g_smush->getFrame(); if (frame > 0) { if (frame != _prevSmushFrame) { _prevSmushFrame = g_smush->getFrame(); g_driver->drawSmushFrame(g_smush->getX(), g_smush->getY()); if (_showFps) g_driver->drawEmergString(550, 25, _fps, Color(255, 255, 255)); } else _doFlip = false; } else g_driver->releaseSmushFrame(); } drawPrimitives(); } else if (_mode == ENGINE_MODE_NORMAL) { if (!_currScene) return; cameraPostChangeHandle(_currScene->setup()); g_driver->clearScreen(); _prevSmushFrame = 0; _currScene->drawBackground(); // Draw underlying scene components // Background objects are drawn underneath everything except the background // There are a bunch of these, especially in the tube-switcher room _currScene->drawBitmaps(ObjectState::OBJSTATE_BACKGROUND); // Underlay objects are just above the background _currScene->drawBitmaps(ObjectState::OBJSTATE_UNDERLAY); // State objects are drawn on top of other things, such as the flag // on Manny's message tube _currScene->drawBitmaps(ObjectState::OBJSTATE_STATE); // Play SMUSH Animations // This should occur on top of all underlying scene objects, // a good example is the tube switcher room where some state objects // need to render underneath the animation or you can't see what's going on // This should not occur on top of everything though or Manny gets covered // up when he's next to Glottis's service room if (g_smush->isPlaying()) { _movieTime = g_smush->getMovieTime(); if (g_smush->isUpdateNeeded()) { g_driver->prepareSmushFrame(g_smush->getWidth(), g_smush->getHeight(), g_smush->getDstPtr()); g_smush->clearUpdateNeeded(); } if (g_smush->getFrame() > 0) g_driver->drawSmushFrame(g_smush->getX(), g_smush->getY()); else g_driver->releaseSmushFrame(); } _currScene->setupCamera(); g_driver->set3DMode(); _currScene->setupLights(); // Update actor costumes & sets for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) { Actor *a = *i; // Update the actor's costumes & chores g_currentUpdatedActor = *i; // Note that the actor need not be visible to update chores, for example: // when Manny has just brought Meche back he is offscreen several times // when he needs to perform certain chores if (a->inSet(_currScene->name())) a->update(); } g_currentUpdatedActor = NULL; // Draw actors for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) { Actor *a = *i; if (a->inSet(_currScene->name()) && a->visible()) a->draw(); a->undraw(a->inSet(_currScene->name()) && a->visible()); } flagRefreshShadowMask(false); // Draw overlying scene components // The overlay objects should be drawn on top of everything else, // including 3D objects such as Manny and the message tube _currScene->drawBitmaps(ObjectState::OBJSTATE_OVERLAY); g_driver->storeDisplay(); drawPrimitives(); } else if (_mode == ENGINE_MODE_DRAW) { if (_refreshDrawNeeded) { handleUserPaint(); g_driver->flipBuffer(); } _refreshDrawNeeded = false; return; } }