CTexturePtr Graphics::LoadTexture(const std::wstring& szFileName ) { // ищем текстуру среди уже загруженных vecTextures::iterator itr = m_vecTextures.begin(); while(itr!=m_vecTextures.end()) { if ( (*itr)->GetSrc().compare(szFileName)==0 ) return *itr; // нашли itr++; } // не нашли, пробуем загрузить текстуру LPDIRECT3DTEXTURE9 pTex = NULL; if (FAILED(D3DXCreateTextureFromFile(m_pd3dDevice, szFileName.c_str(), &pTex))) return NULL; // создаЄм наш собственный обект текстуры CTexturePtr pTexPtr = new CTexture(); pTexPtr->SetSrc(szFileName); pTexPtr->SetTexture(pTex); m_vecTextures.push_back(pTexPtr); return pTexPtr; // возвращаем (указатель на) новую текстуру }
// This is for Atlas. TODO: this copies code from init, should reuse it. void WaterManager::ReloadWaterNormalTextures() { wchar_t pathname[PATH_MAX]; // Load normalmaps (for fancy water) for (size_t i = 0; i < ARRAY_SIZE(m_NormalMap); ++i) { swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/normal00%02d.png", m_WaterType.c_str(), (int)i+1); CTextureProperties textureProps(pathname); textureProps.SetWrap(GL_REPEAT); textureProps.SetMaxAnisotropy(4); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_NormalMap[i] = texture; } }
HRESULT Graphics::SetTexture( DWORD stage, CTexturePtr pTex ) { if (pTex) return m_pd3dDevice->SetTexture(stage, pTex->GetTexture()); return m_pd3dDevice->SetTexture(stage, NULL); }
/////////////////////////////////////////////////////////////////// // Progressive load of water textures int WaterManager::LoadWaterTextures() { // TODO: this doesn't need to be progressive-loading any more // (since texture loading is async now) wchar_t pathname[PATH_MAX]; // Load diffuse grayscale images (for non-fancy water) for (size_t i = 0; i < ARRAY_SIZE(m_WaterTexture); ++i) { swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/default/diffuse%02d.dds", (int)i+1); CTextureProperties textureProps(pathname); textureProps.SetWrap(GL_REPEAT); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_WaterTexture[i] = texture; } if (!g_Renderer.GetCapabilities().m_PrettyWater) { // Enable rendering, now that we've succeeded this far m_RenderWater = true; return 0; } #if CONFIG2_GLES #warning Fix WaterManager::LoadWaterTextures on GLES #else // Load normalmaps (for fancy water) for (size_t i = 0; i < ARRAY_SIZE(m_NormalMap); ++i) { swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/normal00%02d.png", m_WaterType.c_str(), (int)i+1); CTextureProperties textureProps(pathname); textureProps.SetWrap(GL_REPEAT); textureProps.SetMaxAnisotropy(4); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_NormalMap[i] = texture; } // Load CoastalWaves { CTextureProperties textureProps(L"art/textures/terrain/types/water/coastalWave.png"); textureProps.SetWrap(GL_REPEAT); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_WaveTex = texture; } // Load Foam { CTextureProperties textureProps(L"art/textures/terrain/types/water/foam.png"); textureProps.SetWrap(GL_REPEAT); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_FoamTex = texture; } // Use screen-sized textures for minimum artifacts. m_RefTextureSize = g_Renderer.GetHeight(); m_RefTextureSize = round_up_to_pow2(m_RefTextureSize); // Create reflection texture glGenTextures(1, &m_ReflectionTexture); glBindTexture(GL_TEXTURE_2D, m_ReflectionTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // Create refraction texture glGenTextures(1, &m_RefractionTexture); glBindTexture(GL_TEXTURE_2D, m_RefractionTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); // Create depth textures glGenTextures(1, &m_ReflFboDepthTexture); glBindTexture(GL_TEXTURE_2D, m_ReflFboDepthTexture); 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_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL); glGenTextures(1, &m_RefrFboDepthTexture); glBindTexture(GL_TEXTURE_2D, m_RefrFboDepthTexture); 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_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL); // Create the Fancy Effects texture glGenTextures(1, &m_FancyTextureNormal); glBindTexture(GL_TEXTURE_2D, m_FancyTextureNormal); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glGenTextures(1, &m_FancyTextureOther); glBindTexture(GL_TEXTURE_2D, m_FancyTextureOther); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glGenTextures(1, &m_FancyTextureDepth); glBindTexture(GL_TEXTURE_2D, m_FancyTextureDepth); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0); Resize(); // Create the water framebuffers GLint currentFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, ¤tFbo); m_ReflectionFbo = 0; pglGenFramebuffersEXT(1, &m_ReflectionFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ReflectionFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_ReflectionTexture, 0); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_ReflFboDepthTexture, 0); ogl_WarnIfError(); GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING("Reflection framebuffer object incomplete: 0x%04X", status); g_Renderer.m_Options.m_WaterReflection = false; } m_RefractionFbo = 0; pglGenFramebuffersEXT(1, &m_RefractionFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_RefractionFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_RefractionTexture, 0); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_RefrFboDepthTexture, 0); ogl_WarnIfError(); status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING("Refraction framebuffer object incomplete: 0x%04X", status); g_Renderer.m_Options.m_WaterRefraction = false; } pglGenFramebuffersEXT(1, &m_FancyEffectsFBO); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FancyEffectsFBO); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_FancyTextureNormal, 0); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_FancyTextureOther, 0); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_FancyTextureDepth, 0); ogl_WarnIfError(); status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING("Fancy Effects framebuffer object incomplete: 0x%04X", status); g_Renderer.m_Options.m_WaterRefraction = false; } pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, currentFbo); // Enable rendering, now that we've succeeded this far m_RenderWater = true; #endif return 0; }
/////////////////////////////////////////////////////////////////// // Load all sky textures void SkyManager::LoadSkyTextures() { for (size_t i = 0; i < ARRAY_SIZE(m_SkyTexture); ++i) { VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(s_imageNames[i])+L".dds"); CTextureProperties textureProps(path); textureProps.SetWrap(GL_CLAMP_TO_EDGE); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_SkyTexture[i] = texture; } glGenTextures(1, &m_SkyCubeMap); glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyCubeMap); int types[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y }; const wchar_t* images[numTextures+1] = { L"front", L"back", L"right", L"left", L"top", L"top" }; for (size_t i = 0; i < numTextures+1; ++i) { VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(images[i])+L".dds"); shared_ptr<u8> file; size_t fileSize; g_VFS->LoadFile(path, file, fileSize); Tex tex; tex_decode(file, fileSize, &tex); tex_transform_to(&tex, (tex.flags | TEX_BOTTOM_UP | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS)); u8* data = tex_get_data(&tex); if (types[i] == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y || types[i] == GL_TEXTURE_CUBE_MAP_POSITIVE_Y) { std::vector<u8> rotated(tex.dataSize); for (size_t y = 0; y < tex.h; ++y) { for (size_t x = 0; x < tex.w; ++x) { size_t invx = y, invy = tex.w-x-1; rotated[(y*tex.w + x) * 4 + 0] = data[(invy*tex.w + invx) * 4 + 0]; rotated[(y*tex.w + x) * 4 + 1] = data[(invy*tex.w + invx) * 4 + 1]; rotated[(y*tex.w + x) * 4 + 2] = data[(invy*tex.w + invx) * 4 + 2]; rotated[(y*tex.w + x) * 4 + 3] = data[(invy*tex.w + invx) * 4 + 3]; } } glTexImage2D(types[i], 0, GL_RGB, tex.w, tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rotated[0]); } else { glTexImage2D(types[i], 0, GL_RGB, tex.w, tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } tex_free(&tex); } glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 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); glBindTexture(GL_TEXTURE_2D, 0); }
/////////////////////////////////////////////////////////////////// // Progressive load of water textures int WaterManager::LoadWaterTextures() { // TODO: this doesn't need to be progressive-loading any more // (since texture loading is async now) // TODO: add a member variable and setter for this. (can't make this // a parameter because this function is called via delay-load code) static const wchar_t* const water_type = L"default"; wchar_t pathname[PATH_MAX]; // Load diffuse grayscale images (for non-fancy water) for (size_t i = 0; i < ARRAY_SIZE(m_WaterTexture); ++i) { swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/diffuse%02d.dds", water_type, (int)i+1); CTextureProperties textureProps(pathname); textureProps.SetWrap(GL_REPEAT); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_WaterTexture[i] = texture; } // Load normalmaps (for fancy water) for (size_t i = 0; i < ARRAY_SIZE(m_NormalMap); ++i) { swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/normal%02d.dds", water_type, (int)i+1); CTextureProperties textureProps(pathname); textureProps.SetWrap(GL_REPEAT); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_NormalMap[i] = texture; } // Load foam (for fancy water) { CTextureProperties textureProps("art/textures/terrain/types/water/foam.png"); textureProps.SetWrap(GL_REPEAT); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_Foam = texture; } // Load waves (for fancy water) { CTextureProperties textureProps("art/textures/terrain/types/water/shore_wave.png"); textureProps.SetWrap(GL_REPEAT); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_Wave = texture; } // Set the size to the largest power of 2 that is <= to the window height, so // the reflection/refraction images will fit within the window // (alternative: use FBO's, which can have arbitrary size - but do we need // the reflection/refraction textures to be that large?) int size = (int)round_up_to_pow2((unsigned)g_Renderer.GetHeight()); if(size > g_Renderer.GetHeight()) size /= 2; m_ReflectionTextureSize = size; m_RefractionTextureSize = size; // Create reflection texture glGenTextures(1, &m_ReflectionTexture); glBindTexture(GL_TEXTURE_2D, m_ReflectionTexture); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)m_ReflectionTextureSize, (GLsizei)m_ReflectionTextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create refraction texture glGenTextures(1, &m_RefractionTexture); glBindTexture(GL_TEXTURE_2D, m_RefractionTexture); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)m_RefractionTextureSize, (GLsizei)m_RefractionTextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); // Enable rendering, now that we've succeeded this far m_RenderWater = true; return 0; }
void GUIRenderer::UpdateDrawCallCache(DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map<CStr, CGUISprite*>& Sprites) { // This is called only when something has changed (like the size of the // sprite), so it doesn't need to be particularly efficient. // Clean up the old data Calls.clear(); // If this object has zero size, there's nothing to render. (This happens // with e.g. tooltips that have zero size before they're first drawn, so // it isn't necessarily an error.) if (Size.left == Size.right && Size.top == Size.bottom) return; std::map<CStr, CGUISprite*>::iterator it(Sprites.find(SpriteName)); if (it == Sprites.end()) { /* * Sprite not found. Check whether this a special sprite, * and if so create a new sprite: * "stretched:filename.ext" - stretched image * "stretched:grayscale:filename.ext" - stretched grayscale image. * "cropped:0.5, 0.25" - stretch this ratio (x,y) of the top left of the image * "color:r g b a" - solid color * > "textureAsMask" - when using color, use the (optional) texture alpha channel as mask. * These can be combined, but they must be separated by a ":" * so you can have a white overlay over an stretched grayscale image with: * "grayscale:color:255 255 255 100:stretched:filename.ext" */ // Check that this can be a special sprite. if (SpriteName.ReverseFind(":") == -1 && SpriteName.Find("color(") == -1) { LOGERROR("Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str()); return; } CGUISprite* Sprite = new CGUISprite; VfsPath TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.AfterLast(":")); if (SpriteName.Find("stretched:") != -1) { // TODO: Should check (nicely) that this is a valid file? SGUIImage* Image = new SGUIImage; Image->m_TextureName = TextureName; // Allow grayscale images for disabled portraits if (SpriteName.Find("grayscale:") != -1) { Image->m_Effects = new SGUIImageEffects; Image->m_Effects->m_Greyscale = true; } CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); Image->m_Size = ca; Image->m_TextureSize = ca; Sprite->AddImage(Image); Sprites[SpriteName] = Sprite; } else if (SpriteName.Find("cropped:") != -1) { // TODO: Should check (nicely) that this is a valid file? SGUIImage* Image = new SGUIImage; CStr info = SpriteName.AfterLast("cropped:").BeforeFirst(":"); double xRatio = info.BeforeFirst(",").ToDouble(); double yRatio = info.AfterLast(",").ToDouble(); Image->m_TextureName = TextureName; CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); CClientArea cb(CRect(0, 0, 0, 0), CRect(0, 0, 100/xRatio, 100/yRatio)); Image->m_Size = ca; Image->m_TextureSize = cb; Sprite->AddImage(Image); Sprites[SpriteName] = Sprite; } if (SpriteName.Find("color:") != -1) { CStrW value = wstring_from_utf8(SpriteName.AfterLast("color:").BeforeFirst(":")); CColor color; // Check color is valid if (!GUI<CColor>::ParseString(value, color)) { LOGERROR("GUI: Error parsing sprite 'color' (\"%s\")", utf8_from_wstring(value)); return; } SGUIImage* Image = new SGUIImage; // If we are using a mask, this is an effect. // Otherwise we can fallback to the "back color" attribute // TODO: we are assuming there is a filename here. if (SpriteName.Find("textureAsMask:") != -1) { Image->m_TextureName = TextureName; Image->m_Effects = new SGUIImageEffects; Image->m_Effects->m_SolidColor = color; } else Image->m_BackColor = color; CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); Image->m_Size = ca; Image->m_TextureSize = ca; Sprite->AddImage(Image); Sprites[SpriteName] = Sprite; } it = Sprites.find(SpriteName); // Otherwise, just complain and give up: if (it == Sprites.end()) { SAFE_DELETE(Sprite); LOGERROR("Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str()); return; } } Calls.reserve(it->second->m_Images.size()); // Iterate through all the sprite's images, loading the texture and // calculating the texture coordinates std::vector<SGUIImage*>::const_iterator cit; for (cit = it->second->m_Images.begin(); cit != it->second->m_Images.end(); ++cit) { SDrawCall Call(*cit); // pointers are safe since we never modify sprites/images after startup CRect ObjectSize = (*cit)->m_Size.GetClientArea(Size); if (ObjectSize.GetWidth() == 0.0 || ObjectSize.GetHeight() == 0.0) { // Zero sized object. Don't report as an error, since it's common for e.g. hitpoint bars. continue; // i.e. don't continue with this image } Call.m_Vertices = ObjectSize; if ((*cit)->m_RoundCoordinates) { // Round the vertex coordinates to integers, to avoid ugly filtering artifacts Call.m_Vertices.left = (int)(Call.m_Vertices.left + 0.5f); Call.m_Vertices.right = (int)(Call.m_Vertices.right + 0.5f); Call.m_Vertices.top = (int)(Call.m_Vertices.top + 0.5f); Call.m_Vertices.bottom = (int)(Call.m_Vertices.bottom + 0.5f); } if (!(*cit)->m_TextureName.empty()) { CTextureProperties textureProps(g_L10n.LocalizePath((*cit)->m_TextureName)); textureProps.SetWrap((*cit)->m_WrapMode); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); Call.m_HasTexture = true; Call.m_Texture = texture; Call.m_EnableBlending = false; // will be overridden if the texture has an alpha channel Call.m_ObjectSize = ObjectSize; Call.m_CellID = CellID; } else { Call.m_HasTexture = false; // Enable blending if it's transparent (allowing a little error in the calculations) Call.m_EnableBlending = !(fabs((*cit)->m_BackColor.a - 1.0f) < 0.0000001f); } Call.m_BackColor = (*cit)->m_BackColor; Call.m_BorderColor = (*cit)->m_Border ? (*cit)->m_BorderColor : CColor(); Call.m_DeltaZ = (*cit)->m_DeltaZ; if (!Call.m_HasTexture) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid); } else if ((*cit)->m_Effects) { if ((*cit)->m_Effects->m_AddColor != CColor()) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_add); Call.m_ShaderColorParameter = (*cit)->m_Effects->m_AddColor; // Always enable blending if something's being subtracted from // the alpha channel if ((*cit)->m_Effects->m_AddColor.a < 0.f) Call.m_EnableBlending = true; } else if ((*cit)->m_Effects->m_Greyscale) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_grayscale); } else if ((*cit)->m_Effects->m_SolidColor != CColor()) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid_mask); Call.m_ShaderColorParameter = (*cit)->m_Effects->m_SolidColor; Call.m_EnableBlending = !(fabs((*cit)->m_Effects->m_SolidColor.a - 1.0f) < 0.0000001f); } else /* Slight confusion - why no effects? */ { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_basic); } } else { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_basic); } Calls.push_back(Call); } }
void ShaderRenderModifier::PrepareTexture(int pass, CTexturePtr& texture) { CShaderProgramPtr shader = m_Technique.GetShader(pass); shader->BindTexture("baseTex", texture->GetHandle()); }
void PlainRenderModifier::PrepareTexture(int UNUSED(pass), CTexturePtr& texture) { texture->Bind(0); }
void CFreeFont::MakeLetter(wchar_t code) { // Первая вещь, которую нам надо сделать, это вывести наш символ // в растр. Это делается набором команд FreeType // Загрузить глифы для каждого символа. if(FT_Load_Glyph(face, FT_Get_Char_Index(face, code), FT_LOAD_DEFAULT)) throw NOVA_EXP("CFreeFont::MakeLetter - FT_Load_Glyph failed", BAD_OPERATION); // Поместить глиф в объект. FT_Glyph glyph; if(FT_Get_Glyph(face->glyph, &glyph)) throw NOVA_EXP("CFreeFont::MakeLetter - FT_Get_Glyph failed", BAD_OPERATION); // Конвертировать глиф в растр. FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); FT_BitmapGlyph bitmap_glyph = reinterpret_cast<FT_BitmapGlyph>(glyph); // С помощью этой ссылки, получаем легкий доступ до растра. FT_Bitmap & bitmap = bitmap_glyph->bitmap; // Используем нашу вспомогательную функцию для вычисления ширины и высоты // текстуры для нашего растра. nInt32 bwidth = NextP2(bitmap.width); nInt32 bheight = NextP2(bitmap.rows); // Выделим память для данных текстуры. //nByte * expanded_data = NULL; //expanded_data = getmem<nByte>(expanded_data, 2 * bwidth * bheight); CMemoryBuffer mem; mem.AllocBuffer(2 * bwidth * bheight); nByte * expanded_data = (nova::nByte *)mem.GetBegin(); // Поместим данные в расширенный растр. // Отмечу, что использован двухканальный растр (Один для // канала яркости и один для альфа), но мы будем назначать // обоим каналам одно и тоже значение, которое мы // получим из растра FreeType. // Мы используем оператор ?: для того чтобы поместить 0 в зону вне растра FreeType. for(nInt32 j = 0; j < bheight; ++j) for(nInt32 i = 0; i < bwidth; ++i) expanded_data[2*(i + j * bwidth)] = expanded_data[2*(i + j * bwidth)+1] = (i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j]; /* GLuint texture; glGenTextures(1, &texture); glBindTexture( GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Здесь мы создаем текстуру // Помните, что используем GL_LUMINANCE_ALPHA, чтобы было два альфа канала данных glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bwidth, bheight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data); */ //nInt32 tid = CTextureManager::GetSingeltonPtr()->AddTexture(GL_TEXTURE_2D, // expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA); /* CTexturePtr ptex = CTextureManager::GetSingeltonPtr()->AddTexture(new CTexture(fname.c_str(), GL_TEXTURE_2D)); ptex->SetEnvType(GL_MODULATE); ptex->CreateTexture(expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA, GL_CLAMP); // После создания текстуры, мы больше не нуждаемся в промежуточных данных. freemems(expanded_data); CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6, slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows, code, ptex); */ nstring resnamet; nstring resnamei("TempFontImage"); resnamet = mName + "_" + CStringUtils::IntTo16xString(static_cast<nInt32>(code)); // Создаем промежуточное изображение в памяти CImagePtr pImage = CImageManager::GetSingelton().CreateNewImage(resnamei, mName, mem, bwidth, bheight, 1, CImageFormats::NF_LUMINANCE_ALPHA, CResource::NV_FREE); // На базе изображения создаем текстуру CTexturePtr texp = CTextureManager::GetSingelton().CreateNewTexture(resnamet, mName, pImage); // После создания текстуры, мы больше не нуждаемся в промежуточных данных. mem.FreeBuffer(); CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6, slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows, code, texp); mSize += texp->GetSize(); /// Создаем дисплейный список на букву /////////////////////////////////////////////// letter.GetDispList().CreateList(); letter.GetDispList().BeginList(); /// ////////////////////////////////////////////////////////////////////////////////// if(!texp.IsNull()) texp->ApplyTexture(); // Вычислим какая часть нашей текстуры будет заполнена пустым пространством. // Мы рисуем только ту часть текстуры, в которой находится символ, и сохраняем // информацию в переменных x и y, затем, когда мы рисуем четырехугольник, // мы будем только ссылаться на ту часть текстуры, в которой непосредственно // содержится символ. nReal x = static_cast<nReal>(letter.GetBitmapw()) / static_cast<nReal>(letter.GetWidth()), y = static_cast<nReal>(letter.GetBitmapr()) / static_cast<nReal>(letter.GetHeight()); //glBindTexture(GL_TEXTURE_2D, let.GetTex()); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2i(0,0); glTexCoord2f(0,y); glVertex2i(0,letter.GetBitmapr()); glTexCoord2f(x,y); glVertex2i(letter.GetBitmapw(), letter.GetBitmapr()); glTexCoord2f(x,0); glVertex2i(letter.GetBitmapw(), 0); glEnd(); /// Завершаем дисплейный список ////////////////////////////////////////////////// letter.GetDispList().EndList(); /// ////////////////////////////////////////////////////////////////////////////// letters_map[code] = letter; }
void CShaderProgram::BindTexture(texture_id_t id, CTexturePtr tex) { BindTexture(id, tex->GetHandle()); }
void SlowPlayerColorRender::PrepareTexture(int pass, CTexturePtr& texture) { if (pass == 1) texture->Bind(1); texture->Bind(0); }
void FastPlayerColorRender::PrepareTexture(int UNUSED(pass), CTexturePtr& texture) { texture->Bind(2); texture->Bind(1); texture->Bind(0); }
void TransparentDepthShadowModifier::PrepareTexture(int UNUSED(pass), CTexturePtr& texture) { texture->Bind(0); }
void TransparentBlendRenderModifier::PrepareTexture(int UNUSED(pass), CTexturePtr& texture) { texture->Bind(0); }