GC::GC(const char* _title, int _width, int _height, int _framerate, bool _fullscreen, int _OSAA, int _scale, float _anisotropy){ try{ // State #if defined(_DEBUG) KLGLDebug = true; #else KLGLDebug = false; #endif // Create console buffer clConsole = std::make_shared<Console>(); // MOTD time_t buildTime = (time_t)APP_BUILD_TIME; char* buildTimeString = asctime(gmtime(&buildTime)); memset(buildTimeString+strlen(buildTimeString)-1, 0, 1); // Remove the \n cl("KamiLib v0.1.0 R%d %s, %s %s,\n", APP_BUILD_VERSION, buildTimeString, APP_ARCH_STRING, APP_COMPILER_STRING); cl(APP_MOTD); std::string title = "Application"; vsync = true; overSampleFactor = _OSAA; scaleFactor = _scale; fps = _framerate; fullscreen = _fullscreen; bufferAutoSize = false; // Initialize the window geometry window.x = 0; window.y = 0; window.width = _width; window.height = _height; buffer.width = window.width*overSampleFactor; buffer.height = window.height*overSampleFactor; // Attempt to load runtime configuration config = std::make_unique<Config>("configuration.json"); if (config->ParseError() == 1){ cl("Failed to load configuration file overrides.\n"); }else{ KLGLDebug = config->GetBoolean("system", "debug", KLGLDebug ); window.x = config->GetInteger("system", "lastPosX", 0 ); window.y = config->GetInteger("system", "lastPosY", 0 ); window.width = config->GetInteger("system", "windowWidth", _width ); window.height = config->GetInteger("system", "windowHeight", _height ); overSampleFactor= config->GetInteger("system", "bufferScale", _OSAA ); bufferAutoSize = config->GetBoolean("system", "bufferAutoSize", false ); buffer.width = config->GetInteger("system", "bufferWidth", window.width*overSampleFactor ); buffer.height = config->GetInteger("system", "bufferHeight", window.height*overSampleFactor ); vsync = config->GetBoolean("system", "vsync", vsync ); scaleFactor = config->GetInteger("system", "windowScale", _scale ); fullscreen = config->GetBoolean("system", "fullscreen", _fullscreen ); title = config->GetString("system", "title", _title ); } // Init window windowManager = std::make_unique<WindowManager>(title.c_str(), &window, scaleFactor, fullscreen, vsync); // Load OpenGL #if defined APP_USE_GLEW glewInit(); #else gl::exts::LoadTest didLoad = gl::sys::LoadFunctions(); if (!didLoad){ cl("Catastrophic Error: Minimum OpenGL version 3 not supported, please upgrade your graphics hardware.\n"); cl("Number of functions that failed to load: %i.\n", didLoad.GetNumMissing()); exit(EXIT_FAILURE); } #endif // Setup frame buffer fbo.emplace_back(buffer.width, buffer.height); // Create basic pass-through shaders std::string vert2d = GLSL( in vec2 position; in vec2 texcoord; out vec2 coord; uniform mat4 MVP; void main() { coord = texcoord; gl_Position = MVP*vec4(position, 0.0, 1.0); } ); std::string frag2d = GLSL( uniform sampler2D image; in vec2 coord; out vec4 outColor; void main() { outColor = texture(image, coord); }
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter) { if (chunkSize * mNumSplits > 1.f) { // keep splitting osg::ref_ptr<osg::Group> group (new osg::Group); if (parent) parent->addChild(group); float newChunkSize = chunkSize/2.f; buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f)); return group; } else { float minH, maxH; if (!mStorage->getMinMaxHeights(chunkSize, chunkCenter, minH, maxH)) return NULL; // no terrain defined osg::Vec2f worldCenter = chunkCenter*mStorage->getCellWorldSize(); osg::ref_ptr<SceneUtil::PositionAttitudeTransform> transform (new SceneUtil::PositionAttitudeTransform); transform->setPosition(osg::Vec3f(worldCenter.x(), worldCenter.y(), 0.f)); if (parent) parent->addChild(transform); osg::ref_ptr<osg::Vec3Array> positions (new osg::Vec3Array); osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array); osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array); osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject); positions->setVertexBufferObject(vbo); normals->setVertexBufferObject(vbo); colors->setVertexBufferObject(vbo); mStorage->fillVertexBuffers(0, chunkSize, chunkCenter, positions, normals, colors); osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry); geometry->setVertexArray(positions); geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX); geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX); geometry->setUseDisplayList(false); geometry->setUseVertexBufferObjects(true); geometry->addPrimitiveSet(mCache.getIndexBuffer(0)); // we already know the bounding box, so no need to let OSG compute it. osg::Vec3f min(-0.5f*mStorage->getCellWorldSize()*chunkSize, -0.5f*mStorage->getCellWorldSize()*chunkSize, minH); osg::Vec3f max (0.5f*mStorage->getCellWorldSize()*chunkSize, 0.5f*mStorage->getCellWorldSize()*chunkSize, maxH); osg::BoundingBox bounds(min, max); geometry->setComputeBoundingBoxCallback(new StaticBoundingBoxCallback(bounds)); std::vector<LayerInfo> layerList; std::vector<osg::ref_ptr<osg::Image> > blendmaps; mStorage->getBlendmaps(chunkSize, chunkCenter, false, blendmaps, layerList); // For compiling textures, I don't think the osgFX::Effect does it correctly osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node); unsigned int dummyTextureCounter = 0; std::vector<osg::ref_ptr<osg::Texture2D> > layerTextures; { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex); for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it) { osg::ref_ptr<osg::Texture2D> texture = mTextureCache[it->mDiffuseMap]; if (!texture) { texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mDiffuseMap)); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); mResourceSystem->getSceneManager()->applyFilterSettings(texture); mTextureCache[it->mDiffuseMap] = texture; } layerTextures.push_back(texture); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, layerTextures.back()); } } std::vector<osg::ref_ptr<osg::Texture2D> > blendmapTextures; for (std::vector<osg::ref_ptr<osg::Image> >::const_iterator it = blendmaps.begin(); it != blendmaps.end(); ++it) { osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D); texture->setImage(*it); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); texture->setResizeNonPowerOfTwoHint(false); texture->getOrCreateUserDataContainer()->addDescription("dont_override_filter"); blendmapTextures.push_back(texture); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, blendmapTextures.back()); } // use texture coordinates for both texture units, the layer texture and blend texture for (unsigned int i=0; i<2; ++i) geometry->setTexCoordArray(i, mCache.getUVBuffer()); float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize; osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(layerTextures, blendmapTextures, blendmapScale, blendmapScale)); effect->addCullCallback(new SceneUtil::LightListCallback); transform->addChild(effect); osg::Node* toAttach = geometry.get(); effect->addChild(toAttach); if (mIncrementalCompileOperation) { mIncrementalCompileOperation->add(toAttach); mIncrementalCompileOperation->add(textureCompileDummy); } return transform; } }
void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, BitmapTexture* mask) { textureMapper->drawTexture(*texture().get(), rect(), transform, opacity, mask); }
void TexturedQuad::Draw(Renderer *renderer, uint32_t *index) { if (visible())renderer->DrawTexture(index, texture()); (*index)++; }
void main(void){\n\ color = texture(tex, fuv);\n\ }\n";
void BSplineSurfaceFitterWindow::CreateScene() { // Begin with a flat 64x64 height field. int const numSamples = 64; float const extent = 8.0f; VertexFormat hfformat; hfformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0); hfformat.Bind(VA_TEXCOORD, DF_R32G32_FLOAT, 0); MeshFactory mf; mf.SetVertexFormat(hfformat); mHeightField = mf.CreateRectangle(numSamples, numSamples, extent, extent); int numVertices = numSamples * numSamples; VertexPT* hfvertices = mHeightField->GetVertexBuffer()->Get<VertexPT>(); // Set the heights based on a precomputed height field. Also create a // texture image to go with the height field. std::string path = mEnvironment.GetPath("BTHeightField.png"); std::shared_ptr<Texture2> texture(WICFileIO::Load(path, false)); std::shared_ptr<Texture2Effect> txeffect = std::make_shared<Texture2Effect>(mProgramFactory, texture, SamplerState::MIN_L_MAG_L_MIP_P, SamplerState::CLAMP, SamplerState::CLAMP); mHeightField->SetEffect(txeffect); std::mt19937 mte; std::uniform_real_distribution<float> symmr(-0.05f, 0.05f); std::uniform_real_distribution<float> intvr(32.0f, 64.0f); unsigned char* data = (unsigned char*)texture->Get<unsigned char>(); std::vector<Vector3<float>> samplePoints(numVertices); for (int i = 0; i < numVertices; ++i) { unsigned char value = *data; float height = 3.0f*((float)value) / 255.0f + symmr(mte); *data++ = (unsigned char)intvr(mte); *data++ = 3 * (128 - value / 2) / 4; *data++ = 0; data++; hfvertices[i].position[2] = height; samplePoints[i] = hfvertices[i].position; } // Compute a B-Spline surface with NxN control points, where N < 64. // This surface will be sampled to 64x64 and displayed together with the // original height field for comparison. int const numControls = 32; int const degree = 3; BSplineSurfaceFit<float> fitter(degree, numControls, numSamples, degree, numControls, numSamples, &samplePoints[0]); VertexFormat ffformat; ffformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0); ffformat.Bind(VA_COLOR, DF_R32G32B32A32_FLOAT, 0); mf.SetVertexFormat(ffformat); mFittedField = mf.CreateRectangle(numSamples, numSamples, extent, extent); VertexPC* ffvertices = mFittedField->GetVertexBuffer()->Get<VertexPC>(); Vector4<float> translucent{ 1.0f, 1.0f, 1.0f, 0.5f }; for (int i = 0; i < numVertices; ++i) { float u = 0.5f*(ffvertices[i].position[0] / extent + 1.0f); float v = 0.5f*(ffvertices[i].position[1] / extent + 1.0f); ffvertices[i].position = fitter.GetPosition(u, v); ffvertices[i].color = translucent; } std::shared_ptr<VertexColorEffect> vceffect = std::make_shared<VertexColorEffect>(mProgramFactory); mFittedField->SetEffect(vceffect); mCameraRig.Subscribe(mHeightField->worldTransform, txeffect->GetPVWMatrixConstant()); mCameraRig.Subscribe(mFittedField->worldTransform, vceffect->GetPVWMatrixConstant()); mTrackball.Attach(mHeightField); mTrackball.Attach(mFittedField); mTrackball.Update(); }
void TestResult::testOne() { sk_sp<SkPicture> pic; { SkString d; d.printf(" {%d, \"%s\"},", fDirNo, fFilename); SkString path = make_filepath(fDirNo, IN_DIR, fFilename); SkFILEStream stream(path.c_str()); if (!stream.isValid()) { SkDebugf("invalid stream %s\n", path.c_str()); goto finish; } if (fTestStep == kEncodeFiles) { size_t length = stream.getLength(); SkTArray<char, true> bytes; bytes.push_back_n(length); stream.read(&bytes[0], length); stream.rewind(); SkString wPath = make_filepath(0, outSkpDir, fFilename); SkFILEWStream wStream(wPath.c_str()); wStream.write(&bytes[0], length); wStream.flush(); } pic = SkPicture::MakeFromStream(&stream); if (!pic) { SkDebugf("unable to decode %s\n", fFilename); goto finish; } int pWidth = pic->width(); int pHeight = pic->height(); int pLargerWH = SkTMax(pWidth, pHeight); GrContextFactory contextFactory; #ifdef SK_BUILD_FOR_WIN GrContext* context = contextFactory.get(kAngle); #else GrContext* context = contextFactory.get(kNative); #endif if (nullptr == context) { SkDebugf("unable to allocate context for %s\n", fFilename); goto finish; } int maxWH = context->getMaxRenderTargetSize(); int scale = 1; while (pLargerWH / scale > maxWH) { scale *= 2; } SkBitmap bitmap; SkIPoint dim; do { dim.fX = (pWidth + scale - 1) / scale; dim.fY = (pHeight + scale - 1) / scale; bool success = bitmap.allocN32Pixels(dim.fX, dim.fY); if (success) { break; } SkDebugf("-%d-", scale); } while ((scale *= 2) < 256); if (scale >= 256) { SkDebugf("unable to allocate bitmap for %s (w=%d h=%d) (sw=%d sh=%d)\n", fFilename, pWidth, pHeight, dim.fX, dim.fY); return; } SkCanvas skCanvas(bitmap); drawPict(pic, &skCanvas, fScaleOversized ? scale : 1); GrTextureDesc desc; desc.fConfig = kRGBA_8888_GrPixelConfig; desc.fFlags = kRenderTarget_GrTextureFlagBit; desc.fWidth = dim.fX; desc.fHeight = dim.fY; desc.fSampleCnt = 0; sk_sp<GrTexture> texture(context->createUncachedTexture(desc, nullptr, 0)); if (!texture) { SkDebugf("unable to allocate texture for %s (w=%d h=%d)\n", fFilename, dim.fX, dim.fY); return; } SkGpuDevice grDevice(context, texture.get()); SkCanvas grCanvas(&grDevice); drawPict(pic.get(), &grCanvas, fScaleOversized ? scale : 1); SkBitmap grBitmap; grBitmap.allocPixels(grCanvas.imageInfo()); grCanvas.readPixels(&grBitmap, 0, 0); if (fTestStep == kCompareBits) { fPixelError = similarBits(grBitmap, bitmap); SkMSec skTime = timePict(pic, &skCanvas); SkMSec grTime = timePict(pic, &grCanvas); fTime = skTime - grTime; } else if (fTestStep == kEncodeFiles) { SkString pngStr = make_png_name(fFilename); const char* pngName = pngStr.c_str(); writePict(grBitmap, outGrDir, pngName); writePict(bitmap, outSkDir, pngName); } } }
void PickingWindow::CreateScene() { std::string path = mEnvironment.GetPath("Checkerboard.png"); std::shared_ptr<Texture2> texture(WICFileIO::Load(path, false)); mScene = std::make_shared<Node>(); VertexFormat vformat0; vformat0.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0); vformat0.Bind(VA_TEXCOORD, DF_R32G32_FLOAT, 0); // The torus and dodecahedron are created by the mesh factory in which // the 'visual' model bounds are computed. The points and segments // primitives are created explicitly here, so we need to compute their // model bounds to be used by the picking system. MeshFactory mf; mf.SetVertexFormat(vformat0); mTorus = mf.CreateTorus(16, 16, 4.0f, 1.0f); std::shared_ptr<Texture2Effect> effect = std::make_shared<Texture2Effect>( mProgramFactory, texture, SamplerState::MIN_L_MAG_L_MIP_P, SamplerState::CLAMP, SamplerState::CLAMP); mTorus->SetEffect(effect); mCameraRig.Subscribe(mTorus->worldTransform, effect->GetPVWMatrixConstant()); mScene->AttachChild(mTorus); mDodecahedron = mf.CreateDodecahedron(); effect = std::make_shared<Texture2Effect>(mProgramFactory, texture, SamplerState::MIN_L_MAG_L_MIP_P, SamplerState::CLAMP, SamplerState::CLAMP); mDodecahedron->SetEffect(effect); mCameraRig.Subscribe(mDodecahedron->worldTransform, effect->GetPVWMatrixConstant()); mScene->AttachChild(mDodecahedron); VertexFormat vformat1; vformat1.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0); std::shared_ptr<VertexBuffer> vbuffer(new VertexBuffer(vformat1, 4)); Vector3<float>* vertices = vbuffer->Get<Vector3<float>>(); vertices[0] = { 1.0f, 1.0f, 4.0f }; vertices[1] = { 1.0f, 2.0f, 5.0f }; vertices[2] = { 2.0f, 2.0f, 6.0f }; vertices[3] = { 2.0f, 1.0f, 7.0f }; std::shared_ptr<IndexBuffer> ibuffer(new IndexBuffer(IP_POLYPOINT, 4)); std::shared_ptr<ConstantColorEffect> cceffect = std::make_shared<ConstantColorEffect>(mProgramFactory, Vector4<float>({ 0.5f, 0.0f, 0.0f, 1.0f })); mPoints = std::make_shared<Visual>(vbuffer, ibuffer, cceffect); mPoints->UpdateModelBound(); mCameraRig.Subscribe(mPoints->worldTransform, cceffect->GetPVWMatrixConstant()); mScene->AttachChild(mPoints); vbuffer = std::make_shared<VertexBuffer>(vformat1, 4); vertices = vbuffer->Get<Vector3<float>>(); vertices[0] = { -1.0f, -1.0f, 4.0f }; vertices[1] = { -1.0f, -2.0f, 5.0f }; vertices[2] = { -2.0f, -1.0f, 6.0f }; vertices[3] = { -2.0f, -2.0f, 7.0f }; ibuffer = std::make_shared<IndexBuffer>(IP_POLYSEGMENT_CONTIGUOUS, 3, sizeof(int)); ibuffer->SetSegment(0, 0, 1); ibuffer->SetSegment(1, 1, 2); ibuffer->SetSegment(2, 2, 3); cceffect = std::make_shared<ConstantColorEffect>(mProgramFactory, Vector4<float>({ 0.0f, 0.0f, 0.5f, 1.0f })); mSegments = std::make_shared<Visual>(vbuffer, ibuffer, cceffect); mSegments->UpdateModelBound(); mCameraRig.Subscribe(mSegments->worldTransform, cceffect->GetPVWMatrixConstant()); mScene->AttachChild(mSegments); for (int i = 0; i < SPHERE_BUDGET; ++i) { mSphere[i] = mf.CreateSphere(8, 8, 0.125f); cceffect = std::make_shared<ConstantColorEffect>(mProgramFactory, Vector4<float>({ 0.0f, 0.0f, 0.0f, 1.0f })); mSphere[i]->SetEffect(cceffect); mCameraRig.Subscribe(mSphere[i]->worldTransform, cceffect->GetPVWMatrixConstant()); mScene->AttachChild(mSphere[i]); } mTrackball.Attach(mScene); mTrackball.Update(); }
// ----------------------------------------------------------------------------- // Removes any patches and associated entries from [archive] that are not used // in any texture definitions // ----------------------------------------------------------------------------- bool ArchiveOperations::removeUnusedPatches(Archive* archive) { if (!archive) return false; // Find PNAMES entry Archive::SearchOptions opt; opt.match_type = EntryType::fromId("pnames"); auto pnames = archive->findLast(opt); // Find TEXTUREx entries opt.match_type = EntryType::fromId("texturex"); auto tx_entries = archive->findAll(opt); // Can't do anything without PNAMES/TEXTUREx if (!pnames || tx_entries.empty()) return false; // Open patch table PatchTable ptable; ptable.loadPNAMES(pnames, archive); // Open texturex entries to update patch usage vector<TextureXList*> tx_lists; for (auto& entry : tx_entries) { auto texturex = new TextureXList(); texturex->readTEXTUREXData(entry, ptable); for (unsigned t = 0; t < texturex->size(); t++) ptable.updatePatchUsage(texturex->texture(t)); tx_lists.push_back(texturex); } // Go through patch table unsigned removed = 0; vector<ArchiveEntry*> to_remove; for (unsigned a = 0; a < ptable.nPatches(); a++) { auto& p = ptable.patch(a); // Check if used in any texture if (p.used_in.empty()) { // Unused // If its entry is in the archive, flag it to be removed auto entry = App::resources().getPatchEntry(p.name, "patches", archive); if (entry && entry->parent() == archive) to_remove.push_back(entry); // Update texturex list patch indices for (auto& tx_list : tx_lists) tx_list->removePatch(p.name); // Remove the patch from the patch table Log::info(wxString::Format("Removed patch %s", p.name)); removed++; ptable.removePatch(a--); } } // Remove unused patch entries for (auto& a : to_remove) { Log::info(wxString::Format("Removed entry %s", a->name())); archive->removeEntry(a); } // Write PNAMES changes ptable.writePNAMES(pnames); // Write TEXTUREx changes for (unsigned a = 0; a < tx_lists.size(); a++) tx_lists[a]->writeTEXTUREXData(tx_entries[a], ptable); // Cleanup for (auto& tx_list : tx_lists) delete tx_list; // Notify user wxMessageBox( wxString::Format("Removed %d patches and %lu entries. See console log for details.", removed, to_remove.size()), "Removed Unused Patches", wxOK | wxICON_INFORMATION); return true; }
RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_original_path, Error *r_error) { if (r_error) *r_error=ERR_CANT_OPEN; if (p_path.extension()=="cube") { // open as cubemap txture CubeMap* ptr = memnew(CubeMap); Ref<CubeMap> cubemap( ptr ); Error err; FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); if (err) { ERR_FAIL_COND_V( err, RES() ); } String base_path=p_path.substr( 0, p_path.find_last("/")+1 ); for(int i=0;i<6;i++) { String file = f->get_line().strip_edges(); Image image; Error err = ImageLoader::load_image(base_path+file,&image); if (err) { memdelete(f); ERR_FAIL_COND_V( err, RES() ); } if (i==0) { //cubemap->create(image.get_width(),image.get_height(),image.get_format(),Texture::FLAGS_DEFAULT|Texture::FLAG_CUBEMAP); } static const CubeMap::Side cube_side[6]= { CubeMap::SIDE_LEFT, CubeMap::SIDE_RIGHT, CubeMap::SIDE_BOTTOM, CubeMap::SIDE_TOP, CubeMap::SIDE_FRONT, CubeMap::SIDE_BACK }; cubemap->set_side(cube_side[i],image); } memdelete(f); cubemap->set_name(p_path.get_file()); if (r_error) *r_error=OK; return cubemap; } else { // simple image ImageTexture* ptr = memnew(ImageTexture); Ref<ImageTexture> texture( ptr ); uint64_t begtime; double total; Image image; if (debug_load_times) begtime=OS::get_singleton()->get_ticks_usec(); Error err = ImageLoader::load_image(p_path,&image); if (!err && debug_load_times) { double total=(double)(OS::get_singleton()->get_ticks_usec()-begtime)/1000000.0; print_line("IMAGE: "+itos(image.get_width())+"x"+itos(image.get_height())); print_line(" -load: "+rtos(total)); } ERR_EXPLAIN("Failed loading image: "+p_path); ERR_FAIL_COND_V(err, RES()); if (r_error) *r_error=ERR_FILE_CORRUPT; #ifdef DEBUG_ENABLED #ifdef TOOLS_ENABLED if (max_texture_size && (image.get_width() > max_texture_size || image.get_height() > max_texture_size)) { if (bool(Globals::get_singleton()->get("debug/max_texture_size_alert"))) { OS::get_singleton()->alert("Texture is too large: '"+p_path+"', at "+itos(image.get_width())+"x"+itos(image.get_height())+". Max allowed size is: "+itos(max_texture_size)+"x"+itos(max_texture_size)+".","BAD ARTIST, NO COOKIE!"); } ERR_EXPLAIN("Texture is too large: '"+p_path+"', at "+itos(image.get_width())+"x"+itos(image.get_height())+". Max allowed size is: "+itos(max_texture_size)+"x"+itos(max_texture_size)+"."); ERR_FAIL_V(RES()); } #endif #endif uint32_t flags=0; FileAccess *f2 = FileAccess::open(p_path+".flags",FileAccess::READ); Map<String,bool> flags_found; if (f2) { while(!f2->eof_reached()) { String l2 = f2->get_line(); int eqpos = l2.find("="); if (eqpos!=-1) { String flag=l2.substr(0,eqpos).strip_edges(); String val=l2.substr(eqpos+1,l2.length()).strip_edges().to_lower(); flags_found[flag]=(val=="true" || val=="1")?true:false; } } memdelete(f2); } if (flags_found.has("filter")) { if (flags_found["filter"]) flags|=Texture::FLAG_FILTER; } else if (bool(GLOBAL_DEF("image_loader/filter",true))) { flags|=Texture::FLAG_FILTER; } if (flags_found.has("gen_mipmaps")) { if (flags_found["gen_mipmaps"]) flags|=Texture::FLAG_MIPMAPS; } else if (bool(GLOBAL_DEF("image_loader/gen_mipmaps",true))) { flags|=Texture::FLAG_MIPMAPS; } if (flags_found.has("repeat")) { if (flags_found["repeat"]) flags|=Texture::FLAG_REPEAT; } else if (bool(GLOBAL_DEF("image_loader/repeat",true))) { flags|=Texture::FLAG_REPEAT; } if (flags_found.has("anisotropic")) { if (flags_found["anisotropic"]) flags|=Texture::FLAG_ANISOTROPIC_FILTER; } if (flags_found.has("tolinear")) { if (flags_found["tolinear"]) flags|=Texture::FLAG_CONVERT_TO_LINEAR; } if (flags_found.has("mirroredrepeat")) { if (flags_found["mirroredrepeat"]) flags|=Texture::FLAG_MIRRORED_REPEAT; } if (debug_load_times) begtime=OS::get_singleton()->get_ticks_usec(); //print_line("img: "+p_path+" flags: "+itos(flags)); texture->create_from_image( image,flags ); texture->set_name(p_path.get_file()); if (debug_load_times) { total=(double)(OS::get_singleton()->get_ticks_usec()-begtime)/1000000.0; print_line(" -make texture: "+rtos(total)); } if (r_error) *r_error=OK; return RES( texture ); } }
sk_sp<GrTexture> GrClipMaskManager::CreateAlphaClipMask(GrContext* context, int32_t elementsGenID, GrReducedClip::InitialState initialState, const GrReducedClip::ElementList& elements, const SkVector& clipToMaskOffset, const SkIRect& clipSpaceIBounds) { GrResourceProvider* resourceProvider = context->resourceProvider(); GrUniqueKey key; GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) { return sk_sp<GrTexture>(texture); } // There's no texture in the cache. Let's try to allocate it then. GrPixelConfig config = kRGBA_8888_GrPixelConfig; if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { config = kAlpha_8_GrPixelConfig; } sk_sp<GrDrawContext> dc(context->newDrawContext(SkBackingFit::kApprox, clipSpaceIBounds.width(), clipSpaceIBounds.height(), config)); if (!dc) { return nullptr; } // The texture may be larger than necessary, this rect represents the part of the texture // we populate with a rasterization of the clip. SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpaceIBounds.height()); // The scratch texture that we are drawing into can be substantially larger than the mask. Only // clear the part that we care about. dc->clear(&maskSpaceIBounds, GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, true); // Set the matrix so that rendered clip elements are transformed to mask space from clip // space. const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY); // It is important that we use maskSpaceIBounds as the stencil rect in the below loop. // The second pass that zeros the stencil buffer renders the rect maskSpaceIBounds so the first // pass must not set values outside of this bounds or stencil values outside the rect won't be // cleared. // walk through each clip element and perform its set op for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) { const Element* element = iter.get(); SkRegion::Op op = element->getOp(); bool invert = element->isInverseFilled(); if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { GrFixedClip clip(maskSpaceIBounds); // draw directly into the result with the stencil set to make the pixels affected // by the clip shape be non-zero. static constexpr GrUserStencilSettings kStencilInElement( GrUserStencilSettings::StaticInit< 0xffff, GrUserStencilTest::kAlways, 0xffff, GrUserStencilOp::kReplace, GrUserStencilOp::kReplace, 0xffff>() ); if (!stencil_element(dc.get(), clip, &kStencilInElement, translate, element)) { return nullptr; } // Draw to the exterior pixels (those with a zero stencil value). static constexpr GrUserStencilSettings kDrawOutsideElement( GrUserStencilSettings::StaticInit< 0x0000, GrUserStencilTest::kEqual, 0xffff, GrUserStencilOp::kZero, GrUserStencilOp::kZero, 0xffff>() ); if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideElement, op, !invert, false, translate, SkRect::Make(clipSpaceIBounds))) { return nullptr; } } else { // all the remaining ops can just be directly draw into the accumulation buffer GrPaint paint; paint.setAntiAlias(element->isAA()); paint.setCoverageSetOpXPFactory(op, false); draw_element(dc.get(), GrNoClip(), paint, translate, element); } } sk_sp<GrTexture> texture(dc->asTexture()); SkASSERT(texture); texture->resourcePriv().setUniqueKey(key); return texture; }
void TextureHolder::load(Textures::ID id, const std::string &filename){ std::unique_ptr<sf::Texture> texture(new sf::Texture()); texture->loadFromFile(filename); mTextureMap.insert(std::make_pair(id, std::move(texture))); }
void FrameBufferSkPictureCanvasLayerTextureUpdater::Texture::updateRect(CCGraphicsContext* context, TextureAllocator* allocator, const IntRect& sourceRect, const IntRect& destRect) { textureUpdater()->updateTextureRect(context, allocator, texture(), sourceRect, destRect); }
bool SkBitmapProcShader::asFragmentProcessor(GrContext* context, const SkPaint& paint, const SkMatrix& viewM, const SkMatrix* localMatrix, GrColor* paintColor, GrProcessorDataManager* procDataManager, GrFragmentProcessor** fp) const { SkMatrix matrix; matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); SkMatrix lmInverse; if (!this->getLocalMatrix().invert(&lmInverse)) { return false; } if (localMatrix) { SkMatrix inv; if (!localMatrix->invert(&inv)) { return false; } lmInverse.postConcat(inv); } matrix.preConcat(lmInverse); SkShader::TileMode tm[] = { (TileMode)fTileModeX, (TileMode)fTileModeY, }; // Must set wrap and filter on the sampler before requesting a texture. In two places below // we check the matrix scale factors to determine how to interpret the filter quality setting. // This completely ignores the complexity of the drawVertices case where explicit local coords // are provided by the caller. bool useBicubic = false; GrTextureParams::FilterMode textureFilterMode; switch(paint.getFilterQuality()) { case kNone_SkFilterQuality: textureFilterMode = GrTextureParams::kNone_FilterMode; break; case kLow_SkFilterQuality: textureFilterMode = GrTextureParams::kBilerp_FilterMode; break; case kMedium_SkFilterQuality: { SkMatrix matrix; matrix.setConcat(viewM, this->getLocalMatrix()); if (matrix.getMinScale() < SK_Scalar1) { textureFilterMode = GrTextureParams::kMipMap_FilterMode; } else { // Don't trigger MIP level generation unnecessarily. textureFilterMode = GrTextureParams::kBilerp_FilterMode; } break; } case kHigh_SkFilterQuality: { SkMatrix matrix; matrix.setConcat(viewM, this->getLocalMatrix()); useBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode); break; } default: SkErrorInternals::SetError( kInvalidPaint_SkError, "Sorry, I don't understand the filtering " "mode you asked for. Falling back to " "MIPMaps."); textureFilterMode = GrTextureParams::kMipMap_FilterMode; break; } GrTextureParams params(tm, textureFilterMode); SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, fRawBitmap, ¶ms)); if (!texture) { SkErrorInternals::SetError( kInternalError_SkError, "Couldn't convert bitmap to texture."); return false; } *paintColor = (kAlpha_8_SkColorType == fRawBitmap.colorType()) ? SkColor2GrColor(paint.getColor()) : SkColor2GrColorJustAlpha(paint.getColor()); if (useBicubic) { *fp = GrBicubicEffect::Create(procDataManager, texture, matrix, tm); } else { *fp = GrSimpleTextureEffect::Create(procDataManager, texture, matrix, params); } return true; }
void BitmapCanvasLayerTextureUpdater::Texture::updateRect(CCResourceProvider* resourceProvider, const IntRect& sourceRect, const IntRect& destRect) { textureUpdater()->updateTextureRect(resourceProvider, texture(), sourceRect, destRect); }
// Test out the SkSpecialImage::makeTextureImage entry point DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_MakeTexture, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); SkBitmap bm = create_bm(); const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); { // raster sk_sp<SkSpecialImage> rasterImage(SkSpecialImage::MakeFromRaster( SkIRect::MakeWH(kFullSize, kFullSize), bm)); { sk_sp<SkSpecialImage> fromRaster(rasterImage->makeTextureImage(context)); test_texture_backed(reporter, rasterImage, fromRaster); } { sk_sp<SkSpecialImage> subRasterImage(rasterImage->makeSubset(subset)); sk_sp<SkSpecialImage> fromSubRaster(subRasterImage->makeTextureImage(context)); test_texture_backed(reporter, subRasterImage, fromSubRaster); } } { // gpu GrSurfaceDesc desc; desc.fConfig = kSkia8888_GrPixelConfig; desc.fFlags = kNone_GrSurfaceFlags; desc.fWidth = kFullSize; desc.fHeight = kFullSize; sk_sp<GrTexture> texture(context->textureProvider()->createTexture(desc, SkBudgeted::kNo, bm.getPixels(), 0)); if (!texture) { return; } sk_sp<SkSpecialImage> gpuImage(SkSpecialImage::MakeFromGpu( SkIRect::MakeWH(kFullSize, kFullSize), kNeedNewImageUniqueID_SpecialImage, std::move(texture))); { sk_sp<SkSpecialImage> fromGPU(gpuImage->makeTextureImage(context)); test_texture_backed(reporter, gpuImage, fromGPU); } { sk_sp<SkSpecialImage> subGPUImage(gpuImage->makeSubset(subset)); sk_sp<SkSpecialImage> fromSubGPU(subGPUImage->makeTextureImage(context)); test_texture_backed(reporter, subGPUImage, fromSubGPU); } } }
void FakeLayerTextureUpdater::Texture::updateRect(CCGraphicsContext*, TextureAllocator* allocator, const IntRect&, const IntRect&) { if (allocator) texture()->acquireBackingTexture(allocator); m_layer->updateRect(); }
// Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw) static void test_image(const sk_sp<SkSpecialImage>& img, skiatest::Reporter* reporter, GrContext* context, bool peekTextureSucceeds, int offset, int size) { const SkIRect subset = img->subset(); REPORTER_ASSERT(reporter, offset == subset.left()); REPORTER_ASSERT(reporter, offset == subset.top()); REPORTER_ASSERT(reporter, kSmallerSize == subset.width()); REPORTER_ASSERT(reporter, kSmallerSize == subset.height()); //-------------- // Test that peekTexture reports the correct backing type REPORTER_ASSERT(reporter, peekTextureSucceeds == img->isTextureBacked()); #if SK_SUPPORT_GPU //-------------- // Test getTextureAsRef - as long as there is a context this should succeed if (context) { sk_sp<GrTexture> texture(img->asTextureRef(context)); REPORTER_ASSERT(reporter, texture); } #endif //-------------- // Test getROPixels - this should always succeed regardless of backing store SkBitmap bitmap; REPORTER_ASSERT(reporter, img->getROPixels(&bitmap)); if (context) { REPORTER_ASSERT(reporter, kSmallerSize == bitmap.width()); REPORTER_ASSERT(reporter, kSmallerSize == bitmap.height()); } else { REPORTER_ASSERT(reporter, size == bitmap.width()); REPORTER_ASSERT(reporter, size == bitmap.height()); } //-------------- // Test that draw restricts itself to the subset SkImageInfo info = SkImageInfo::MakeN32(kFullSize, kFullSize, kOpaque_SkAlphaType); sk_sp<SkSpecialSurface> surf(img->makeSurface(info)); SkCanvas* canvas = surf->getCanvas(); canvas->clear(SK_ColorBLUE); img->draw(canvas, SkIntToScalar(kPad), SkIntToScalar(kPad), nullptr); SkBitmap bm; bm.allocN32Pixels(kFullSize, kFullSize, true); bool result = canvas->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), 0, 0); SkASSERT_RELEASE(result); // Only the center (red) portion should've been drawn into the canvas REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kPad-1, kPad-1)); REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kPad, kPad)); REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kSmallerSize+kPad-1, kSmallerSize+kPad-1)); REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kSmallerSize+kPad, kSmallerSize+kPad)); //-------------- // Test that makeTightSubset & makeTightSurface return appropriately sized objects // of the correct backing type SkIRect newSubset = SkIRect::MakeWH(subset.width(), subset.height()); { sk_sp<SkImage> tightImg(img->makeTightSubset(newSubset)); REPORTER_ASSERT(reporter, tightImg->width() == subset.width()); REPORTER_ASSERT(reporter, tightImg->height() == subset.height()); REPORTER_ASSERT(reporter, peekTextureSucceeds == !!tightImg->getTexture()); SkPixmap tmpPixmap; REPORTER_ASSERT(reporter, peekTextureSucceeds != !!tightImg->peekPixels(&tmpPixmap)); } { SkImageInfo info = SkImageInfo::MakeN32(subset.width(), subset.height(), kPremul_SkAlphaType); sk_sp<SkSurface> tightSurf(img->makeTightSurface(info)); REPORTER_ASSERT(reporter, tightSurf->width() == subset.width()); REPORTER_ASSERT(reporter, tightSurf->height() == subset.height()); REPORTER_ASSERT(reporter, peekTextureSucceeds == !!tightSurf->getTextureHandle(SkSurface::kDiscardWrite_BackendHandleAccess)); SkPixmap tmpPixmap; REPORTER_ASSERT(reporter, peekTextureSucceeds != !!tightSurf->peekPixels(&tmpPixmap)); } }
bool bakeTextureMap(const Surface &src, const Surface &target) { OCL ocl; if (!initOpenCL(ocl, 2)) { BAKE_LOG("Failed to initialize OpenCL."); return false; } SurfaceVolume sv; if (!buildSurfaceVolume(src, Eigen::Vector3i::Constant(64), sv)) { BAKE_LOG("Failed to create surface volume."); return false; } // Target cl_int err; cl::Buffer bTargetVertexPositions(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, target.vertexPositions.array().size() * sizeof(float), const_cast<float*>(target.vertexPositions.data()), &err); ASSERT_OPENCL(err, "Failed to create vertex buffer for target."); cl::Buffer bTargetVertexUVs(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, target.vertexUVs.array().size() * sizeof(float), const_cast<float*>(target.vertexUVs.data()), &err); ASSERT_OPENCL(err, "Failed to create UV buffer for target."); cl::Buffer bTargetVertexNormals(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, target.vertexNormals.array().size() * sizeof(float), const_cast<float*>(target.vertexNormals.data()), &err); ASSERT_OPENCL(err, "Failed to create normals buffer for target."); // Source cl::Buffer bSrcVertexPositions(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, src.vertexPositions.array().size() * sizeof(float), const_cast<float*>(src.vertexPositions.data()), &err); ASSERT_OPENCL(err, "Failed to create vertex buffer for source."); cl::Buffer bSrcVertexNormals(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, src.vertexNormals.array().size() * sizeof(float), const_cast<float*>(src.vertexNormals.data()), &err); ASSERT_OPENCL(err, "Failed to create normals buffer for source."); cl::Buffer bSrcVertexColors(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, src.vertexColors.array().size() * sizeof(float), const_cast<float*>(src.vertexColors.data()), &err); ASSERT_OPENCL(err, "Failed to create color buffer for source."); // Volume cl::Buffer bSrcVoxels(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, (int)sv.cells.size() * sizeof(int), const_cast<int*>(sv.cells.data()), &err); ASSERT_OPENCL(err, "Failed to create voxel buffer for source."); cl::Buffer bSrcTrianglesInVoxels(ocl.ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, (int)sv.triangleIndices.size() * sizeof(int), const_cast<int*>(sv.triangleIndices.data()), &err); ASSERT_OPENCL(err, "Failed to triangle index buffer for source."); float minmax[8] = { sv.bounds.min().x(), sv.bounds.min().y(), sv.bounds.min().z(), 0.f, sv.bounds.max().x(), sv.bounds.max().y(), sv.bounds.max().z(), 0.f, }; cl_float4 voxelSizes = {{sv.voxelSizes.x(), sv.voxelSizes.y(), sv.voxelSizes.z(), 0}}; cl_float4 invVoxelSizes = {{1.f / sv.voxelSizes.x(), 1.f / sv.voxelSizes.y(), 1.f / sv.voxelSizes.z(), 0}}; cl_int4 voxelsPerDim = {{sv.voxelsPerDimension.x(), sv.voxelsPerDimension.y(), sv.voxelsPerDimension.z(), 0}}; // Texture const int imagesize = 512; Image<unsigned char> texture(imagesize, imagesize, 3); texture.toOpenCV().setTo(0); cl::Image2D bTexture(ocl.ctx, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, cl::ImageFormat(CL_RGB, CL_UNORM_INT8), imagesize, imagesize, 0, texture.row(0), &err); ASSERT_OPENCL(err, "Failed to create texture image."); int argc = 0; ocl.kBakeTexture.setArg(0, bTargetVertexPositions); ocl.kBakeTexture.setArg(1, bTargetVertexNormals); ocl.kBakeTexture.setArg(2, bTargetVertexUVs); ocl.kBakeTexture.setArg(3, bSrcVertexPositions); ocl.kBakeTexture.setArg(4, bSrcVertexNormals); ocl.kBakeTexture.setArg(5, bSrcVertexColors); ocl.kBakeTexture.setArg(6, bSrcVoxels); ocl.kBakeTexture.setArg(7, bSrcTrianglesInVoxels); ocl.kBakeTexture.setArg(8, carray(minmax, 8)); ocl.kBakeTexture.setArg(9, sizeof(cl_float4), voxelSizes.s); ocl.kBakeTexture.setArg(10, sizeof(cl_float4), invVoxelSizes.s); ocl.kBakeTexture.setArg(11, sizeof(cl_int4), voxelsPerDim.s); ocl.kBakeTexture.setArg(12, bTexture); ocl.kBakeTexture.setArg(13, imagesize); ocl.kBakeTexture.setArg(14, 0.5f); ocl.kBakeTexture.setArg(15, (int)target.vertexPositions.cols()/3); int nTrianglesDivisableBy2 = target.vertexPositions.cols()/3 + (target.vertexPositions.cols()/3) % 2; err = ocl.q.enqueueNDRangeKernel(ocl.kBakeTexture, cl::NullRange, cl::NDRange(nTrianglesDivisableBy2), cl::NullRange); ASSERT_OPENCL(err, "Failed to run bake kernel."); cl::size_t<3> origin; origin.push_back(0); origin.push_back(0); origin.push_back(0); cl::size_t<3> region; region.push_back(imagesize); region.push_back(imagesize); region.push_back(1); err = ocl.q.enqueueReadImage(bTexture, false, origin, region, 0, 0, texture.row(0)); ASSERT_OPENCL(err, "Failed to read image."); ocl.q.finish(); cv::Mat m = texture.toOpenCV(); cv::flip(m, m, 0); cv::imwrite("input.png", m); cv::imshow("test", m); cv::waitKey(); return false; }
void RenderState::SpriteInterface(sel::State &p_lua_state, sf::RenderWindow &p_window) { auto lua_interface = p_lua_state["interface"]; auto map_contains = [this] (const std::string &p_identifier) -> bool { return m_spritemap.find(p_identifier) != m_spritemap.end(); }; lua_interface["loadSprite"] = [this, map_contains] (const std::string &p_identifier, const std::string &p_path) -> void { Resource<sf::Texture> texture(p_path, LoadTexture); if(map_contains(p_identifier)) m_spritemap.at(p_identifier)->setTexture(texture.Get()); else m_spritemap[p_identifier] = std::make_unique<sf::Sprite>(texture.Get()); return; }; lua_interface["removeSprite"] = [this] (const std::string &p_identifier) -> void { m_spritemap.erase(p_identifier); return; }; lua_interface["clearSprites"] = [this] () -> void { m_spritemap.clear(); return; }; lua_interface["setSpritePosition"] = [this, map_contains] (const std::string &p_identifier, lua_Number p_x, lua_Number p_y) -> void { if(map_contains(p_identifier)) m_spritemap.at(p_identifier)->setPosition(static_cast<float>(p_x), static_cast<float>(p_y)); return; }; lua_interface["setSpriteRotation"] = [this, map_contains] (const std::string &p_identifier, lua_Number p_deg) -> void { if(map_contains(p_identifier)) { sf::FloatRect size = m_spritemap.at(p_identifier)->getLocalBounds(); m_spritemap.at(p_identifier)->setOrigin(size.width / 2.f, size.height / 2.f); m_spritemap.at(p_identifier)->setRotation(static_cast<float>(p_deg)); m_spritemap.at(p_identifier)->setOrigin(0.f, 0.f); } return; }; lua_interface["setSpriteClip"] = [this, map_contains] (const std::string &p_identifier, int p_l, int p_t, int p_w, int p_h) -> void { if(map_contains(p_identifier)) m_spritemap.at(p_identifier)->setTextureRect(sf::IntRect(p_l, p_t, p_w, p_h)); return; }; lua_interface["setSpriteScale"] = [this, map_contains] (const std::string &p_identifier, lua_Number p_x, lua_Number p_y) -> void { if(map_contains(p_identifier)) m_spritemap.at(p_identifier)->setScale(static_cast<float>(p_x), static_cast<float>(p_y)); return; }; lua_interface["drawSprite"] = [this, map_contains, &p_window] (const std::string &p_identifier) -> void { if(map_contains(p_identifier)) p_window.draw(*m_spritemap.at(p_identifier)); return; }; return; }
sk_sp<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor( const SkMatrix& origTextureMatrix, const SkRect& origConstraintRect, FilterConstraint filterConstraint, bool coordsLimitedToConstraintRect, const GrTextureParams::FilterMode* filterOrNullForBicubic, SkSourceGammaTreatment gammaTreatment) { SkMatrix textureMatrix = origTextureMatrix; const SkIRect* contentArea = this->contentAreaOrNull(); // Convert the constraintRect to be relative to the texture rather than the content area so // that both rects are in the same coordinate system. SkTCopyOnFirstWrite<SkRect> constraintRect(origConstraintRect); if (contentArea) { SkScalar l = SkIntToScalar(contentArea->fLeft); SkScalar t = SkIntToScalar(contentArea->fTop); constraintRect.writable()->offset(l, t); textureMatrix.postTranslate(l, t); } SkRect domain; GrTextureParams params; if (filterOrNullForBicubic) { params.setFilterMode(*filterOrNullForBicubic); } SkAutoTUnref<GrTexture> texture(this->refTextureSafeForParams(params, gammaTreatment, nullptr)); if (!texture) { return nullptr; } // If we made a copy then we only copied the contentArea, in which case the new texture is all // content. if (texture != this->originalTexture()) { contentArea = nullptr; } DomainMode domainMode = determine_domain_mode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect, texture->width(), texture->height(), contentArea, filterOrNullForBicubic, &domain); if (kTightCopy_DomainMode == domainMode) { // TODO: Copy the texture and adjust the texture matrix (both parts need to consider // non-int constraint rect) // For now: treat as bilerp and ignore what goes on above level 0. // We only expect MIP maps to require a tight copy. SkASSERT(filterOrNullForBicubic && GrTextureParams::kMipMap_FilterMode == *filterOrNullForBicubic); static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBilerp_FilterMode; domainMode = determine_domain_mode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect, texture->width(), texture->height(), contentArea, &kBilerp, &domain); SkASSERT(kTightCopy_DomainMode != domainMode); } SkASSERT(kNoDomain_DomainMode == domainMode || (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom)); textureMatrix.postIDiv(texture->width(), texture->height()); return create_fp_for_domain_and_filter(texture, textureMatrix, domainMode, domain, filterOrNullForBicubic); }
void main() { color = texture(skybox, TexCoords); }
int main(int argc, char** argv) { image = glmReadPPM("data/terra.ppm", &iwidth, &iheight); if (!image) exit(0); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize((512+GAP*3)*3/2, 512+GAP*3); glutInitWindowPosition(50, 50); glutInit(&argc, argv); window = glutCreateWindow("Texture"); glutReshapeFunc(main_reshape); glutDisplayFunc(main_display); glutKeyboardFunc(main_keyboard); world = glutCreateSubWindow(window, GAP, GAP, 256, 256); glutReshapeFunc(world_reshape); glutDisplayFunc(world_display); glutKeyboardFunc(main_keyboard); glutCreateMenu(world_menu); glutAddMenuEntry("Textures", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("Fishermen", 'f'); glutAddMenuEntry("OpenGL Logo", 'o'); glutAddMenuEntry("Checker", 'c'); glutAddMenuEntry("Marble", 'm'); glutAddMenuEntry("Train", 't'); glutAttachMenu(GLUT_RIGHT_BUTTON); texture(); screen = glutCreateSubWindow(window, GAP+256+GAP, GAP, 256, 256); glutReshapeFunc(screen_reshape); glutDisplayFunc(screen_display); glutKeyboardFunc(main_keyboard); glutMotionFunc(screen_motion); glutMouseFunc(screen_mouse); texture(); command = glutCreateSubWindow(window, GAP+256+GAP, GAP+256+GAP, 256, 256); glutReshapeFunc(command_reshape); glutMotionFunc(command_motion); glutDisplayFunc(parameters_display); glutMouseFunc(parameters_mouse); glutKeyboardFunc(main_keyboard); glutCreateMenu(command_menu); glutAddMenuEntry("Texture", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("Matrix", 'm'); glutAddMenuEntry("Environment/Parameters", 'p'); glutAddMenuEntry("Reset parameters (r)", 'r'); glutAddMenuEntry("", 0); glutAddMenuEntry("Quit", 27); glutAttachMenu(GLUT_RIGHT_BUTTON); redisplay_all(); glutTimerFunc(500, timer, 0); glutMainLoop(); return 0; }
void Reader::drawText( QGLPainter *painter, const QString& string, const QColor4ub& color ) { Texture texture( string, color ); texture.draw( painter ); }
void MainWindow::packerUpdate() { int i; quint64 area = 0; packer.sortOrder = ui->sortOrder->currentIndex(); packer.border.t = ui->borderTop->value(); packer.border.l = ui->borderLeft->value(); packer.border.r = ui->borderRight->value(); packer.border.b = ui->borderBottom->value(); packer.trim = ui->trim->currentIndex(); packer.merge = ui->merge->isChecked(); packer.mergeBF = false; packer.rotate = ui->rotationStrategy->currentIndex(); int textureWidth = ui->textureW->value(), textureHeight = ui->textureH->value(); int heuristic = ui->comboHeuristic->currentIndex(); QString outDir = ui->outDir->text(); QString outFile = ui->outFile->text(); QString outFormat = ui->outFormat->currentText(); bool previewWithImages =ui->previewWithImages->isChecked(); packer.pack(heuristic, textureWidth, textureHeight); QList<QImage> textures; for (i = 0; i < packer.bins.size(); i++) { QImage texture(packer.bins.at(i).width(), packer.bins.at(i).height(), QImage::Format_ARGB32); texture.fill(Qt::transparent); textures << texture; } if(exporting) { for(int j = 0; j < textures.count(); j++) { QString outputFile = outDir; outputFile += QDir::separator(); outputFile += outFile; if(textures.count() > 1) outputFile += QString("_") + QString::number(j + 1); outputFile += ".atlas"; QString imgFile = outFile; if(textures.count() > 1) imgFile += QString("_") + QString::number(j + 1); imgFile += "."; imgFile += outFormat.toLower(); QFile positionsFile(outputFile); if (!positionsFile.open(QIODevice::WriteOnly | QIODevice::Text)) QMessageBox::critical(0, tr("Error"), tr("Cannot create file ") + outputFile); else { QTextStream out(&positionsFile); out << "textures: " << imgFile << "\n"; for (i = 0; i < packer.images.size(); i++) { if(packer.images.at(i).textureId != j) continue; QPoint pos(packer.images.at(i).pos.x() + packer.border.l, packer.images.at(i).pos.y() + packer.border.t); QSize size, sizeOrig; QRect crop; sizeOrig = packer.images.at(i).size; if(!packer.trim) { size = packer.images.at(i).size; crop = QRect(0,0,size.width(),size.height()); } else { size = packer.images.at(i).crop.size(); crop = packer.images.at(i).crop; } if(packer.images.at(i).rotated) { size.transpose(); crop = QRect(packer.images.at(i).size.height() - crop.y() - crop.height(), crop.x(), crop.height(), crop.width()); } out << (((packerData*)(packer.images.at(i).id))->listItem)->text() << "\t" << pos.x() << "\t" << pos.y() << "\t" << crop.width() << "\t" << crop.height() << "\t" << crop.x() << "\t" << crop.y() << "\t" << sizeOrig.width() << "\t" << sizeOrig.height() << "\t" << (packer.images.at(i).rotated ? "r" : "") << "\n"; } } } } for (i = 0; i < packer.images.size(); i++) { if(packer.images.at(i).pos == QPoint(999999, 999999)) { (((packerData*)(packer.images.at(i).id))->listItem)->setForeground(Qt::red); continue; } (((packerData*)(packer.images.at(i).id))->listItem)->setForeground(Qt::black); if(packer.images.at(i).duplicateId != NULL && packer.merge) { continue; } QPoint pos(packer.images.at(i).pos.x() + packer.border.l, packer.images.at(i).pos.y() + packer.border.t); QSize size; QRect crop; if(!packer.trim) { size = packer.images.at(i).size; crop = QRect(0,0,size.width(),size.height()); } else { size = packer.images.at(i).crop.size(); crop = packer.images.at(i).crop; } QImage img; if((exporting || previewWithImages)) img = QImage(((packerData*)(packer.images.at(i).id))->path); if(packer.images.at(i).rotated) { QTransform myTransform; myTransform.rotate(90); img = img.transformed(myTransform); size.transpose(); crop = QRect(packer.images.at(i).size.height() - crop.y() - crop.height(), crop.x(), crop.height(), crop.width()); } if(packer.images.at(i).textureId < packer.bins.size()) { QPainter p(&textures.operator [](packer.images.at(i).textureId)); if(!exporting) p.fillRect(pos.x(), pos.y(), size.width(), size.height(), pattern); if(previewWithImages || exporting) { p.drawImage(pos.x(), pos.y(), img, crop.x(), crop.y(), crop.width(), crop.height()); } else if(!exporting) p.drawRect(pos.x(), pos.y(), size.width() - 1, size.height() - 1); } } for(int i = 0; i < textures.count(); i++) area += textures.at(i).width() * textures.at(i).height(); float percent = (((float)packer.area / (float)area) * 100.0f); float percent2 = (float)(((float)packer.neededArea / (float)area) * 100.0f ); ui->preview->setText(tr("Preview: ") + QString::number(percent) + QString("% filled, ") + (packer.missingImages == 0 ? QString::number(packer.missingImages) + tr(" images missed,") : QString("<font color=red><b>") + QString::number(packer.missingImages) + tr(" images missed,") + "</b></font>") + " " + QString::number(packer.mergedImages) + tr(" images merged, needed area: ") + QString::number(percent2) + "%."); if(exporting) { const char * format = qPrintable(outFormat); for(int i = 0; i < textures.count(); i++) { QString imgdirFile; imgdirFile = outDir; imgdirFile += QDir::separator(); imgdirFile += outFile; if(textures.count() > 1) imgdirFile += QString("_") + QString::number(i + 1); imgdirFile += "."; imgdirFile += outFormat.toLower(); if(outFormat == "JPG") { int res = textures.at(i).save(imgdirFile, format, 100); } else { int res = textures.at(i).save(imgdirFile); } } QMessageBox::information(0, tr("Done"), tr("Your atlas successfully saved in ") + outDir); exporting = false; } else emit renderedImage(textures); }
void subCompute(TRasterFxPort &m_input, TTile &tile, double frame, const TRenderSettings &ri, TPointD p00, TPointD p01, TPointD p11, TPointD p10, int details, bool wireframe, TDimension m_offScreenSize, bool isCast) { TPixel32 bgColor; TRectD outBBox, inBBox; outBBox = inBBox = TRectD(tile.m_pos, TDimensionD(tile.getRaster()->getLx(), tile.getRaster()->getLy())); m_input->getBBox(frame, inBBox, ri); if (inBBox == TConsts::infiniteRectD) // e' uno zerario inBBox = outBBox; int inBBoxLx = (int)inBBox.getLx() / ri.m_shrinkX; int inBBoxLy = (int)inBBox.getLy() / ri.m_shrinkY; if (inBBox.isEmpty()) return; if (p00 == p01 && p00 == p10 && p00 == p11 && !isCast) // significa che non c'e' deformazione { m_input->compute(tile, frame, ri); return; } TRaster32P rasIn; TPointD rasInPos; if (!wireframe) { if (ri.m_bpp == 64 || ri.m_bpp == 48) { TRaster64P aux = TRaster64P(inBBoxLx, inBBoxLy); rasInPos = TPointD(inBBox.x0 / ri.m_shrinkX, inBBox.y0 / ri.m_shrinkY); TTile tmp(aux, rasInPos); m_input->compute(tmp, frame, ri); rasIn = TRaster32P(inBBoxLx, inBBoxLy); TRop::convert(rasIn, aux); } else { rasInPos = TPointD(inBBox.x0 / ri.m_shrinkX, inBBox.y0 / ri.m_shrinkY); TTile tmp(TRaster32P(inBBoxLx, inBBoxLy), rasInPos); m_input->allocateAndCompute(tmp, rasInPos, TDimension(inBBoxLx, inBBoxLy), TRaster32P(), frame, ri); rasIn = tmp.getRaster(); } } unsigned int texWidth = 2; unsigned int texHeight = 2; while (texWidth < (unsigned int)inBBoxLx) texWidth = texWidth << 1; while (texHeight < (unsigned int)inBBoxLy) texHeight = texHeight << 1; while (texWidth > 1024 || texHeight > 1024) // avevo usato la costante // GL_MAX_TEXTURE_SIZE invece di // 1024, ma non funzionava! { inBBoxLx = inBBoxLx >> 1; inBBoxLy = inBBoxLy >> 1; texWidth = texWidth >> 1; texHeight = texHeight >> 1; } if (rasIn->getLx() != inBBoxLx || rasIn->getLy() != inBBoxLy) { TRaster32P rasOut = TRaster32P(inBBoxLx, inBBoxLy); TRop::resample(rasOut, rasIn, TScale((double)rasOut->getLx() / rasIn->getLx(), (double)rasOut->getLy() / rasIn->getLy())); rasIn = rasOut; } int rasterWidth = tile.getRaster()->getLx() + 2; int rasterHeight = tile.getRaster()->getLy() + 2; assert(rasterWidth > 0); assert(rasterHeight > 0); TRectD clippingRect = TRectD(tile.m_pos, TDimensionD(tile.getRaster()->getLx(), tile.getRaster()->getLy())); #if CREATE_GL_CONTEXT_ONE_TIME int ret = wglMakeCurrent(m_offScreenGL.m_offDC, m_offScreenGL.m_hglRC); assert(ret == TRUE); #else TOfflineGL offScreenRendering(TDimension(rasterWidth, rasterHeight)); //#ifdef _WIN32 offScreenRendering.makeCurrent(); //#else //#if defined(LINUX) || defined(MACOSX) // offScreenRendering.m_offlineGL->makeCurrent(); //#endif #endif checkErrorsByGL // disabilito quello che non mi serve per le texture glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); glDisable(GL_DITHER); glDisable(GL_DEPTH_TEST); glCullFace(GL_FRONT); glDisable(GL_STENCIL_TEST); glDisable(GL_LOGIC_OP); // creo la texture in base all'immagine originale glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); checkErrorsByGL #if !CREATE_GL_CONTEXT_ONE_TIME TRaster32P rasaux; if (!wireframe) { TRaster32P texture(texWidth, texHeight); texture->clear(); rasaux = texture; rasaux->lock(); texture->copy(rasIn); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, 4, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->getRawData()); } #else unsigned int texWidth = 1024; unsigned int texHeight = 1024; rasaux = rasIn; rasaux->lock(); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rasIn->getLx(), rasIn->getLy(), GL_RGBA, GL_UNSIGNED_BYTE, rasIn->getRawData()); #endif checkErrorsByGL glEnable(GL_TEXTURE_2D); // cfr. help: OpenGL/Programming tip/OpenGL Correctness Tips glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-rasterWidth * 0.5, rasterWidth * 0.5, -rasterHeight * 0.5, rasterHeight * 0.5, -1, 1); glViewport(0, 0, rasterWidth, rasterHeight); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); // do OpenGL draw double lwTex = (double)(inBBoxLx - 1) / (double)(texWidth - 1); double lhTex = (double)(inBBoxLy - 1) / (double)(texHeight - 1); TPointD tex00 = TPointD(0.0, 0.0); TPointD tex10 = TPointD(lwTex, 0.0); TPointD tex11 = TPointD(lwTex, lhTex); TPointD tex01 = TPointD(0.0, lhTex); GLenum polygonStyle; if (wireframe) { polygonStyle = GL_LINE; glDisable(GL_TEXTURE_2D); } else polygonStyle = GL_FILL; checkErrorsByGL p00.x /= ri.m_shrinkX; p00.y /= ri.m_shrinkY; p10.x /= ri.m_shrinkX; p10.y /= ri.m_shrinkY; p11.x /= ri.m_shrinkX; p11.y /= ri.m_shrinkY; p01.x /= ri.m_shrinkX; p01.y /= ri.m_shrinkY; TPointD translate = TPointD(tile.m_pos.x + tile.getRaster()->getLx() * 0.5, tile.m_pos.y + tile.getRaster()->getLy() * 0.5); glTranslated(-translate.x, -translate.y, 0.0); // disegno il poligono double dist_p00_p01 = tdistance2(p00, p01); double dist_p10_p11 = tdistance2(p10, p11); double dist_p01_p11 = tdistance2(p01, p11); double dist_p00_p10 = tdistance2(p00, p10); bool vertical = (dist_p00_p01 == dist_p10_p11); bool horizontal = (dist_p00_p10 == dist_p01_p11); if (vertical && horizontal) details = 1; glPolygonMode(GL_FRONT_AND_BACK, polygonStyle); subdivision(p00, p10, p11, p01, tex00, tex10, tex11, tex01, clippingRect, details); if (!wireframe) { // abilito l'antialiasing delle linee glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // disegno il bordo del poligono glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_QUADS); glTexCoord2d(tex00.x, tex00.y); tglVertex(p00); glTexCoord2d(tex10.x, tex10.y); tglVertex(p10); glTexCoord2d(tex11.x, tex11.y); tglVertex(p11); glTexCoord2d(tex01.x, tex01.y); tglVertex(p01); glEnd(); // disabilito l'antialiasing per le linee glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } // force to finish glFlush(); // rimetto il disegno dei poligoni a GL_FILL glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // metto il frame buffer nel raster del tile glPixelStorei(GL_UNPACK_ROW_LENGTH, rasterWidth); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); TRaster32P newRas(tile.getRaster()->getLx(), tile.getRaster()->getLy()); newRas->lock(); glReadPixels(1, 1, newRas->getLx(), newRas->getLy(), GL_RGBA, GL_UNSIGNED_BYTE, (void *)newRas->getRawData()); newRas->unlock(); checkErrorsByGL rasaux->unlock(); tile.getRaster()->copy(newRas); }
void CircularCam::objectStep(double dt, World *w, PhysicalObject *po) { // if we see over the object if (height > po->getHeight()) return; if (!po->isCylindric()) { // object has a hull for (PhysicalObject::Hull::const_iterator it = po->getHull().begin(); it != po->getHull().end(); ++it) { if (height > it->getHeight()) continue; const Polygone& shape = it->getTransformedShape(); const size_t faceCount = shape.size(); if (it->isTextured()) { for (size_t i = 0; i<faceCount; i++) drawTexturedLine(shape[i], shape[(i+1) % faceCount], it->getTextures()[i]); } else { Texture texture(1, po->getColor()); for (size_t i = 0; i<faceCount; i++) drawTexturedLine(shape[i], shape[(i+1) % faceCount], texture); } } } else { // object has no bounding surface, monocolor const double radius = po->getRadius(); const Color& color = po->getColor(); // compute basic parameter if (radius == 0) return; const Vector poCenter = po->pos - absPos; const double poDist = poCenter.norm(); if (poDist == 0) return; const double poAngle = normalizeAngle(poCenter.angle() - absOrientation); const double poAperture = atan(radius / poDist); assert(poAperture > 0); // clip object const double poBegin = poAngle - poAperture; const double poEnd = poAngle + poAperture; if (poBegin > halfFieldOfView || poEnd < -halfFieldOfView) return; const double beginAngle = std::max(poBegin, -halfFieldOfView); const double endAngle = std::min(poEnd, halfFieldOfView); // compute first pixel used // formula is (beginAngle + fov) / pixelAngle, with // pixelAngle = 2fov / (numPix-1) const size_t firstPixelUsed = static_cast<size_t>(floor((zbuffer.size() - 1) * 0.5 * (beginAngle / halfFieldOfView + 1))); const size_t lastPixelUsed = static_cast<size_t>(ceil((zbuffer.size() - 1) * 0.5 * (endAngle / halfFieldOfView + 1))); const double poDist2 = poDist * poDist; for (size_t i = firstPixelUsed; i <= lastPixelUsed; i++) { // apply pixel operation to framebuffer (*pixelOperation)(zbuffer[i], image[i], poDist2, color); } } };
void main() { // Linearly interpolate between both textures (second texture is only slightly combined) color = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.5); //color = vec4(1.0f, 0.0f,0.0, 1.0f); }
GtaStyle::GtaStyle(std::string filename) { std::cout << "opening map: " << filename << std::endl; std::ifstream f(filename.c_str()); f.seekg(0, std::ios::end); int size = f.tellg(); f.seekg(0, std::ios::beg); std::cout << "allocating " << size << " bytes for map" << std::endl; _data = new char[size]; f.read(_data, size); f.close(); char* offset = _data; FileHeader* file_header = reinterpret_cast<FileHeader*>(offset); std::string hdr(file_header->name, 0, 4); if(hdr != "GBST") throw std::runtime_error("wrong header: \"" + hdr + "\""); if(file_header->version != 700) throw std::runtime_error("wrong version: " + boost::lexical_cast<std::string>(file_header->version)); offset += sizeof(FileHeader); while(offset < _data + size) { ChunkHeader* chunk_header = reinterpret_cast<ChunkHeader*>(offset); offset += sizeof(ChunkHeader); std::string chunk_hdr(chunk_header->type, 0, 4); std::cout << "Found: " << chunk_hdr << " at " << offset - _data << ", size: " << chunk_header->size << std::endl; if(chunk_hdr == "PALX") // palette index { _palette_index.phys_palette = reinterpret_cast<uint16_t*>(offset); offset += chunk_header->size; } else if(chunk_hdr == "PPAL") // physical palettes { _palette_data = reinterpret_cast<uint32_t*>(offset); offset += chunk_header->size; } else if(chunk_hdr == "PALB") // palette base { _palette_base = reinterpret_cast<PaletteBase*>(offset); offset += sizeof(PaletteBase); } else if(chunk_hdr == "TILE") { _tiles = reinterpret_cast<uint8_t*>(offset); offset += chunk_header->size; } else { std::cout << "skipping " << chunk_header->size << " bytes on \"" << chunk_hdr << "\" offset: " << (int)(offset - _data) << std::endl; offset += chunk_header->size; } } _textures.reserve(992); const int page_size = 256 * 256; for(int page_num = 0; page_num < 62; page_num++) { uint8_t* page = _tiles + page_size * page_num; for(int y = 0; y < 4; y++) { for(int x = 0; x < 4; x++) { uint32_t tile[64*64]; const int tile_index = page_num * 16 + y * 4 + x; int palette_index = _palette_index.phys_palette[tile_index]; bool has_transparency = false; for(int tile_y = 0; tile_y < 64; tile_y++) { for(int tile_x = 0; tile_x < 64; tile_x++) { uint8_t c = page[(y * 64 + tile_y) * 256 + x * 64 + tile_x]; if(c == 0) { has_transparency = true; tile[tile_y * 64 + tile_x] = 0x00000000; } else { tile[tile_y * 64 + tile_x] = getPaletteValue(palette_index, c) | 0xff000000; } } } boost::shared_ptr<Texture> texture(new Texture); texture->hasTransparency(has_transparency); texture->bind(); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 64, 64, GL_BGRA, GL_UNSIGNED_BYTE, tile); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_BGRA, GL_UNSIGNED_BYTE, tile); _textures.push_back(texture); } } } }
/** * Maps the font bitmaps to an OpenGL texture object. * * This is a public function so it can be called whenever the OpenGL context * gets destroyed (eg. after a windows resize on MS Windows). */ void NoDice::Font:: mapToTexture() { typedef std::vector<GLubyte> Texture; static const std::size_t bitmapDepth = 2*sizeof(GLubyte); // The stride for individual bitmap rows within the texture. const Texture::size_type stride = m_textureWidth * bitmapDepth; // Convenience variables to make later conversion of tex coords onto (0,1) // easier. const GLfloat fTextureWidth = static_cast<GLfloat>(m_textureWidth); const GLfloat fTextureHeight = static_cast<GLfloat>(m_textureHeight); Texture texture(m_textureWidth * m_textureHeight * bitmapDepth); // The current write-to position within the texture. These values do not take // the bitmapDepth into account. int curTexX = 0; int curTexY = 0; for (unsigned char c = 0; c < s_max_char; ++c) { // Copy the glyph bitmap into the texture. // // The glyph bitmap is a packed array of height rows of width bytes. This // has to be projected into the texture array as the same rows but but with // a stride of m_textureWidth * bitmapDepth bytes. // Texture::iterator texPos = texture.begin() + curTexY * stride + curTexX * bitmapDepth; Glyph::Bitmap::size_type bitmapWidth = m_glyph[c].width * bitmapDepth; for (Glyph::Bitmap::const_iterator bitmapLine = m_glyph[c].bitmap.begin(); bitmapLine != m_glyph[c].bitmap.end(); bitmapLine += bitmapWidth, texPos += stride) { std::copy(bitmapLine, bitmapLine + bitmapWidth, texPos); } // Remember the texel coordinates for the glyph m_glyph[c].s = static_cast<GLfloat>(curTexX) / fTextureWidth; m_glyph[c].t = static_cast<GLfloat>(curTexY) / fTextureHeight; m_glyph[c].w = static_cast<GLfloat>(m_glyph[c].width) / fTextureWidth; m_glyph[c].h = static_cast<GLfloat>(m_glyph[c].height) / fTextureHeight; // Adjust the destination offset for the next glyph if (curTexX + m_glyph[c].width < m_textureWidth) { curTexX += m_glyph[c].width; } else { curTexX = 0; ++curTexY; } } // Send it to the OpenGL engine. glEnable(GL_TEXTURE_2D); glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_2D, m_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, m_textureWidth, m_textureHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, &texture[0]); check_gl_error("glTexImage2D"); glDisable(GL_TEXTURE_2D); }