Related
My DirectX application does not render the texture correctly. Result:
Expected from VS editor:
As you can see the cat texture is not completely drawn.
I 'm using WaveFrontReader to load the .OBJ and the .MTL files and WicTextureLoader to load the PNG/JPG.
My HLSL:
cbuffer constants : register(b0)
{
row_major float4x4 transform;
row_major float4x4 projection;
float3 lightvector;
}
struct vs_in
{
float3 position : POS;
float3 normal : NOR;
float2 texcoord : TEX;
float4 color : COL;
};
struct vs_out
{
float4 position : SV_POSITION;
float2 texcoord : TEX;
float4 color : COL;
};
Texture2D mytexture : register(t0);
SamplerState mysampler : register(s0);
vs_out vs_main(vs_in input)
{
float light = clamp(dot(normalize(mul(float4(input.normal, 0.0f), transform).xyz), normalize(-lightvector)), 0.0f, 1.0f) * 0.8f + 0.2f;
vs_out output;
output.position = mul(float4(input.position, 1.0f), mul(transform, projection));
output.texcoord = input.texcoord;
output.color = float4(input.color.rgb * light, input.color.a);
return output;
}
float4 ps_main(vs_out input) : SV_TARGET
{
return mytexture.Sample(mysampler, input.texcoord) * input.color;
}
My preparation:
void Config3DWindow()
{
const wchar_t* tf = L"1.hlsl";
d2d.m_swapChain1->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&frameBuffer));
d2d.device->CreateRenderTargetView(frameBuffer, nullptr, &frameBufferView);
frameBuffer->GetDesc(&depthBufferDesc); // base on framebuffer properties
depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
CComPtr<ID3DBlob> vsBlob;
D3DCompileFromFile(tf, nullptr, nullptr, "vs_main", "vs_5_0", 0, 0, &vsBlob, nullptr);
d2d.device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &vertexShader);
D3D11_INPUT_ELEMENT_DESC inputElementDesc[] =
{
{ "POS", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEX", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
d2d.device->CreateInputLayout(inputElementDesc, ARRAYSIZE(inputElementDesc), vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &inputLayout);
///////////////////////////////////////////////////////////////////////////////////////////////
CComPtr<ID3DBlob> psBlob;
D3DCompileFromFile(tf, nullptr, nullptr, "ps_main", "ps_5_0", 0, 0, &psBlob, nullptr);
d2d.device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &pixelShader);
D3D11_BUFFER_DESC constantBufferDesc = {};
constantBufferDesc.ByteWidth = sizeof(Constants) + 0xf & 0xfffffff0;
constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
d2d.device->CreateBuffer(&constantBufferDesc, nullptr, &constantBuffer);
}
Loading the obj:
WaveFrontReader<UINT> wfr;
wfr.Load(L"12221_Cat_v1_l3.oobj");
wfr.LoadMTL(L"12221_Cat_v1_l3.mtl");
obj.CreateDirect3D2(wfr);
CreateDirect3D2() function:
std::vector<float> Vertices;
// float VertexDataX[] = // float3 position, float3 normal, float2 texcoord, float4 color
auto numV = wf.vertices.size();
Vertices.resize(numV * 12);
for (size_t i = 0; i < numV; i++)
{
auto& v = wf.vertices[i];
float* i2 = Vertices.data() + (i * 12);
// position
i2[0] = v.position.x;
i2[1] = v.position.y;
i2[2] = v.position.z;
// normal
i2[3] = v.normal.x;
i2[4] = v.normal.y;
i2[5] = v.normal.z;
// tx
i2[6] = v.textureCoordinate.x;
i2[7] = v.textureCoordinate.y;
// Colors
i2[8] = 1.0f;
i2[9] = 1.0f;
i2[10] = 1.0f;
i2[11] = 1.0f;
}
D3D11_BUFFER_DESC vertexBufferDesc = {};
vertexBufferDesc.ByteWidth = Vertices.size() * sizeof(float);
vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA vertexData = { Vertices.data() }; // in data.h
vertexBuffer = 0;
d2d.device->CreateBuffer(&vertexBufferDesc, &vertexData, &vertexBuffer);
// Indices
std::vector<UINT>& Indices = wf.indices;
D3D11_BUFFER_DESC indexBufferDesc = {};
IndicesSize = Indices.size() * sizeof(UINT);
indexBufferDesc.ByteWidth = IndicesSize;
indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
D3D11_SUBRESOURCE_DATA indexData = { Indices.data() }; // in data.h
indexBuffer = 0;
d2d.device->CreateBuffer(&indexBufferDesc, &indexData, &indexBuffer);
for (auto& ma : wf.materials)
{
CComPtr<ID3D11Resource> tex;
CComPtr<ID3D11ShaderResourceView> texv;
CreateWICTextureFromFile(d2d.device, d2d.context, ma.strTexture, &tex, &texv,0);
if (tex && texv)
{
OBJFT ot;
ot.texture = tex;
ot.textureView = texv;
textures.push_back(ot);
}
tex = 0;
texv = 0;
}
The drawing function:
void Present(OBJF& o, int Count, _3DP& _3, D2D1_COLOR_F bcol)
{
float w = static_cast<float>(depthBufferDesc.Width); // width
float h = static_cast<float>(depthBufferDesc.Height); // height
float n = 1000.0f; // near
float f = 1000000.0f; // far
matrix rotateX = { 1, 0, 0, 0, 0, static_cast<float>(cos(_3.rotation[0])), -static_cast<float>(sin(_3.rotation[0])), 0, 0, static_cast<float>(sin(_3.rotation[0])), static_cast<float>(cos(_3.rotation[0])), 0, 0, 0, 0, 1 };
matrix rotateY = { static_cast<float>(cos(_3.rotation[1])), 0, static_cast<float>(sin(_3.rotation[1])), 0, 0, 1, 0, 0, -static_cast<float>(sin(_3.rotation[1])), 0, static_cast<float>(cos(_3.rotation[1])), 0, 0, 0, 0, 1 };
matrix rotateZ = { static_cast<float>(cos(_3.rotation[2])), -static_cast<float>(sin(_3.rotation[2])), 0, 0, static_cast<float>(sin(_3.rotation[2])), static_cast<float>(cos(_3.rotation[2])), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
matrix scale = { _3.scale[0], 0, 0, 0, 0, _3.scale[1], 0, 0, 0, 0, _3.scale[2], 0, 0, 0, 0, 1 };
matrix translate = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, _3.translation[0], _3.translation[1], _3.translation[2], 1 };
///////////////////////////////////////////////////////////////////////////////////////////
D3D11_MAPPED_SUBRESOURCE mappedSubresource = {};
d2d.context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubresource);
Constants* constants = reinterpret_cast<Constants*>(mappedSubresource.pData);
constants->Transform = rotateX * rotateY * rotateZ * scale * translate;
constants->Projection = { 2 * n / w, 0, 0, 0, 0, 2 * n / h, 0, 0, 0, 0, f / (f - n), 1, 0, 0, n * f / (n - f), 0 };
constants->LightVector = { 1.0f, 1.0f, 1.0f };
d2d.context->Unmap(constantBuffer, 0);
///////////////////////////////////////////////////////////////////////////////////////////
FLOAT backgroundColor[4] = { 0.00f, 0.00f, 0.00f, 1.0f };
if (bcol.a > 0)
{
backgroundColor[0] = bcol.r;
backgroundColor[1] = bcol.g;
backgroundColor[2] = bcol.b;
backgroundColor[3] = bcol.a;
}
UINT stride = 12 * 4; // vertex size (12 floats: float3 position, float3 normal, float2 texcoord, float4 color)
UINT offset = 0;
D3D11_VIEWPORT viewport = { 0.0f, 0.0f, w, h, 0.0f, 1.0f };
///////////////////////////////////////////////////////////////////////////////////////////
auto deviceContext = d2d.context;
deviceContext->ClearRenderTargetView(frameBufferView, backgroundColor);
deviceContext->ClearDepthStencilView(depthBufferView, D3D11_CLEAR_DEPTH, 1.0f, 0);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
deviceContext->IASetInputLayout(inputLayout);
deviceContext->IASetVertexBuffers(0, 1, &o.vertexBuffer.p, &stride, &offset);
deviceContext->IASetIndexBuffer(o.indexBuffer, DXGI_FORMAT_R32_UINT, 0);
deviceContext->VSSetShader(vertexShader, nullptr, 0);
deviceContext->VSSetConstantBuffers(0, 1, &constantBuffer.p);
deviceContext->RSSetViewports(1, &viewport);
deviceContext->PSSetShader(pixelShader, nullptr, 0);
std::vector<ID3D11ShaderResourceView*> rsx;
for (auto& t : o.textures)
rsx.push_back(t.textureView);
ID3D11ShaderResourceView** rr = rsx.data();
deviceContext->PSSetShaderResources(0, rsx.size(), rr);
deviceContext->PSSetSamplers(0, 1, &samplerState.p);
deviceContext->OMSetRenderTargets(1, &frameBufferView.p, depthBufferView);
deviceContext->OMSetDepthStencilState(depthStencilState, 0);
///////////////////////////////////////////////////////////////////////////////////////////
DXGI_RGBA ra = { 1,1,1,1 };
deviceContext->DrawIndexed(o.IndicesSize, 0, 0);
d2d.m_swapChain1->Present(1, 0);
}
Entire project here: https://drive.google.com/open?id=1BbW3DUd20bAwei4KjnkUPwgm5Ia1aRxl
This is what I got after I was able to reproduce the issue of OP on my side:
My only change was that I exluded lighting in the shader code:
vs_out vs_main(vs_in input)
{
float light = 1.0f;
//float light = clamp(dot(normalize(mul(float4(input.normal, 0.0f), transform).xyz), normalize(-lightvector)), 0.0f, 1.0f) * 0.8f + 0.2f;
vs_out output;
output.position = mul(float4(input.position, 1.0f), mul(transform, projection));
output.texcoord = input.texcoord;
output.color = float4(input.color.rgb * light, input.color.a);
return output;
}
Then I became aware of the cat's eye on the cat's tail.
That reminded me that a lot of image formats store the image from top to down.
OpenGL textures (and probably Direct3D as well) has usually the origin in the lower left corner. Hence, it's not un-usual that texture images are mirrored vertically (during or after loading the image from file and before sending it to GPU).
To prove my suspicion, I mirrored the image manually (in GIMP) and then (without re-compiling) got this:
It looks like my suspicion was right.
Something is wrong with the image or texture loading in the loader of OP.
I'm drawing sprites that are all in a buffer using glDrawElements.
To tell sprites what texture to be in the fragment shader I have uniform sampler2D textures[32]; each vertex has an index, which is passed to the fragment shader from the vertex shader:
color = texture(textures[index], fs_in.uv);
when I try draw my sprites with more than 1 texture active it gets the wrong textures in the top right corner
http://puu.sh/lyr5j/d8c2cf6c8f.png
I have no clue why this is happening have tried texture parameters
I cant seem to find anyone who has had a similar problem.
This is my renderer's init function (I am purposly passing the texid as float since I have heard ints don't work well (also tried))
glGenBuffers(1, &m_VDBO);
glGenVertexArrays(1, &m_VAO);
glBindVertexArray(m_VAO);
glBindBuffer(GL_ARRAY_BUFFER, m_VDBO);
glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
glEnableVertexAttribArray(SHADER_UV_INDEX);
glEnableVertexAttribArray(SHADER_COLOR_INDEX);
glEnableVertexAttribArray(SHADER_TEXID_INDEX);
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::vertex));
glVertexAttribPointer(SHADER_UV_INDEX, 2, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::uv));
glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::color));
glVertexAttribPointer(SHADER_TEXID_INDEX, 1, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *)offsetof(VertexData, VertexData::texID));
glBindBuffer(GL_ARRAY_BUFFER, 0);
const GLushort modelindices[] = { 0, 1, 2, 2, 3, 0 };
GLuint indices[RENDERER_INDICES_SIZE];
for (int i = 0; i < RENDERER_INDICES_SIZE; i += 6)
{
for (int o = 0; o < 6; o++)
{
indices[i + o] = modelindices[o] + (i / 6 * 4);
}
}
glGenBuffers(1, &m_IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, RENDERER_INDICES_SIZE * sizeof(GLuint), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
the flush function
glBindVertexArray(m_VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
for (int i = 0; i < m_TextureSlots.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, m_TextureSlots[i]);
}
glDrawElements(GL_TRIANGLES, m_IndexCount, GL_UNSIGNED_INT, 0);
m_TextureSlots.clear();
m_IndexCount = 0;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
It is hard for me to see where your problem is coming from, the only thing I can suggest is taking a look at an Image2d class object constructor that I have. Now, my source depends on outside classes such as a ShaderManager class that relies heavily on template types and a Batch class and a BatchManager class to send over the vertices to the video card. Also this Image2d is an inherited object. However, this may serve as some help to you in tracking down your own problem. There are two different constructors for different versions of the implementation depending on which version of OpenGL and GLSL is being used. If I remember correctly version 2 uses the BatchManager to send the vertices to the video card where version 1 doesn't which can be seen within the render() method.
Image2d v1.0
// ----------------------------------------------------------------------------
// Image2d()
Image2d::Image2d( float fWidth, float fHeight, TextureInfo::FilterQuality filterQuality, bool generateMipMap, const std::string& strTextureFilename, const std::string& strId ) :
VisualMko( glm::uvec2(), strId ),
m_vboTexture( 0 ),
m_vboPosition( 0 ),
m_vboIndices( 0 ),
m_vao( 0 ) {
if ( fWidth <= 0 || fHeight <= 0 ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Invalid image size (" << fWidth << "," << fHeight << ") must be more then 0 in each dimension.";
throw ExceptionHandler( strStream );
}
// Save TextureId
TextureFileReader textureFileReader( strTextureFilename );
m_textureInfo = textureFileReader.getOrCreateTextureInfo( filterQuality, generateMipMap, false );
// Define Texture Co-Ordinates
std::vector<float> vTextureCoordinates;
vTextureCoordinates.push_back( 0.0f );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 0 );
vTextureCoordinates.push_back( 0 );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 0 );
// Define Vertex Positions (x,y,z)
std::vector<float> vVertexPositions;
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( fHeight );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( fWidth );
vVertexPositions.push_back( fHeight );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( fWidth );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
// Define 2 Triangle Faces
std::vector<unsigned char> vIndices;
vIndices.push_back( 0 );
vIndices.push_back( 1 );
vIndices.push_back( 2 );
vIndices.push_back( 3 );
// Create Vertex Array Object
glGenVertexArrays( 1, &m_vao );
glBindVertexArray( m_vao ); // Start Array
m_pShaderManager->setAttribute( A_COLOR, COLOR_WHITE );
// Create Position Buffer And Store On Video Card
glGenBuffers( 1, & m_vboPosition );
glBindBuffer( GL_ARRAY_BUFFER, m_vboPosition );
glBufferData( GL_ARRAY_BUFFER, vVertexPositions.size() * sizeof( vVertexPositions[0] ), &vVertexPositions[0], GL_STATIC_DRAW );
m_pShaderManager->enableAttribute( A_POSITION );
// Create Texture Coordinate Buffer
glGenBuffers( 1, &m_vboTexture );
glBindBuffer( GL_ARRAY_BUFFER, m_vboTexture );
glBufferData( GL_ARRAY_BUFFER, vTextureCoordinates.size() * sizeof( vTextureCoordinates[0] ), &vTextureCoordinates[0], GL_STATIC_DRAW );
m_pShaderManager->enableAttribute( A_TEXTURE_COORD0 );
// Create Index Buffer
glGenBuffers( 1, &m_vboIndices );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_vboIndices );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vIndices.size() * sizeof( vIndices[0] ), &vIndices[0], GL_STATIC_DRAW );
glBindVertexArray( 0 ); // Stop Array
// Disable Attribute Pointers
m_pShaderManager->disableAttribute( A_POSITION );
m_pShaderManager->disableAttribute( A_TEXTURE_COORD0 );
// THIS MUST BE AFTER Vertex Array Buffer Is Unbound!
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); // Stop Buffer Index
glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Stop Buffer
// We have a Valid Image2d Save Filename
m_strFilename = strTextureFilename;
} // Image2D - v1.0
Image2D - v2.0
// ----------------------------------------------------------------------------
// Image2d()
Image2d::Image2d( const glm::uvec2& origin, const glm::uvec2& size, const std::string& strTextureFilename, const std::string& strId ) :
VisualMko( size, strId ),
m_vboTexture( 0 ),
m_vboPosition( 0 ),
m_vboIndices( 0 ),
m_vao( 0 ) {
m_version = 2;
TextureFileReader textureFileReader( strTextureFilename );
m_textureInfo = textureFileReader.getOrCreateTextureInfo( TextureInfo::FILTER_NONE, false, false );
m_config.uTextureId = m_textureInfo.uTextureId;
if ( 0 == m_textureInfo.size.x || 0 == m_textureInfo.size.y ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << "size of " << strTextureFilename << " is invalid " << m_textureInfo.size;
throw ExceptionHandler( strStream );
}
// Verify Image Fits Inside Texture
if ( m_textureInfo.size.x < size.x + origin.x || m_textureInfo.size.y < size.y + origin.y ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " " << strTextureFilename << " size is " << m_textureInfo.size
<< " which is too small for an image that is " << size
<< " pixels in size, with an origin point set at " << origin ;
throw ExceptionHandler( strStream );
}
glm::vec2 textureCoordScaleFactor( 1.0f / static_cast<float>( m_textureInfo.size.x ),
1.0f / static_cast<float>( m_textureInfo.size.y ) );
glm::vec2 textureCoordBottomLeft = glm::vec2( textureCoordScaleFactor.x * origin.x,
textureCoordScaleFactor.y * ( m_textureInfo.size.y - origin.y - size.y ) );
glm::vec2 textureCoordTopRight = glm::vec2( textureCoordScaleFactor.x * ( origin.x + size.x ),
textureCoordScaleFactor.y * ( m_textureInfo.size.y - origin.y ) );
// Set Colors And Texture Coordinates (Position Will Be Updated In Render Function)
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordBottomLeft.x, textureCoordTopRight.y ) ) );
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordBottomLeft.x, textureCoordBottomLeft.y ) ) );
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordTopRight.x, textureCoordTopRight.y ) ) );
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordTopRight.x, textureCoordBottomLeft.y ) ) );
} // Image2d - v2.0
and here is my render() method
// ----------------------------------------------------------------------------
// render()
void Image2d::render() {
if ( 1 == m_version ) {
m_pShaderManager->setTexture( 0, U_TEXTURE0_SAMPLER_2D, m_textureInfo.uTextureId );
glBindVertexArray( m_vao );
glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, nullptr );
glBindVertexArray( 0 );
} else {
// Version 2.0
// Update Vertices
if ( m_transformMatrix.updateTranslation || m_transformMatrix.updateScale || m_transformMatrix.updateRotation ) {
m_transformMatrix.updateTranslation = m_transformMatrix.updateScale = m_transformMatrix.updateRotation = false;
// Order Of Operations Matter Here!
glm::mat4 matrix; // Identity
if ( m_transformMatrix.hasTranslation ) {
matrix[3][0] = m_transformMatrix.translation.x;
matrix[3][1] = m_transformMatrix.translation.y;
}
if ( m_transformMatrix.hasRotation ) {
matrix = glm::rotate( matrix, m_transformMatrix.fRotationAngleRadians, glm::vec3( 0.0f, 0.0f, -1.0f ) );
}
if ( m_transformMatrix.hasScale ) {
matrix = matrix * glm::mat4( m_transformMatrix.scale.x, 0.0f, 0.0f, 0.0f,
0.0f, m_transformMatrix.scale.y, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f );
}
// Center Offset
if ( m_offsetPosition.x != 0 || m_offsetPosition.y != 0 ) {
matrix = glm::translate( matrix, glm::vec3( -m_offsetPosition.x, -m_offsetPosition.y, 0.0f ) );
}
// Apply Transformation To All 4 Vertices
m_vVertices[0].position = glm::vec2( matrix * glm::vec4( 0, 0, 0, 1.0f ) );
m_vVertices[1].position = glm::vec2( matrix * glm::vec4( 0, m_size.y, 0, 1.0f ) );
m_vVertices[2].position = glm::vec2( matrix * glm::vec4( m_size.x, 0, 0, 1.0f ) );
m_vVertices[3].position = glm::vec2( matrix * glm::vec4( m_size.x, m_size.y, 0, 1.0f ) );
}
renderBatch();
}
} // render
Make sure that the sizes you are specifying in your glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
is accurate. Also make sure that you are stopping your your VertexArray at the appropriate time as well as disabling your Attribute Pointers. Everything that you bound must be unbound, and for some types Order does matter!
Trying to modify the cube position with the XMMatrixTranslation function. Attached is the code...
// Rotate and modify position of cube around the origin
g_World = XMMatrixRotationY( t );
g_World = XMMatrixMultiply(g_World, XMMatrixTranslation(0, yDirection, 0));
// Modify the color
g_vMeshColor.x = ( sinf( t * 1.0f ) + 1.0f ) * 0.5f;
g_vMeshColor.y = ( cosf( t * 3.0f ) + 1.0f ) * 0.5f;
g_vMeshColor.z = ( sinf( t * 5.0f ) + 1.0f ) * 0.5f;
//
// Clear the back buffer
//
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
//
// Clear the depth buffer to 1.0 (max depth)
//
g_pImmediateContext->ClearDepthStencilView( g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );
//
// Update variables that change once per frame
//
CBChangesEveryFrame cb;
cb.mWorld = XMMatrixTranspose( g_World );
cb.vMeshColor = g_vMeshColor;
g_pImmediateContext->UpdateSubresource( g_pCBChangesEveryFrame, 0, NULL, &cb, 0, 0 );
//
// Render the cube
//
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pCBNeverChanges );
g_pImmediateContext->VSSetConstantBuffers( 1, 1, &g_pCBChangeOnResize );
g_pImmediateContext->VSSetConstantBuffers( 2, 1, &g_pCBChangesEveryFrame );
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
g_pImmediateContext->PSSetConstantBuffers( 2, 1, &g_pCBChangesEveryFrame );
g_pImmediateContext->PSSetShaderResources( 0, 1, &g_pTextureRV );
g_pImmediateContext->PSSetSamplers( 0, 1, &g_pSamplerLinear );
g_pImmediateContext->DrawIndexed( 36, 0, 0 );
//
// Present our back buffer to our front buffer
//
g_pSwapChain->Present( 0, 0 );
When I press the down button the position of the cube is supposed to change in the negative y direction. The cube disappears when the I press the key.
Thanks,
Scott
Background:
- I've been spending the last 6 weeks trying to learn Directx 11 programming.
I'm currently rendering dds images on-screen following this book
http://www.amazon.co.uk/Beginning-Directx-11-Game-Programming/dp/1435458958/ref=sr_1_1?ie=UTF8&qid=1346510304&sr=8-1
I am trying to draw 2D sprites upon a 2D background which in itself also is a 2D sprite. Problem is that these two lines
d3dDevice_->CreateBlendState( &blendDesc, &alphaBlendState_ );
d3dContext_->OMSetBlendState( alphaBlendState_, blendFactor, 0xFFFFFFFF );
to enable the alpha transparency in the dds images. I like to have the option to blend sprites but right now every sprites is blended with my blue background thus resulting in blu logos, icons etc.
How do I make the Alpha Blending ignore a specific image in directx 11?
Since the background sprite is the first to be drawn I can't activate the Blending later in the code when rendering the other sprites without every sprite turning blue.
thanks in advance :)
EDIT:
I've been working on this issue for the past 3 weeks and still no solution. Everytime the blend state is enabled in the DeviceContext is seems to apply to every texture drawn on the screen no matter the order of rendering.
Here is the source code of the header file:
class GameSpriteDemo : public Dx11DemoBase
{
public:
GameSpriteDemo( );
virtual ~GameSpriteDemo( );
bool LoadContent( );
void UnloadContent( );
void Update( float dt );
void Render( );
void DisableBlending();
ID3D11ShaderResourceView* getColorMap(int);
int UniqSpriteAmount();
// text rendering system
private:
bool DrawString( char* message, float startX, float startY );
private:
ID3D11VertexShader* solidColorVS_;
ID3D11VertexShader* solidColorVS_2;
ID3DX11Effect* effect_;
vector<ID3D11VertexShader*> solidColorVShaders;
ID3D11PixelShader* solidColorPS_;
ID3D11PixelShader* solidColorPS_2;
ID3D11InputLayout* inputLayout_;
ID3D11InputLayout* inputLayout2;
ID3D11Buffer* vertexBuffer_;
vector<ID3D11Buffer*> vertexBuffers;
ID3D11ShaderResourceView* colorMap_;
vector<ID3D11ShaderResourceView*> colorMaps;
ID3D11SamplerState* colorMapSampler_;
vector<ID3D11SamplerState*> colorSamplers;
ID3D11BlendState* alphaBlendState_;
ID3D11BlendState* alphaBlendStateOff;
vector<LPCTSTR> elements2D;
vector<GameSprite> sprites_;
ID3D11Buffer* mvpCB_;
XMMATRIX vpMatrix_;
};
#endif
Here is the source code of the cpp file: (the Base Class DxD11DemoClass is not needed since it only sets up SwapChain and D3DContext)
bool GameSpriteDemo::LoadContent( )
{
// add sprite textures to the engine, giving them index 0, 1, 2... etc.
elements2D.push_back("placeholder3.dds");
elements2D.push_back("cav.dds");
elements2D.push_back("Stats.dds");
// create sprites
XMFLOAT2 sprite1Pos( 0.0f, 500.0f);
GameSprite sprite1(getDevice(), "placeholder3.dds", 0, sprite1Pos, 0.0f);
XMFLOAT2 sprite1Scale( 0.5f, 0.5f );
XMFLOAT2 mini(0.8f, 0.6f);
sprite1.SetScale(mini);
sprites_.push_back(sprite1);
XMFLOAT2 sprite2Pos( 200.0f, 100.0f );
GameSprite sprite2(getDevice(), "Stats.dds", 2, sprite2Pos, 2.0f);
// sprites_.push_back(sprite2);
XMFLOAT2 sprite3Pos( 290.0f, 300.0f );
GameSprite sprite3(getDevice(), "cav.dds", 1, sprite3Pos, 2.0f);
sprite3.SetScale(sprite1Scale);
sprites_.push_back(sprite3);
// create vertex buffers, colorMaps and colorSamplers
for (int i = 0; i <= elements2D.size(); i++) {
solidColorVShaders.push_back(solidColorVS_);
colorMaps.push_back(colorMap_);
colorSamplers.push_back(colorMapSampler_);
vertexBuffers.push_back(vertexBuffer_);
}
// continue
ID3DBlob* vsBuffer = 0;
bool compileResult = CompileD3DShader( "TextureMap.fx", "VS_Main", "vs_4_0", &vsBuffer );
if( compileResult == false )
{
DXTRACE_MSG( "Error compiling the vertex shader!" );
return false;
}
HRESULT d3dResult;
d3dResult = d3dDevice_->CreateVertexShader( vsBuffer->GetBufferPointer( ),
vsBuffer->GetBufferSize( ), 0, &solidColorVShaders[0] );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Error creating the vertex shader!" );
if( vsBuffer )
vsBuffer->Release( );
return false;
}
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
unsigned int totalLayoutElements = ARRAYSIZE( solidColorLayout );
d3dResult = d3dDevice_->CreateInputLayout( solidColorLayout, totalLayoutElements,
vsBuffer->GetBufferPointer( ), vsBuffer->GetBufferSize( ), &inputLayout_ );
vsBuffer->Release( );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Error creating the input layout!" );
return false;
}
ID3DBlob* psBuffer = 0;
compileResult = CompileD3DShader( "TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer );
if( compileResult == false )
{
DXTRACE_MSG( "Error compiling pixel shader!" );
return false;
}
d3dResult = d3dDevice_->CreatePixelShader( psBuffer->GetBufferPointer( ),
psBuffer->GetBufferSize( ), 0, &solidColorPS_ );
psBuffer->Release( );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Error creating pixel shader!" );
return false;
}
// create ColorMap, ColorSampler and VertexBuffer for each unique sprite
D3D11_SAMPLER_DESC colorMapDesc;
D3D11_BUFFER_DESC vertexDesc;
D3D11_SUBRESOURCE_DATA resourceData;
for (int j = 0; j < elements2D.size(); j++) {
d3dResult = D3DX11CreateShaderResourceViewFromFile( d3dDevice_,
elements2D[j], 0, 0, &colorMaps[j], 0 );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Failed to load the texture image!" );
return false;
}
ZeroMemory( &colorMapDesc, sizeof( colorMapDesc ) );
colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;
d3dResult = d3dDevice_->CreateSamplerState( &colorMapDesc, &colorSamplers[j] );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Failed to create color map sampler state!" );
return false;
}
float Width = sprites_[j].getWidth();
float Height = sprites_[j].getHeight();
VertexPos vertices[] =
{
{ XMFLOAT3( Width, Height, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
{ XMFLOAT3( Width, -Height, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
{ XMFLOAT3( -Width, -Height, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
{ XMFLOAT3( -Width, -Height, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
{ XMFLOAT3( -Width, Height, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
{ XMFLOAT3( Width, Height, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
};
ZeroMemory( &vertexDesc, sizeof( vertexDesc ) );
vertexDesc.Usage = D3D11_USAGE_DEFAULT;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof( VertexPos ) * 6;
ZeroMemory( &resourceData, sizeof( resourceData ) );
resourceData.pSysMem = vertices;
d3dResult = d3dDevice_->CreateBuffer( &vertexDesc, &resourceData, &vertexBuffers[j] );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Failed to create vertex buffer!" );
return false;
}
}
// end of foor loop
// create text fonts
d3dResult = D3DX11CreateShaderResourceViewFromFile( d3dDevice_,
"font.dds", 0, 0, &colorMap_, 0 );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Failed to load the texture image!" );
return false;
}
D3D11_SAMPLER_DESC colorMapDesc2;
ZeroMemory( &colorMapDesc2, sizeof( colorMapDesc2 ) );
colorMapDesc2.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc2.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc2.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc2.ComparisonFunc = D3D11_COMPARISON_NEVER;
colorMapDesc2.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
colorMapDesc2.MaxLOD = D3D11_FLOAT32_MAX;
d3dResult = d3dDevice_->CreateSamplerState( &colorMapDesc2, &colorMapSampler_ );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Failed to create color map sampler state!" );
return false;
}
D3D11_BUFFER_DESC vertexDesc2;
ZeroMemory( &vertexDesc2, sizeof( vertexDesc2 ) );
vertexDesc2.Usage = D3D11_USAGE_DYNAMIC;
vertexDesc2.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vertexDesc2.BindFlags = D3D11_BIND_VERTEX_BUFFER;
const int sizeOfSprite = sizeof( VertexPos ) * 6;
const int maxLetters = 24;
vertexDesc2.ByteWidth = sizeOfSprite * maxLetters;
d3dResult = d3dDevice_->CreateBuffer( &vertexDesc2, 0, &vertexBuffer_ );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Failed to create vertex buffer!" );
return false;
}
// end of font creation
D3D11_BUFFER_DESC constDesc;
ZeroMemory( &constDesc, sizeof( constDesc ) );
constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constDesc.ByteWidth = sizeof( XMMATRIX );
constDesc.Usage = D3D11_USAGE_DEFAULT;
d3dResult = d3dDevice_->CreateBuffer( &constDesc, 0, &mvpCB_ );
if( FAILED( d3dResult ) )
{
return false;
}
XMMATRIX view = XMMatrixIdentity( );
XMMATRIX projection = XMMatrixOrthographicOffCenterLH( 0.0f, 1366.0f, 0.0f, 768.0f, 0.1f, 100.0f );
vpMatrix_ = XMMatrixMultiply( view, projection );
D3D11_BLEND_DESC blendDesc;
ZeroMemory( &blendDesc, sizeof( blendDesc ) );
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
d3dDevice_->CreateBlendState( &blendDesc, &alphaBlendState_ );
// create the disabled blend state
blendDesc.RenderTarget[0].BlendEnable = FALSE;
d3dDevice_->CreateBlendState( &blendDesc, &alphaBlendStateOff );
d3dContext_->OMSetBlendState( alphaBlendState_, blendFactor, 0xFFFFFFFF );
// holy shit here we go again
ID3DBlob* vsBuffer2 = 0;
compileResult = CompileD3DShader( "TextMap.fx", "VS_Main", "vs_4_0", &vsBuffer2 );
if( compileResult == false )
{
DXTRACE_MSG( "Error compiling the vertex shader!" );
return false;
}
d3dResult = d3dDevice_->CreateVertexShader( vsBuffer2->GetBufferPointer( ),
vsBuffer2->GetBufferSize( ), 0, &solidColorVS_2 );
ID3DBlob* psBuffer2 = 0;
compileResult = CompileD3DShader( "TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer2 );
if( compileResult == false )
{
DXTRACE_MSG( "Error compiling pixel shader!" );
return false;
}
d3dResult = d3dDevice_->CreatePixelShader( psBuffer2->GetBufferPointer( ),
psBuffer2->GetBufferSize( ), 0, &solidColorPS_2 );
psBuffer2->Release( );
return true;
}
void GameSpriteDemo::UnloadContent( )
{
if( colorMapSampler_ ) colorMapSampler_->Release( );
if( colorMap_ ) colorMap_->Release( );
if( solidColorVShaders[0] ) solidColorVShaders[0]->Release( );
if( solidColorPS_ ) solidColorPS_->Release( );
if( inputLayout_ ) inputLayout_->Release( );
if( vertexBuffer_ ) vertexBuffer_->Release( );
if( mvpCB_ ) mvpCB_->Release( );
if( alphaBlendState_ ) alphaBlendState_->Release( );
if( alphaBlendStateOff ) alphaBlendStateOff->Release( );
colorMapSampler_ = 0;
colorMap_ = 0;
solidColorVShaders[0] = 0;
solidColorPS_ = 0;
inputLayout_ = 0;
vertexBuffer_ = 0;
mvpCB_ = 0;
alphaBlendState_ = 0;
alphaBlendStateOff = 0;
}
void GameSpriteDemo::Update( float dt )
{
// Nothing to update
}
bool GameSpriteDemo::DrawString( char* message, float startX, float startY )
{
// Size in bytes for a single sprite.
const int sizeOfSprite = sizeof( VertexPos ) * 6;
// Demo's dynamic buffer setup for max of 24 letters.
const int maxLetters = 24;
int length = strlen( message );
// Clamp for strings too long.
if( length > maxLetters )
length = maxLetters;
// Char's width on screen.
float charWidth = 32.0f / (1366.0f*1.0f);
// Char's height on screen.
float charHeight = 32.0f / (768.0f*1.0f);
// Char's texel width.
float texelWidth = 32.0f / 896.0f;
// verts per-triangle (3) * total triangles (2) = 6.
const int verticesPerLetter = 6;
D3D11_MAPPED_SUBRESOURCE mapResource;
HRESULT d3dResult = d3dContext_->Map( vertexBuffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapResource );
if( FAILED( d3dResult ) )
{
DXTRACE_MSG( "Failed to map resource!" );
return false;
}
// Point to our vertex buffer's internal data.
VertexPos *spritePtr = ( VertexPos* )mapResource.pData;
const int indexA = static_cast<char>( 'A' );
const int indexZ = static_cast<char>( 'Z' );
const int index_a = static_cast<char>( 'a' );
for( int i = 0; i < length; ++i )
{
float thisStartX = startX + ( charWidth * static_cast<float>( i ) );
float thisEndX = thisStartX + charWidth;
float thisEndY = startY + charHeight;
spritePtr[0].pos = XMFLOAT3( thisEndX, thisEndY, 1.0f );
spritePtr[1].pos = XMFLOAT3( thisEndX, startY, 1.0f );
spritePtr[2].pos = XMFLOAT3( thisStartX, startY, 1.0f );
spritePtr[3].pos = XMFLOAT3( thisStartX, startY, 1.0f );
spritePtr[4].pos = XMFLOAT3( thisStartX, thisEndY, 1.0f );
spritePtr[5].pos = XMFLOAT3( thisEndX, thisEndY, 1.0f );
int texLookup = 0;
int letter = static_cast<char>( message[i] );
if (letter == index_a) {
texLookup = (indexZ - indexA) + 2;
}
else if( letter < indexA || letter > indexZ )
{
// Grab one index past Z, which is a blank space in the texture.
texLookup = ( indexZ - indexA ) + 1;
}
else
{
// A = 0, B = 1, Z = 25, etc.
texLookup = ( letter - indexA );
}
float tuStart = 0.0f + ( texelWidth * static_cast<float>( texLookup ) );
float tuEnd = tuStart + texelWidth;
spritePtr[0].tex0 = XMFLOAT2( tuEnd, 0.0f );
spritePtr[1].tex0 = XMFLOAT2( tuEnd, 1.0f );
spritePtr[2].tex0 = XMFLOAT2( tuStart, 1.0f );
spritePtr[3].tex0 = XMFLOAT2( tuStart, 1.0f );
spritePtr[4].tex0 = XMFLOAT2( tuStart, 0.0f );
spritePtr[5].tex0 = XMFLOAT2( tuEnd, 0.0f );
spritePtr += 6;
}
d3dContext_->Unmap( vertexBuffer_, 0 );
d3dContext_->Draw( 6 * length, 0 );
return true;
}
void GameSpriteDemo::Render( )
{
if( d3dContext_ == 0 )
return;
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
d3dContext_->ClearRenderTargetView( backBufferTarget_, clearColor );
unsigned int stride = sizeof( VertexPos );
unsigned int offset = 0;
d3dContext_->IASetInputLayout( inputLayout_ );
d3dContext_->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
d3dContext_->VSSetShader( solidColorVShaders[0], 0, 0 );
d3dContext_->PSSetShader( solidColorPS_, 0, 0 );
XMMATRIX world;
XMMATRIX mvp;
int index;
for (int k = 0; k < sprites_.size(); k++) {
index = sprites_[k].getIndex();
d3dContext_->IASetVertexBuffers( 0, 1, &vertexBuffers[index], &stride, &offset );
d3dContext_->PSSetShaderResources( 0, 1, &colorMaps[index] );
d3dContext_->PSSetSamplers( 0, 1, &colorSamplers[index] );
world = sprites_[k].GetWorldMatrix();
mvp = XMMatrixMultiply( world, vpMatrix_ );
mvp = XMMatrixTranspose( mvp );
d3dContext_->UpdateSubresource( mvpCB_, 0, 0, &mvp, 0, 0 );
d3dContext_->VSSetConstantBuffers( 0, 1, &mvpCB_ );
d3dContext_->Draw( 6, 0 );
}
// render text
DisableBlending();
d3dContext_->IASetVertexBuffers( 0, 1, &vertexBuffer_, &stride, &offset );
d3dContext_->PSSetShaderResources( 0, 1, &colorMap_ );
d3dContext_->PSSetSamplers( 0, 1, &colorMapSampler_ );
d3dContext_->VSSetShader( solidColorVS_2, 0, 0 );
d3dContext_->PSSetShader( solidColorPS_2, 0, 0 );
DrawString( "PROTOTYPE TEXT", -0.2f, 0.0f );
swapChain_->Present( 0, 0 );
}
ID3D11ShaderResourceView* GameSpriteDemo::getColorMap(int index) {
return colorMaps[index];
}
// this functions disables the alpha blending
void GameSpriteDemo::DisableBlending() {
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
d3dContext_->OMSetBlendState( alphaBlendStateOff, blendFactor, 0xFFFFFFFF );
}
Screen of the results when drawing with blending enabled
http://i49.tinypic.com/33kao9v.jpg
and here is the HLSL code for the two FX files I'm using (the first for the sprites, the second for the text)
TextureMap.fx
cbuffer cbChangesPerFrame : register( b0 )
{
matrix mvp_;
};
Texture2D colorMap_ : register( t0 );
SamplerState colorSampler_ : register( s0 );
struct VS_Input
{
float4 pos : POSITION;
float2 tex0 : TEXCOORD0;
};
struct PS_Input
{
float4 pos : SV_POSITION;
float2 tex0 : TEXCOORD0;
};
PS_Input VS_Main( VS_Input vertex )
{
PS_Input vsOut = ( PS_Input )0;
vsOut.pos = mul( vertex.pos, mvp_ );
vsOut.tex0 = vertex.tex0;
return vsOut;
}
float4 PS_Main( PS_Input frag ) : SV_TARGET
{
return colorMap_.Sample( colorSampler_, frag.tex0 );
}
TextMap.fx
Texture2D colorMap_ : register( t0 );
SamplerState colorSampler_ : register( s0 );
struct VS_Input
{
float4 pos : POSITION;
float2 tex0 : TEXCOORD0;
};
struct PS_Input
{
float4 pos : SV_POSITION;
float2 tex0 : TEXCOORD0;
};
PS_Input VS_Main( VS_Input vertex )
{
PS_Input vsOut = ( PS_Input )0;
vsOut.pos = vertex.pos;
vsOut.tex0 = vertex.tex0;
return vsOut;
}
float4 PS_Main( PS_Input frag ) : SV_TARGET
{
return colorMap_.Sample( colorSampler_, frag.tex0 );
}
I have wondered maybe to use pixel shaders to perform alpha blending for specific 2D images but my first attempts has not worked at all.
Hope someone can find a solution somehow :)
and thanks again for the help.
Good afternoon,
I'm trying to learn to use a graphics library that uses OpenGL. I can draw 2D primitives (text and lines) but 3D triangles don't render. I've tried everything I can think of but as an OpenGL newcomer I've probably missed something obvious.
This code is not intended to be efficient. I'm trying to get it to work first.
Here's the setup at startup:
// 800 by 600 windows 32 bit depth
Driver->setDisplay( UDriver::CMode( ScreenWidth, ScreenHeight, 32 ) );
NL3D::CViewport viewport;
viewport.initFullScreen();
Driver->setViewport( viewport );
NLMISC::CMatrix mtx;
mtx.identity();
Driver->setViewMatrix( mtx );
Driver->setModelMatrix( mtx );
// screen size is same as pixel resolution
// CFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective= true)
Driver->setMatrixMode2D( CFrustum( 0.0f, ScreenWidth, 0.0f, ScreenHeight, -2.0f, 10000.0f, false ) );
Here's the code in my rendering loop:
static NL3D::CMaterial mat;
mat.initUnlit();
mat.setColor( CRGBA( 255, 255, 0, 128 ) );
float x = 200.0f;
float y = 200.0f;
float width = 200.0f; // (float)ScreenWidth * 0.125f;
float height = 200.0f; // (float)ScreenHeight * 0.125f;
static NL3D::CVertexBuffer vb;
if ( vb.getName().empty() )
vb.setName("drawBitmap");
vb.setVertexFormat( NL3D::CVertexBuffer::PositionFlag | NL3D::CVertexBuffer::TexCoord0Flag );
vb.setNumVertices( 4 );
{
NL3D::CVertexBufferReadWrite vba;
vb.lock( vba );
vba.setVertexCoord( 0, NLMISC::CVector( x, 0, y ) );
vba.setVertexCoord( 1, NLMISC::CVector( x + width, 0, y ) );
vba.setVertexCoord( 2, NLMISC::CVector( x + width, 0, y + height ) );
vba.setVertexCoord( 3, NLMISC::CVector( x, 0, y + height ) );
vba.setTexCoord( 0, 0, 0.f, 1.f );
vba.setTexCoord( 1, 0, 1.f, 1.f );
vba.setTexCoord( 2, 0, 1.f, 0.f );
vba.setTexCoord( 3, 0, 0.f, 0.f );
}
dynamic_cast<NL3D::CDriverUser*>(Driver)->getDriver()->activeVertexBuffer( vb );
static NL3D::CIndexBuffer pb;
if ( pb.getName().empty() )
pb.setName("drawBitmap");
pb.setFormat( NL_DEFAULT_INDEX_BUFFER_FORMAT );
pb.setNumIndexes( 6 );
{
CIndexBufferReadWrite iba;
pb.lock( iba );
iba.setTri( 0, 0, 1, 2 );
iba.setTri( 3, 2, 3, 0 );
}
dynamic_cast<NL3D::CDriverUser*>(Driver)->getDriver()->activeIndexBuffer( pb );
dynamic_cast<NL3D::CDriverUser*>(Driver)->getDriver()->renderTriangles( mat, 0, 2 );
Any suggestions?
Thanks
It turned out to be multiple OpenGL contexts. It wasn't setting things back before trying to draw.