Blurred image with directx

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
sv161
Posts: 8
Joined: Tue Sep 20, 2011 3:31 pm

Blurred image with directx

Post by sv161 »

Hi!
I noticed the blurred image using the direct3d9/direct3d8 driver. There is no blur when using the opengl driver.

Please, compare results.
OpenGL
http://imageshack.us/photo/my-images/37/opengl.png/
D3D9
http://imageshack.us/photo/my-images/28/d3d9.png/
Original texture:
http://imageshack.us/photo/my-images/267/fractal.png/

My environment: Win 7 64-bit, VS2010, irrlicht 1.7.2

Please, explain me what's wrong.

For testing purposes I replaced "01.HelloWorld_vc9" with this code

Code: Select all

#include <irrlicht.h>
 
using namespace irr;
 
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
#ifdef _IRR_WINDOWS_
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
 
const int WIN_X = 1024;
const int WIN_Y = 768;
const int MARGIN_X = 85;
const int MARGIN_Y = 0;
 
typedef enum {
  BM_NORMAL,
  BM_LIGHTEN,
  BM_DARKEN,
  BM_DISABLE,
  BM_ALPHABLEND_ALPHATEST,
} EBlendingMode;
 
irr::f32 GetBlendFunc (EBlendingMode blend_mode)
{
        switch (blend_mode)
        {
        case BM_NORMAL: return pack_texureBlendFunc (
                                                                                irr::video::EBF_SRC_ALPHA,
                                                                                irr::video::EBF_ONE_MINUS_SRC_ALPHA, 
                                                                                irr::video::EMFN_MODULATE_1X,
                                                                                irr::video::EAS_TEXTURE | irr::video::EAS_VERTEX_COLOR);
        case BM_LIGHTEN: return pack_texureBlendFunc (
                                                                                irr::video::EBF_SRC_ALPHA,
                                                                                irr::video::EBF_ONE,
                                                                                irr::video::EMFN_MODULATE_1X,
                                                                                irr::video::EAS_TEXTURE | irr::video::EAS_VERTEX_COLOR);
        case BM_DARKEN: return pack_texureBlendFunc (
                                                                                irr::video::EBF_ZERO,
                                                                                irr::video::EBF_SRC_COLOR,
                                                                                irr::video::EMFN_MODULATE_1X,
                                                                                irr::video::EAS_TEXTURE | irr::video::EAS_VERTEX_COLOR);
        }
        return 0;
}
 
void SetRenderMatrices(IVideoDriver * driver)
{
        core::matrix4 identity_matrix;
        identity_matrix.makeIdentity();
        driver->setTransform (video::ETS_WORLD, identity_matrix);
 
        //------------ VIEW --------------
        core::matrix4 view_matrix;
        view_matrix.setTranslation (core::vector3df (-0.5f * WIN_X, -0.5f * WIN_Y, 0));
 
        driver->setTransform (video::ETS_VIEW, view_matrix);
 
        //------------ PROJECTION --------------
        core::matrix4 proj_matrix;
        proj_matrix.buildProjectionMatrixOrthoLH (WIN_X, -WIN_Y, -500, 500);
 
        driver->setTransform (video::ETS_PROJECTION, proj_matrix);
}
 
void SetViewport(IVideoDriver * driver)
{
        //Setup viewport a bit smaller than whole window size
        driver->setViewPort(irr::core::recti (MARGIN_X, MARGIN_Y, WIN_X - MARGIN_X - 1, WIN_Y - MARGIN_Y - 1));
}
 
IrrlichtDevice * CreateIrrDevice()
{
        SIrrlichtCreationParameters     p;
        
        p.AntiAlias = false;
        p.Bits = 32;
        p.Doublebuffer = true;
        p.DeviceType = EIDT_BEST;
        p.EventReceiver = NULL;
 
        p.Fullscreen = true;
        p.HighPrecisionFPU = false;
        p.IgnoreInput = false;
        p.Stencilbuffer = false;
        p.Stereobuffer = false;
        p.Vsync = true;
        p.WindowId = 0;
        p.WindowSize = core::dimension2d<int> (WIN_X, WIN_Y);
 
        p.WithAlphaChannel = false;
        p.ZBufferBits = 0;
 
        p.DriverType = video::EDT_OPENGL;
        return irr::createDeviceEx (p);
}
 
int main()
{
        IrrlichtDevice *device = CreateIrrDevice();
 
        if (!device)
                return 1;
 
        device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
 
        IVideoDriver* driver = device->getVideoDriver();
 
        irr::video::SMaterial material;
        material.BackfaceCulling = false;
        material.AntiAliasing = false;
        material.Lighting = false;
        material.ZBuffer = irr::video::ECFN_ALWAYS;
        material.Wireframe = false;
        material.MaterialType = irr::video::EMT_ONETEXTURE_BLEND;
        material.MaterialTypeParam = GetBlendFunc (BM_NORMAL);
        material.setFlag (irr::video::EMF_BILINEAR_FILTER, true);
        material.setFlag (irr::video::EMF_TRILINEAR_FILTER, false);
        material.setFlag (irr::video::EMF_ANISOTROPIC_FILTER, false);
        material.setFlag (irr::video::EMF_TEXTURE_WRAP, false);
        
        driver->setMaterial (material);
 
        irr::video::S3DVertex2TCoords Vertices [4];
        irr::video::SColor color(255, 255, 255, 255);
        Vertices [0].Color = color;
        Vertices [1].Color = color;
        Vertices [2].Color = color;
        Vertices [3].Color = color;
 
        Vertices [0].Pos.set(0, 0, 0);
        Vertices [1].Pos.set(1024, 0, 0);
        Vertices [2].Pos.set(1024, 768, 0);
        Vertices [3].Pos.set(0, 768, 0);
 
        Vertices [0].TCoords.set(0, 0);
        Vertices [1].TCoords.set(1, 0);
        Vertices [2].TCoords.set(1, 1);
        Vertices [3].TCoords.set(0, 1);
 
        Vertices [0].Normal.set(0.0f, 0.0f, -1.0f);
        Vertices [1].Normal.set(0.0f, 0.0f, -1.0f);
        Vertices [2].Normal.set(0.0f, 0.0f, -1.0f);
        Vertices [3].Normal.set(0.0f, 0.0f, -1.0f);
 
        irr::u16 VertexIndices [6] = { 0, 1, 2, 0, 2, 3 };
 
        irr::video::ITexture * tex = driver->getTexture("fractal.png");
 
        while(device->run())
        {
                SetRenderMatrices(driver);
                SetViewport(driver);
 
                irr::core::matrix4 world = driver->getTransform(irr::video::ETS_WORLD);
                irr::core::matrix4 view = driver->getTransform(irr::video::ETS_VIEW);
                irr::core::matrix4 proj = driver->getTransform(irr::video::ETS_PROJECTION);
 
                driver->beginScene(true, true, SColor(255, 100, 101, 140));
 
                material.setTexture(0, tex);
 
                driver->setMaterial(material);
                
                driver->drawIndexedTriangleList (Vertices, 4, VertexIndices, 2);
 
                driver->endScene();
        }
        
        device->drop();
 
        return 0;
}
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Blurred image with directx

Post by hybrid »

Could be the upscaling due to the non-power-of-two dimension of the texture. Please check (by printing the result of queryFeature for EVDF_NPOT_TEXTURE or something like that) if both d3d and opengl support it. But I'll check if some filter setting could cause this, too.
sv161
Posts: 8
Joined: Tue Sep 20, 2011 3:31 pm

Re: Blurred image with directx

Post by sv161 »

driver->queryFeature(EVDF_TEXTURE_NPOT) returns true for both d3d9 and opengl
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Blurred image with directx

Post by hybrid »

Well, I've found your manually adapted projection matrix and viewport. Could be that this affects the filtering differently.
sv161
Posts: 8
Joined: Tue Sep 20, 2011 3:31 pm

Re: Blurred image with directx

Post by sv161 »

Yes, I need it, because I want adapt the game for widescreen displays. So I calculate margins and customize matrices and viewport.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Blurred image with directx

Post by hybrid »

There's no need to do these calculations manually. Just set the device size and the aspect ratio properly, and you should get the correct results.
sv161
Posts: 8
Joined: Tue Sep 20, 2011 3:31 pm

Re: Blurred image with directx

Post by sv161 »

Thanks, but I want say, that I need orthogonal projection, because my game is casual 2d. So I need this margins. I have the same result using camera's methods for orthogonal projection setup

Code: Select all

 
        irr::scene::ISceneManager * smgr = device->getSceneManager();
 
        float cam_pos_x = WIN_X * 0.5f;
        float cam_pos_y = WIN_Y * 0.5f;
        ICameraSceneNode * camera = smgr->addCameraSceneNode(
                NULL,
                irr::core::vector3df(cam_pos_x, cam_pos_y, -100),
                irr::core::vector3df(cam_pos_x, cam_pos_y, 0));
        core::matrix4 proj_matrix;
        proj_matrix.buildProjectionMatrixOrthoLH (WIN_X, -WIN_Y, -500, 500);
        camera->setProjectionMatrix(proj_matrix, true);
My research with d3d9 showed the exact result in simple test application.
So I think I need to dig into d3d to figure out what the problem is. I think it's problem like +1 or -1 somewhere in viewport/margins calculus.
Here is the source code of this simple application

Code: Select all

 
#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )
 
 
 
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
 
const int WIN_X = 1024;
const int WIN_Y = 768;
const int MARGIN_X = 85;
const int MARGIN_Y = 0;
 
LPDIRECT3D9             g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
IDirect3DIndexBuffer9*  g_pIB = NULL;
 
LPDIRECT3DTEXTURE9      g_pTexture = NULL; // Our texture
 
// A structure for our custom vertex type. We added texture coordinates
struct CUSTOMVERTEX
{
    D3DXVECTOR3 position; // The position
    D3DCOLOR color;    // The color
#ifndef SHOW_HOW_TO_USE_TCI
    FLOAT tu, tv;   // The texture coordinates
#endif
};
 
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
 
 
 
//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // Create the D3D object.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Set up the structure used to create the D3DDevice. Since we are now
    // using more complex geometry, we will create a device with a zbuffer.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = FALSE;
        d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
        d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
        d3dpp.BackBufferWidth = WIN_X;
        d3dpp.BackBufferHeight = WIN_Y;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
 
    // Create the D3DDevice
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }
 
    // Turn off culling
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 
    // Turn off D3D lighting
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
 
    // Turn on the zbuffer
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
 
    return S_OK;
}
 
 
 
//-----------------------------------------------------------------------------
// Name: InitVertex()
// Desc: Initialize one vertex of buffer, setting coords and texture coords
//-----------------------------------------------------------------------------
void InitVertex(CUSTOMVERTEX* pVertices, int index, const D3DXVECTOR3 & v_coord, FLOAT u, FLOAT v)
{
        pVertices[index].position = v_coord;
    pVertices[index].color = 0xffffffff;
#ifndef SHOW_HOW_TO_USE_TCI
    pVertices[index].tu = u;
    pVertices[index].tv = v;
#endif
}
 
 
 
//-----------------------------------------------------------------------------
// Name: SetupViewport()
// Desc: Setup viewport with margins
//-----------------------------------------------------------------------------
bool SetupViewport()
{
        D3DVIEWPORT9 viewData = { MARGIN_X, MARGIN_Y, WIN_X - MARGIN_X * 2, WIN_Y - MARGIN_Y * 2, 0.0f, 1.0f };
        HRESULT hr;
    hr = g_pd3dDevice->SetViewport(&viewData);
        return SUCCEEDED(hr);
}
 
 
 
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Create the Textures and vertex buffers
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Use D3DX to create a texture from a file based image
    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"fractal.png", &g_pTexture ) ) )
    {
        return E_FAIL;
    }
 
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4 * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_MANAGED, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }
 
        // Create the index buffer.
    if( FAILED( g_pd3dDevice->CreateIndexBuffer( 4 * sizeof(short), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_pIB, 0 ) ) )
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer. We are setting the tu and tv texture
    // coordinates, which range from 0.0 to 1.0
    CUSTOMVERTEX* pVertices;
                
 
    if( FAILED( g_pVB->Lock( 0, 0, ( void** )&pVertices, 0 ) ) )
        return E_FAIL;
 
        InitVertex(pVertices, 
                0,
                D3DXVECTOR3(0, 0, 0),
                0, 0);
 
        InitVertex(pVertices, 
                1,
                D3DXVECTOR3(1024, 0, 0),
                1, 0);
 
        InitVertex(pVertices, 
                2,
                D3DXVECTOR3(1024, 768, 0),
                1, 1);
 
        InitVertex(pVertices, 
                3,
                D3DXVECTOR3(0, 768, 0),
                0, 1);
 
    g_pVB->Unlock();
 
        short *indices;
 
        g_pd3dDevice->CreateIndexBuffer(4 * sizeof(short),
                              0,
                              D3DFMT_INDEX16,
                              D3DPOOL_MANAGED,
                                                          &g_pIB,
                              NULL);
        g_pIB->Lock(0, 0, (void**)&indices, 0);
        indices[0] = 0;
        indices[1] = 1;
        indices[2] = 2;
        indices[3] = 0;
        indices[4] = 2;
        indices[5] = 3;
    g_pIB->Unlock();
 
    return S_OK;
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pTexture != NULL )
        g_pTexture->Release();
 
    if( g_pVB != NULL )
        g_pVB->Release();
 
        if( g_pIB != NULL )
        g_pIB->Release();
 
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
 
 
//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    // Set up world matrix
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
 
    // Set up our view matrix.
    D3DXMATRIXA16 matView;
        D3DXMatrixIdentity( &matView );
        D3DXMatrixTranslation(&matView, -0.5f * WIN_X, -0.5f * WIN_Y, 0);
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
 
    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixOrthoLH( &matProj, (FLOAT)WIN_X, (FLOAT)-WIN_Y, -1, 1);
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
    // Clear the backbuffer and the zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );
 
    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Setup the world, view, and projection matrices
        SetupMatrices();
                SetupViewport();
 
        // Setup our texture. Using Textures introduces the texture stage states,
        // which govern how Textures get blended together (in the case of multiple
        // Textures) and lighting information. In this case, we are modulating
        // (blending) our texture with the diffuse color of the vertices.
        g_pd3dDevice->SetTexture( 0, g_pTexture );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
                
                g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
                g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
 
                //g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 5);
                //g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
                //g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
 
        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
                g_pd3dDevice->SetIndices( g_pIB );
                g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2 );
 
        // End the scene
        g_pd3dDevice->EndScene();
    }
 
    // Present the backbuffer contents to the display
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    UNREFERENCED_PARAMETER( hInst );
 
    // Register the window class
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );
 
    // Create the application's window
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 05: Textures",
                              /*WS_OVERLAPPEDWINDOW*/WS_EX_TOPMOST | WS_POPUP, 0, 0, WIN_X, WIN_Y,
                              NULL, NULL, wc.hInstance, NULL );
 
    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Create the scene geometry
        if( SUCCEEDED( InitGeometry() ) )
        {
            // Show the window
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
 
            // Enter the message loop
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Blurred image with directx

Post by hybrid »

That's an interesting problem. I'll take the last example as 'Not a bug in Irrlicht', but it might be worth investigating a little more, and maybe find a way to avoid this problematic situation in Irrlicht by some counter measures.
sv161
Posts: 8
Joined: Tue Sep 20, 2011 3:31 pm

Re: Blurred image with directx

Post by sv161 »

People on the another forum pointed me into this article, maybe it help
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Blurred image with directx

Post by hybrid »

That is already handled by Irrlicht. Which makes a one pixel shift between d3d and opengl. But it should avoid the texture blur.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Blurred image with directx

Post by mongoose7 »

The document suggests a half-pixel shift. Or is this what you meant?
sv161
Posts: 8
Joined: Tue Sep 20, 2011 3:31 pm

Re: Blurred image with directx

Post by sv161 »

mongoose7 wrote: The document suggests a half-pixel shift. Or is this what you meant?
Yes, subtract (0.5; 0.5) from each vertex position. Or the same result but adding (1/TextureWidth/2; 1/TextureHeight/2) to texture coordinate for each vertex.
hybrid wrote:That is already handled by Irrlicht. Which makes a one pixel shift between d3d and opengl. But it should avoid the texture blur.
If I "fix" texture coordinates manually like this

Code: Select all

 
        float shift_x = 1.0f / tex->getSize().Width / 2.0f;
        float shift_y = 1.0f / tex->getSize().Height / 2.0f;
        for(int i = 0; i < 4; i++)
        {
                Vertices[i].TCoords.X -= shift_x;
                Vertices[i].TCoords.Y -= shift_y;
        }
 
then I have NO blur.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Blurred image with directx

Post by hybrid »

Ok, that's interesting. The half-pixel shift is done in 2d mode only in Irrlicht, in setRenderStates2DMode. That's why you don't get any help from Irrlicht in your case. However, it's also not really possible, as there's no proper way to do a 2d alignment with generic 3d rendering. So you should probably render those parts in 2d and get a proper alignment by Irrlicht.
Post Reply