Проблема в том, что я пытаюсь нарисовать строку на экране, используя растровую текстуру, ее длина ограничена тем, с чем она была инициализирована, даже когда я обновляю строку в цикле рендеринга.
Я пытаюсь реализоватьпростой рендеринг шрифтов с использованием растровых текстур, я до сих пор успешно отображал глиф из растровых текстур, я пытался инициализировать с различной длиной строки, но проблема сохраняется.
Я подозреваю, что vertexBufferDesc.ByteWidth
не обновляется для исправления обновленной длины строки, когда я динамически обновляю буфер вершин с помощью функции map и unmap.
bool GlyphClass::Initialize(ID3D11Device* device, HWND hwnd, int screenWidth, int screenHeight, WCHAR* path)
{
bool result;
m_GlyphWidthData.open("Font/AgencyFBFont_64x64_width.txt");
while (1)
{
if (m_GlyphWidthData.eof())
{
break;
}
int tmp = 0;
m_GlyphWidthData >> tmp;
if (tmp != 0)
{
m_GlyphWidth.push_back(tmp);
}
}
m_GlyphWidthData.close();
m_GlyphCharacter = 'A';
m_StringToDraw = "TEXTTEST@xyz";//
m_fontTextureShader = new TextureShaderClass;
if (!m_fontTextureShader)
{
return false;
}
result = m_fontTextureShader->Initialize(device, hwnd);
if (!result)
{
MessageBox(hwnd, L"Could not initialize font texture shader object!", L"Error", MB_OK);
return false;
}
m_ScreenWidth = screenWidth;
m_ScreenHeight = screenHeight;
result = InitializeBuffers(device);
if (!result)
{
return false;
}
result = LoadTexture(device, path);
if (!result)
{
return false;
}
return true;
}
bool GlyphClass::InitializeBuffers(ID3D11Device* device)
{
VertexType* vertices;
unsigned long* indices;
D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
D3D11_SUBRESOURCE_DATA vertexData, indexData;
HRESULT result;
int i;
m_VertexCount = 6;
m_IndexCount = m_VertexCount * m_MaxCharInLine;
vertices = new VertexType[m_VertexCount];
if (!vertices)
{
return false;
}
indices = new unsigned long[m_IndexCount];
if (!indices)
{
return false;
}
memset(vertices, 0, sizeof(VertexType) * m_VertexCount);
for (i = 0; i < m_IndexCount; i++)
{
indices[i] = i;
}
vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_VertexCount * m_StringToDraw.length();
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;
vertexData.pSysMem = vertices;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;
result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_VertexBuffer);
if (FAILED(result))
{
return false;
}
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_IndexCount;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
indexBufferDesc.StructureByteStride = 0;
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_IndexBuffer);
if (FAILED(result))
{
return false;
}
delete[] vertices;
vertices = 0;
delete[] indices;
indices = 0;
return true;
}
bool GlyphClass::UpdateBuffers(ID3D11DeviceContext* context, int posX, int posY)
{
m_StringToDraw = userInputString != "" ? userInputString : "STRING 555@xyz0123456789";
VertexType* vertices;
D3D11_MAPPED_SUBRESOURCE mappedResource;
VertexType* vertexPtr;
HRESULT hr;
vertices = new VertexType[m_VertexCount * m_StringToDraw.length()];
if (!vertices)
{
return false;
}
// Initialize vertex array to zeros at first.
memset(vertices, 0, sizeof(VertexType) * m_VertexCount * m_StringToDraw.length() );
float posXOffset = (float)posX;
float posYOffset = (float)posY;
for ( int i = 0; i < m_StringToDraw.length(); i++ )
{
int cx = m_StringToDraw[i] % 16;
int cy = m_StringToDraw[i] / 16;
float tex_left = (float)cx * (1.f / 16.f);
float tex_top = (float)cy * (1.f / 16.f);
float tex_right = tex_left + (1.f / 16.f) * ((float)m_GlyphWidth[m_StringToDraw[i]] / 64.f);
float tex_bottom = tex_top + (1.f / 16.f);
int totalCharWidth = 64;
float left = (float)((float)(m_ScreenWidth / 2.f) * -1) + posXOffset;
float right = left + (float)m_GlyphWidth[m_StringToDraw[i]];
float top = (float)(m_ScreenHeight / 2.f) - posYOffset;
float bottom = top - (float)totalCharWidth;
//triangle 1 - clockwise
vertices[0 + m_VertexCount * i].position = Vector3(left, top, 0.f);
vertices[0 + m_VertexCount * i].texture = Vector2(tex_left, tex_top);
vertices[1 + m_VertexCount * i].position = Vector3(right, bottom, 0.f);
vertices[1 + m_VertexCount * i].texture = Vector2(tex_right, tex_bottom);
vertices[2 + m_VertexCount * i].position = Vector3(left, bottom, 0.f);
vertices[2 + m_VertexCount * i].texture = Vector2(tex_left, tex_bottom);
//triangle + i 2
vertices[3 + m_VertexCount * i].position = Vector3(left, top, 0.f);
vertices[3 + m_VertexCount * i].texture = Vector2(tex_left, tex_top);
vertices[4 + m_VertexCount * i].position = Vector3(right, top, 0.f);
vertices[4 + m_VertexCount * i].texture = Vector2(tex_right, tex_top);
vertices[5 + m_VertexCount * i].position = Vector3(right, bottom, 0.f);
vertices[5 + m_VertexCount * i].texture = Vector2(tex_right, tex_bottom);
posXOffset += m_GlyphWidth[m_StringToDraw[i]];
}
hr = context->Map(m_VertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(hr))
{
return false;
}
vertexPtr = (VertexType*)mappedResource.pData;
int bufferSize = sizeof(VertexType) * m_VertexCount * m_StringToDraw.length();
memcpy(vertexPtr, (void*)vertices, bufferSize);
D3D11_BUFFER_DESC tmpDesc;
m_VertexBuffer->GetDesc(&tmpDesc);
context->Unmap(m_VertexBuffer, 0);
delete[] vertices;
vertices = 0;
return true;
}
строка m_StringToDraw должна измениться, и вершинный буфер должен нарисоватьвсе обновленные строки