C++ FreeType生成多个纹理
我试图在DirectX 11下使用FreeType,以便在屏幕上绘制一些文本。目前,我能够将FT\u位图*转换为ID3D11Texture2D*,然后创建一个ID3D11ShaderResourceView* 然后,我使用着色器绘制此着色器资源视图。问题是这段代码只画了文本的最后一个字母4次,我真的不明白为什么 首先,以下是如何呈现UI元素: 图表.cpp:C++ FreeType生成多个纹理,c++,directx,directx-11,freetype,C++,Directx,Directx 11,Freetype,我试图在DirectX 11下使用FreeType,以便在屏幕上绘制一些文本。目前,我能够将FT\u位图*转换为ID3D11Texture2D*,然后创建一个ID3D11ShaderResourceView* 然后,我使用着色器绘制此着色器资源视图。问题是这段代码只画了文本的最后一个字母4次,我真的不明白为什么 首先,以下是如何呈现UI元素: 图表.cpp: void Graph::DrawSprite(Object* p_object) { /*...*/ // Problem he
void Graph::DrawSprite(Object* p_object)
{
/*...*/
// Problem here
Text* text = nullptr;
text = p_object->GetComponent<Text>();
if (text)
_graphicAPI->Draw(text->GetBuffer());
/*...*/
}
bool FontManager::LoadFont(ID3D11Device* p_device, const std::string p_extension, const char* p_fileName)
{
if (p_extension == ".ttf")
{
Font* font = new Font();
if (!font)
return false;
if (!font->LoadTTF(p_device, _library, p_fileName))
{
delete font;
return false;
}
// sets text (tmp)
font->RenderFont(p_device, "ASDASD", Math::Vec2(100, 100));
_fonts.push_back(font);
return true;
}
return false;
}
bool Font::LoadTTF(ID3D11Device* p_device, FT_Library p_library, const char* p_fileName)
{
_fileName = p_fileName;
if (FT_New_Face(p_library, p_fileName, 0, &_face))
return false;
if (FT_Set_Pixel_Sizes(_face, 0, DEFAULT_FONT_SIZE))
return false;
return true;
}
void Font::RenderFont(ID3D11Device* p_device, const char* p_text, Math::Vec2 p_position)
{
FT_GlyphSlot slot = _face->glyph;
FT_Vector pen;
pen.x = p_position._x;
pen.y = p_position._y;
FT_Matrix matrix;
float angle = (/*90*/0.0 / 360) * 3.14159 * 2;
matrix.xx = (FT_Fixed)(cos(angle) * 0x10000L);
matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L);
matrix.yx = (FT_Fixed)(sin(angle) * 0x10000L);
matrix.yy = (FT_Fixed)(cos(angle) * 0x10000L);
for (unsigned int i = 0; i < strlen(p_text); ++i)
{
FT_Set_Transform(_face, &matrix, &pen);
if (FT_Load_Char(_face, p_text[i], FT_LOAD_RENDER))
continue;
if (!CreateShaderResourceView(p_device, &slot->bitmap))
return;
// Increment pen position
pen.x += slot->advance.x >> 6;
}
}
bool Font::CreateShaderResourceView(ID3D11Device* p_device, FT_Bitmap* p_bitmap)
{
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = p_bitmap->width;
textureDesc.Height = p_bitmap->rows;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
textureDesc.MiscFlags = 0;
ID3D11Texture2D* texture2D;
ZeroMemory(&texture2D, sizeof(texture2D));
D3D11_SUBRESOURCE_DATA resourceData;
resourceData.pSysMem = p_bitmap->buffer;
resourceData.SysMemPitch = p_bitmap->pitch;
resourceData.SysMemSlicePitch = 0;
HRESULT res = p_device->CreateTexture2D(&textureDesc, &resourceData, &texture2D);
if (FAILED(res))
return false;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
HRESULT result = p_device->CreateShaderResourceView(texture2D, &shaderResourceViewDesc, &_shaderResourceView);
if (FAILED(result))
return false;
return true;
}
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
PixelInputType SpriteVertexShader(VertexInputType input)
{
PixelInputType output;
input.position.w = 1.0f;
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.tex = input.tex;
return output;
}
SpriteShader.cpp:
bool SpriteShader::Render(ID3D11DeviceContext* p_deviceContext, unsigned int p_indexCount, ID3D11ShaderResourceView* p_texView,
const Math::Mat4& p_matrix, const CameraBuffer& p_camera)
{
bool result = SetShaderParameters(p_deviceContext, p_texView, p_matrix, p_camera._view, p_camera._projection);
if (!result)
return false;
RenderShader(p_deviceContext, p_indexCount);
return true;
}
bool SpriteShader::SetShaderParameters(ID3D11DeviceContext* p_deviceContext, ID3D11ShaderResourceView* p_texView,
const Math::Mat4& p_worldMatrix, const Math::Mat4& p_viewMatrix, const Math::Mat4& p_projectionMatrix)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
unsigned int bufferNumber;
MatrixBufferType* dataMatrixPtr;
result = p_deviceContext->Map(_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
return false;
dataMatrixPtr = (MatrixBufferType*)mappedResource.pData;
dataMatrixPtr->world = p_worldMatrix;
dataMatrixPtr->view = p_viewMatrix;
dataMatrixPtr->projection = p_projectionMatrix;
p_deviceContext->Unmap(_matrixBuffer, 0);
bufferNumber = 0;
p_deviceContext->VSSetConstantBuffers(bufferNumber, 1, &_matrixBuffer);
p_deviceContext->PSSetShaderResources(0, 1, &p_texView);
return true;
}
void SpriteShader::RenderShader(ID3D11DeviceContext* p_deviceContext, unsigned int p_indexCount)
{
p_deviceContext->IASetInputLayout(_layout);
p_deviceContext->VSSetShader(_vertexShader, NULL, 0);
p_deviceContext->PSSetShader(_pixelShader, NULL, 0);
p_deviceContext->PSSetSamplers(0, 1, &_sampleState);
p_deviceContext->DrawIndexed(p_indexCount, 0, 0);
}
下面是如何加载TTF字体并将其转换为ID3D11ShaderResourceView*
FontManager.cpp:
void Graph::DrawSprite(Object* p_object)
{
/*...*/
// Problem here
Text* text = nullptr;
text = p_object->GetComponent<Text>();
if (text)
_graphicAPI->Draw(text->GetBuffer());
/*...*/
}
bool FontManager::LoadFont(ID3D11Device* p_device, const std::string p_extension, const char* p_fileName)
{
if (p_extension == ".ttf")
{
Font* font = new Font();
if (!font)
return false;
if (!font->LoadTTF(p_device, _library, p_fileName))
{
delete font;
return false;
}
// sets text (tmp)
font->RenderFont(p_device, "ASDASD", Math::Vec2(100, 100));
_fonts.push_back(font);
return true;
}
return false;
}
bool Font::LoadTTF(ID3D11Device* p_device, FT_Library p_library, const char* p_fileName)
{
_fileName = p_fileName;
if (FT_New_Face(p_library, p_fileName, 0, &_face))
return false;
if (FT_Set_Pixel_Sizes(_face, 0, DEFAULT_FONT_SIZE))
return false;
return true;
}
void Font::RenderFont(ID3D11Device* p_device, const char* p_text, Math::Vec2 p_position)
{
FT_GlyphSlot slot = _face->glyph;
FT_Vector pen;
pen.x = p_position._x;
pen.y = p_position._y;
FT_Matrix matrix;
float angle = (/*90*/0.0 / 360) * 3.14159 * 2;
matrix.xx = (FT_Fixed)(cos(angle) * 0x10000L);
matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L);
matrix.yx = (FT_Fixed)(sin(angle) * 0x10000L);
matrix.yy = (FT_Fixed)(cos(angle) * 0x10000L);
for (unsigned int i = 0; i < strlen(p_text); ++i)
{
FT_Set_Transform(_face, &matrix, &pen);
if (FT_Load_Char(_face, p_text[i], FT_LOAD_RENDER))
continue;
if (!CreateShaderResourceView(p_device, &slot->bitmap))
return;
// Increment pen position
pen.x += slot->advance.x >> 6;
}
}
bool Font::CreateShaderResourceView(ID3D11Device* p_device, FT_Bitmap* p_bitmap)
{
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = p_bitmap->width;
textureDesc.Height = p_bitmap->rows;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
textureDesc.MiscFlags = 0;
ID3D11Texture2D* texture2D;
ZeroMemory(&texture2D, sizeof(texture2D));
D3D11_SUBRESOURCE_DATA resourceData;
resourceData.pSysMem = p_bitmap->buffer;
resourceData.SysMemPitch = p_bitmap->pitch;
resourceData.SysMemSlicePitch = 0;
HRESULT res = p_device->CreateTexture2D(&textureDesc, &resourceData, &texture2D);
if (FAILED(res))
return false;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
HRESULT result = p_device->CreateShaderResourceView(texture2D, &shaderResourceViewDesc, &_shaderResourceView);
if (FAILED(result))
return false;
return true;
}
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
PixelInputType SpriteVertexShader(VertexInputType input)
{
PixelInputType output;
input.position.w = 1.0f;
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.tex = input.tex;
return output;
}
对于字体类,我基于教程。CreateShaderResourceView()是我的绘图位图()
Font.cpp:
void Graph::DrawSprite(Object* p_object)
{
/*...*/
// Problem here
Text* text = nullptr;
text = p_object->GetComponent<Text>();
if (text)
_graphicAPI->Draw(text->GetBuffer());
/*...*/
}
bool FontManager::LoadFont(ID3D11Device* p_device, const std::string p_extension, const char* p_fileName)
{
if (p_extension == ".ttf")
{
Font* font = new Font();
if (!font)
return false;
if (!font->LoadTTF(p_device, _library, p_fileName))
{
delete font;
return false;
}
// sets text (tmp)
font->RenderFont(p_device, "ASDASD", Math::Vec2(100, 100));
_fonts.push_back(font);
return true;
}
return false;
}
bool Font::LoadTTF(ID3D11Device* p_device, FT_Library p_library, const char* p_fileName)
{
_fileName = p_fileName;
if (FT_New_Face(p_library, p_fileName, 0, &_face))
return false;
if (FT_Set_Pixel_Sizes(_face, 0, DEFAULT_FONT_SIZE))
return false;
return true;
}
void Font::RenderFont(ID3D11Device* p_device, const char* p_text, Math::Vec2 p_position)
{
FT_GlyphSlot slot = _face->glyph;
FT_Vector pen;
pen.x = p_position._x;
pen.y = p_position._y;
FT_Matrix matrix;
float angle = (/*90*/0.0 / 360) * 3.14159 * 2;
matrix.xx = (FT_Fixed)(cos(angle) * 0x10000L);
matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L);
matrix.yx = (FT_Fixed)(sin(angle) * 0x10000L);
matrix.yy = (FT_Fixed)(cos(angle) * 0x10000L);
for (unsigned int i = 0; i < strlen(p_text); ++i)
{
FT_Set_Transform(_face, &matrix, &pen);
if (FT_Load_Char(_face, p_text[i], FT_LOAD_RENDER))
continue;
if (!CreateShaderResourceView(p_device, &slot->bitmap))
return;
// Increment pen position
pen.x += slot->advance.x >> 6;
}
}
bool Font::CreateShaderResourceView(ID3D11Device* p_device, FT_Bitmap* p_bitmap)
{
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = p_bitmap->width;
textureDesc.Height = p_bitmap->rows;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
textureDesc.MiscFlags = 0;
ID3D11Texture2D* texture2D;
ZeroMemory(&texture2D, sizeof(texture2D));
D3D11_SUBRESOURCE_DATA resourceData;
resourceData.pSysMem = p_bitmap->buffer;
resourceData.SysMemPitch = p_bitmap->pitch;
resourceData.SysMemSlicePitch = 0;
HRESULT res = p_device->CreateTexture2D(&textureDesc, &resourceData, &texture2D);
if (FAILED(res))
return false;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
HRESULT result = p_device->CreateShaderResourceView(texture2D, &shaderResourceViewDesc, &_shaderResourceView);
if (FAILED(result))
return false;
return true;
}
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
PixelInputType SpriteVertexShader(VertexInputType input)
{
PixelInputType output;
input.position.w = 1.0f;
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.tex = input.tex;
return output;
}
精灵vs:
void Graph::DrawSprite(Object* p_object)
{
/*...*/
// Problem here
Text* text = nullptr;
text = p_object->GetComponent<Text>();
if (text)
_graphicAPI->Draw(text->GetBuffer());
/*...*/
}
bool FontManager::LoadFont(ID3D11Device* p_device, const std::string p_extension, const char* p_fileName)
{
if (p_extension == ".ttf")
{
Font* font = new Font();
if (!font)
return false;
if (!font->LoadTTF(p_device, _library, p_fileName))
{
delete font;
return false;
}
// sets text (tmp)
font->RenderFont(p_device, "ASDASD", Math::Vec2(100, 100));
_fonts.push_back(font);
return true;
}
return false;
}
bool Font::LoadTTF(ID3D11Device* p_device, FT_Library p_library, const char* p_fileName)
{
_fileName = p_fileName;
if (FT_New_Face(p_library, p_fileName, 0, &_face))
return false;
if (FT_Set_Pixel_Sizes(_face, 0, DEFAULT_FONT_SIZE))
return false;
return true;
}
void Font::RenderFont(ID3D11Device* p_device, const char* p_text, Math::Vec2 p_position)
{
FT_GlyphSlot slot = _face->glyph;
FT_Vector pen;
pen.x = p_position._x;
pen.y = p_position._y;
FT_Matrix matrix;
float angle = (/*90*/0.0 / 360) * 3.14159 * 2;
matrix.xx = (FT_Fixed)(cos(angle) * 0x10000L);
matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L);
matrix.yx = (FT_Fixed)(sin(angle) * 0x10000L);
matrix.yy = (FT_Fixed)(cos(angle) * 0x10000L);
for (unsigned int i = 0; i < strlen(p_text); ++i)
{
FT_Set_Transform(_face, &matrix, &pen);
if (FT_Load_Char(_face, p_text[i], FT_LOAD_RENDER))
continue;
if (!CreateShaderResourceView(p_device, &slot->bitmap))
return;
// Increment pen position
pen.x += slot->advance.x >> 6;
}
}
bool Font::CreateShaderResourceView(ID3D11Device* p_device, FT_Bitmap* p_bitmap)
{
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = p_bitmap->width;
textureDesc.Height = p_bitmap->rows;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
textureDesc.MiscFlags = 0;
ID3D11Texture2D* texture2D;
ZeroMemory(&texture2D, sizeof(texture2D));
D3D11_SUBRESOURCE_DATA resourceData;
resourceData.pSysMem = p_bitmap->buffer;
resourceData.SysMemPitch = p_bitmap->pitch;
resourceData.SysMemSlicePitch = 0;
HRESULT res = p_device->CreateTexture2D(&textureDesc, &resourceData, &texture2D);
if (FAILED(res))
return false;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
HRESULT result = p_device->CreateShaderResourceView(texture2D, &shaderResourceViewDesc, &_shaderResourceView);
if (FAILED(result))
return false;
return true;
}
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
PixelInputType SpriteVertexShader(VertexInputType input)
{
PixelInputType output;
input.position.w = 1.0f;
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.tex = input.tex;
return output;
}
以下是我得到的:
这家伙()也有同样的问题,但解决方案对我不起作用。有人知道如何解决这个问题吗?我已经在这上面呆了一个星期了…似乎在
for(unsigned int I=0;I
的内部,您尝试逐字母渲染字体,并在每次迭代时重新创建着色器资源视图。因此,在最后,您将看到包含最后一个字母纹理视图的着色器资源视图。谢谢^^^,我还必须通过此textureDesc.Width=p_bitmap->Width更改textureDesc.Width值代码>