Jump to content

  • Log In with Google      Sign In   
  • Create Account

Kjell Andersson

Member Since 28 Nov 1999
Offline Last Active Jul 16 2016 05:50 AM

#5280569 Exporting mesh vertex group to text.

Posted by Kjell Andersson on 10 March 2016 - 12:09 PM

The following code provides you with vertices and face indices from a D3DXMesh. You will have to write the code that saves it to file yourself, but that should be easy.

LPD3DXMESH m_pD3DMesh;

void MeshXWrapper::GetMeshData(int *pMeshVertexCount, dVector3 **ppMeshVertices,
                               int *pMeshIndexCount, int **ppMeshIndices)
{
    LPDIRECT3DVERTEXBUFFER9 pVB = NULL;
    m_pD3DMesh->GetVertexBuffer(&pVB);

    struct MY_FVF {
        float x;
        float y;
        float z;
    };

    void *pbVertexData;
    if (SUCCEEDED(pVB->Lock(0, 0, &pbVertexData, D3DLOCK_READONLY))) {
        DWORD numBytesPerVertex = m_pD3DMesh->GetNumBytesPerVertex();

        int numVertices = m_pD3DMesh->GetNumVertices();
        *ppMeshVertices = new dVector3[numVertices];
        unsigned char *pVBDataPos = (unsigned char*)pbVertexData;
        for (int i=0; i < numVertices; i++) {
            (*ppMeshVertices)[i][0] = ((MY_FVF*)pVBDataPos)->x;
            (*ppMeshVertices)[i][1] = ((MY_FVF*)pVBDataPos)->y;
            (*ppMeshVertices)[i][2] = ((MY_FVF*)pVBDataPos)->z;
            (*ppMeshVertices)[i][3] = 0;
            pVBDataPos += numBytesPerVertex;
        }
        pVB->Unlock();
        *pMeshVertexCount = m_pD3DMesh->GetNumVertices();
    }


    // Index buffer

    LPDIRECT3DINDEXBUFFER9 pIB;
    m_pD3DMesh->GetIndexBuffer(&pIB);
    D3DINDEXBUFFER_DESC indexDesc;
    pIB->GetDesc(&indexDesc);

    LPVOID pbIndexData;
    if (SUCCEEDED(m_pD3DMesh->LockIndexBuffer(D3DLOCK_READONLY, &pbIndexData))) {
        *pMeshIndexCount = indexDesc.Size / sizeof(unsigned short);
        *ppMeshIndices = new int[*pMeshIndexCount];
        for (int i=0; i<(*pMeshIndexCount)/3; i++) {
            unsigned short i0 = ((unsigned short*)pbIndexData)[i*3+0];
            unsigned short i1 = ((unsigned short*)pbIndexData)[i*3+1];
            unsigned short i2 = ((unsigned short*)pbIndexData)[i*3+2];

            (*ppMeshIndices)[i*3+0] = i0;
            (*ppMeshIndices)[i*3+1] = i1;
            (*ppMeshIndices)[i*3+2] = i2;
        }
        m_pD3DMesh->UnlockIndexBuffer();
    }

    pIB->Release();
    pVB->Release();
}




#5247324 Quaternions for FPS Camera?

Posted by Kjell Andersson on 18 August 2015 - 01:18 AM

If you are working with DirectX you may also take a look at DirectXMath, https://msdn.microsoft.com/en-us/library/windows/desktop/ee415597%28v=vs.85%29.aspx




#5247323 Quaternions for FPS Camera?

Posted by Kjell Andersson on 18 August 2015 - 01:12 AM

If you want a full math library for all your calculations, including quaternions, you can take a look at Eigen (http://eigen.tuxfamily.org)

It has a very free and liberal license.

 

In your case you are looking for the Geometry section (http://eigen.tuxfamily.org/dox/group__Geometry__Module.html) where you will find a lot of transformation classes and operations.

A quaternion is a representation of a rotation around an axis of your choice. So, to create a rotation for looking up 45 degrees you create a quaternion that rotates around a vector facing right from your character.

This constructor will probably work nice for you: Quaternion (const AngleAxisType &aa)

Then you apply this Quaternion to your existing character orientation, which is preferably also stored as a quaternion.




#5238177 How to recreate Dragon's Lair/Space Ace type game for mobile devices

Posted by Kjell Andersson on 03 July 2015 - 08:30 AM

If Dragon's Lair would have been made today it would be 3D based and rendered using a cartoon shader for the characters if that was the desired look. Video simply takes too much storage space.




#5232552 Water texturing of caustics effects

Posted by Kjell Andersson on 03 June 2015 - 06:18 AM

For those interested in rendering water, I just posted a new article on how to do texturing of caustics patterns to improve the look of rendered water.

 

The article focuses on Unity 3D and provides complete shader code that can be downloaded and used in your own projects. Even though the article talks about Unity 3D, the technique and the code snippets supplied can easily be translated to your own engine.

 

http://www.dualheights.se/caustics/caustics-water-texturing-using-unity3d.shtml

 

Happy reading!

 




#5185032 I wanna learn, I WANNA LEARN! C# Unity

Posted by Kjell Andersson on 04 October 2014 - 04:19 PM

I wouldn't totally dismiss the idea of browsing though others' code. Even if you don't understand everyhing it might give you a hint on how to structure code. It is also very helpful if you find complete projects just to compile them and get them to run on your computer. Then start modifying them to see what happens and you will soon understand bigger portions of the code and the structure that is behind that particular project. After you have done that with a couple of projects you might start to see patterns that are worth keeping for your own projects.

 

When I started programming back in the ages it began as dissassembling raw memory and poking around at instructions to see what would happend. Today with Internet and so many projects giving out the actual source code to the entire project I would say that its a gold mine to learn from. Just go in with the mindset that you will not understand half of what's there and that is a perfectly normal feeling. Just start poking around in the code and learn from what happens.




#5103189 Window appears only for a brief moment

Posted by Kjell Andersson on 21 October 2013 - 12:47 PM

The most probable cause is that your friend is lacking runtime DLLs on his computer.

Also, be sure to not compile against debug runtimes (with respect to both DirectX and MSVCRT) - make a release build.

The debug runtimes are normally not installed if you are not a developer yourself.

 

The best way to find out what is missing on your friends computer, and what you made wrong with your build, is to use Dependency Walker (http://www.dependencywalker.com).




#5102478 D3D9 64-bit debug runtime

Posted by Kjell Andersson on 18 October 2013 - 02:42 PM

I have finally found the answer to this problem.

First I would like to point a finger at Microsoft for really messing with us old developers that have a ton of legacy code to maintain. You are not helping us!

 

The problem originates from a Windows 7 update that locked down the HKLM\Software\Microsoft\Direct3D registry key to a user named TrustedInstaller. This made the Administrator not having rights to update the settings in the registry key - thus not allowing us to switch to a debug version of Direct3D 9.

 

To fix this problem you have to follow this procedure:

 

1. Using regedit as an Administrator, go to the HKLM\Software\Microsoft\Direct3D key.

2. Select Permissions... from the context menu on the key.

3. Press the Advanced button.

4. Go to the Owner tab and select the Administrator as the owner. Apply the changes and close the Advanced settings.

5. Back in the Premissions dialog select the Administrators group and check Full Control. Apply changes and close dialog.

 

You are now able to start the DirectX Control Panel from the DirectX SDK June 2010 and switch to the debug runtime.




#5092150 So I made this... Help xD

Posted by Kjell Andersson on 06 September 2013 - 02:26 PM

You need to declare variables before you use them.

 

A quick fix of your code to get it compiling for you:

// Adventure Game

#include <iostream>
#include <string>

using namespace std;

int main ()
{
    std::string characterName;
    std::string characterRace;
    std::string characterClass;

    cout << "\tWelcome to The Generic Adventure Game!\n\n";
    cout << "Please create your character\n\n";

    // Character Customization
    cout << "Name: ";
    cin >> characterName;
    cout << "\n\n";

    cout << "Available races...\n";
    cout << "Dwarf, Human, Orc\n\n";
    cout << "Race: ";
    cin >> characterRace;
    cout << "\n\n";

    cout << "Available classes...\n";
    cout << "Paladin, Wizard, Warrior\n\n";
    cout << "Class: ";
    cin >> characterClass;
    cout << "\n\n";

    if (characterName.find(' ') != string::npos) {
        cout << "Name is invalid. One word names only.";
        return -1;
    }

    if (characterRace != "Dwarf" && characterRace != "Human" && characterRace != "Orc") {
        cout << "Race is invalid. Remember the races are Dwarf, Human and Orc.";
        return -1;
    }

    if (characterClass != "Paladin" && characterClass != "Wizard" && characterClass != "Warrior") {
        cout << "Class is invalid. Remember the classes are Paladin, Wizard and Warrior";
        return -1;
    }

    if (!characterName.empty() &&
        (characterRace == "Dwarf" ||
        characterRace == "Human" ||
        characterRace == "Orc") &&
        (characterClass == "Paladin" ||
        characterClass == "Wizard" ||
        characterClass == "Warrior"))
    {
        cout << "Lets play!";
    }

    return 0;
}

Keep your spirit high, and keep going! Learning is a fun process!




#5073726 How to sample a texture with 8 bit channel in shader?

Posted by Kjell Andersson on 28 June 2013 - 05:48 PM

Worth noting is that the 8-bit RGBA values can be normalized (i.e. 0 to 255 => 0.0 to 1.0) when presented to the shader by the sampler for different format modifiers.

See the formatting table at the bottom of this page: http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx




#5072048 Render to Texture within HLSL

Posted by Kjell Andersson on 22 June 2013 - 12:03 PM

I'm using effect annotations to declaratively define render target textures in my shaders. The engine code parses these annotations when loading the effects and creates textures dynamically that are feed back to the shader through pEffect->SetTexture().

 

If you look at my blur filter you will find these annotations as RENDERCOLORTARGET in the code below.

texture g_inputTexture;  // Input texture to the filter

float2 outputTextureSize : VIEWPORTPIXELSIZE;

texture g_pass2Texture : RENDERCOLORTARGET
<
	float2 ViewportRatio = { 1.0, 1.0 };
>;

texture g_pass3Texture : RENDERCOLORTARGET
<
	float2 ViewportRatio = { 1.0, 1.0 };
>;

float Spread <
    string UIName = "Spread";
> = 0.1f;

// Vertex shader /////////////////////////////////////////

struct AppData {
	float3 Position		: POSITION;
	float2 UV			: TEXCOORD0;
};

struct VertData {
	float4 HPosition	: POSITION;
	float2 UV			: TEXCOORD0;
	float2 PixelDelta	: TEXCOORD1;
};

VertData VS_Common(AppData IN)
{
	VertData OUT;

	OUT.UV = IN.UV.xy;

	OUT.HPosition = float4(IN.Position.x, IN.Position.y, 0, 1.0);

	float dx = 1.0 / outputTextureSize.x;
	float dy = 1.0 / outputTextureSize.y;
    OUT.PixelDelta = float2(dx, dy);

	return OUT;
}

// Pixel shader /////////////////////////////////////////

sampler Sampler1 = sampler_state
{
	Texture   = (g_inputTexture);
	MipFilter = LINEAR;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	BorderColor = float4(0, 0, 0, 0);
	AddressU  = CLAMP;
	AddressV  = CLAMP;
};

sampler Sampler2 = sampler_state
{
	Texture   = (g_pass2Texture);
	MipFilter = LINEAR;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	BorderColor = float4(0, 0, 0, 0);
	AddressU  = CLAMP;
	AddressV  = CLAMP;
};

sampler Sampler3 = sampler_state
{
	Texture   = (g_pass3Texture);
	MipFilter = LINEAR;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	BorderColor = float4(0, 0, 0, 0);
	AddressU  = CLAMP;
	AddressV  = CLAMP;
};

static const int g_cKernelSize = 13;

static const float BlurWeights[g_cKernelSize] =
{
	0.002216,
	0.008764,
	0.026995,
	0.064759,
	0.120985,
	0.176033,
	0.199471,
	0.176033,
	0.120985,
	0.064759,
	0.026995,
	0.008764,
	0.002216,
};

float4 PS_HBlur(uniform sampler Sampler,
                uniform float SpreadMultiplier,
                float2 uv : TEXCOORD0,
                float2 pixelDelta : TEXCOORD1) : COLOR
{
	float4 Color = 0;

	float SpreadAmount = Spread * SpreadMultiplier;
	for (int i = 0; i < g_cKernelSize; i++) {
		Color += tex2D(Sampler, uv + float2(-SpreadAmount*pixelDelta.x*(i-6), 0)) * BlurWeights[i];
	}

    return Color;
}

float4 PS_VBlur(uniform sampler Sampler,
                uniform float SpreadMultiplier,
                float2 uv : TEXCOORD0,
                float2 pixelDelta : TEXCOORD1) : COLOR
{
	float4 color = 0;

	float SpreadAmount = Spread * SpreadMultiplier;
	for (int i = 0; i < g_cKernelSize; i++) {
		color += tex2D(Sampler, uv + float2(0, -SpreadAmount*pixelDelta.y*(i-6))) * BlurWeights[i];
	}
	
	return color;
}

// Technique /////////////////////////////////////////

technique FilterTechnique
{
	pass HBlur1 <
		string RenderTarget0 = "g_pass2Texture";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_HBlur(Sampler1, 8);
	}

	pass VBlur1 <
		string RenderTarget0 = "g_pass3Texture";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_VBlur(Sampler2, 8);
	}

	pass HBlur2 <
		string RenderTarget0 = "g_pass2Texture";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_HBlur(Sampler3, 4);
	}

	pass VBlur2 <
		string RenderTarget0 = "g_pass3Texture";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_VBlur(Sampler2, 4);
	}

	pass HBlur3 <
		string RenderTarget0 = "g_pass2Texture";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_HBlur(Sampler3, 2);
	}

	pass VBlur3 <
		string RenderTarget0 = "g_pass3Texture";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_VBlur(Sampler2, 2);
	}

	pass HBlur4 <
		string RenderTarget0 = "g_pass2Texture";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_HBlur(Sampler3, 1);
	}

	pass VBlur4 <
		string RenderTarget0 = "";
	>
	{
		// Setup render states
		ZWriteEnable     = FALSE;
		ZEnable          = FALSE;
		AlphaBlendEnable = FALSE;

		// Shaders
		VertexShader = compile vs_1_1 VS_Common();
		PixelShader  = compile ps_2_0 PS_VBlur(Sampler2, 1);
	}
}

The ViewportRatio parameter I use as a scaling parameter when creating the textures - for effects that for example want lower resolution intermediate textures.

 

What you are looking for is the enumeration of effect annotations in code similar to this:

void GXEffectFilter::ParseEffectAnnotations(LPD3DXEFFECT pEffect)
{
	// Parse parameter annotations
	D3DXHANDLE			paramHandle;
	D3DXPARAMETER_DESC	paramDesc;

	unsigned int index = 0;
	while ((paramHandle = pEffect->GetParameter(NULL, index)) != NULL) {
		if (pEffect->GetParameterDesc(paramHandle, &paramDesc) == S_OK) {
			// Iterate through all associated annotations
			FLOAT viewportRatio[2] = {1, 1};
			for (unsigned int a = 0; a < paramDesc.Annotations; a++) {
				D3DXHANDLE hAnnot = pEffect->GetAnnotation(paramHandle, a);
				// Get annotation description
				D3DXPARAMETER_DESC annotDesc;
				if (pEffect->GetParameterDesc(hAnnot, &annotDesc) == S_OK) {
					if (_stricmp(annotDesc.Name, "ViewportRatio") == 0) {
						pEffect->GetFloatArray(hAnnot, viewportRatio, 2);
					}
[...]
				}
			}
			// Handle creation of textures
			if (paramDesc.Type == D3DXPT_TEXTURE &&
				paramDesc.Semantic != NULL && _stricmp(paramDesc.Semantic, "RENDERCOLORTARGET") == 0)
			{
				RegisterInternalTexture(index, viewportRatio);
			}
[...]
		}
		index++;
	}
}

Then handle the creation of the dynamic texture in the RegisterInternalTexture() call and set the created texture back to the shader by calling

		pEffect->SetTexture(pEffect->GetParameter(NULL, parameterIndex), pTexture);

When you later is about the render each pass in your shader you will have to parse the Pass annotations and find "RenderTarget0" and use pD3DDevice->SetRenderTarget() with the texture you have defined in your shader pass.




#5068115 SafeRelease not that Safe?

Posted by Kjell Andersson on 07 June 2013 - 05:01 PM

D3DXCreateEffectFromFileA does not set mEffect if the function fails. Are you sure that you sett mEffect to NULL in your constructor?

 

Maybe you are having two mEffect, one local before your call to D3DXCreateEffectFromFileA, as you write above, and one as a member in your class that never gets initialized to NULL in the constructor?




#5068110 Just getting my hands dirty. Questions for starting out.

Posted by Kjell Andersson on 07 June 2013 - 04:38 PM

Without starting a flame war, I prefer DirectX, mostly because I'm used to it and know the in-and-outs of it better than OpenGL.

 

Historically DirectX gave your more control and adopted new graphic card features quicker than the OpenGL standard did. OpenGL supported new features through extensions that were provided by the different hardware producers and made it a pain to support all the different graphic cards that were out there.

 

Today when you can do much work on your own in shaders the difference is not as big as it used to be. The main difference is that DirectX is only for the Windows platform. If you are to do 3D programming on other platforms than Windows (e.g. Android) you will have to use OpenGL or some higher abstraction of it.

 

To answer your second question - yes, the DirectX initialization and overhead work is quite brutal, but have gotten better over the years. This is connected to by first remark above - it gives you control. If you download the DirectX SDK (part of the Windows SDK nowadays) there are examples and tutorials supplied with the SDK that helps you with the mundane work of setting up DirectX. You will get started with actual graphics coding quickly, so don't worry about the initialization so much.




#5068102 Raytracing

Posted by Kjell Andersson on 07 June 2013 - 04:08 PM

The dot product between the normal of the surface and your intersection vector will be > 0 and thus fail the if test in the intersection test.

 

This means that the intersection test is designed to use back-face culling, i.e. the back of a triangles are not visible.




#5031232 Texture coordinates for a straight line and a point

Posted by Kjell Andersson on 11 February 2013 - 03:46 PM

A pixel shader only affects the pixels that are within your rendered geometry. For the triangle case, only the pixels within your triangle are rendered by the shader. This means that the pixels that are outside of your triangle will not be affected. If you are drawing a triangle with a shader that blurs the texture you will get a blurry texture within the triangle only - it will not blur the edges to the outside of the triangle area.

 

When using the graphics card to draw lines or points, the same applies. The shader will only calculate the texture for the pixels within the line or the single point. You will thus never be able to draw blurred lines using only a shader attached to the line drawing.

 

In order to draw blurred lines you have to do a screen blur by first rendering your lines and points to an off-screen texture. Then you draw this texture to the screen using a quad and attach your blur shader to the drawing of that quad.

 

The other approach to drawing blurred lines and points is to use a pre-created semi-transparent texture of a blurred point. Instead of drawing a single line using the line drawing of the graphics card you create a thick "box"-line using two triangles to create a quad where you want the line or point to be drawn. Then just apply the "blurred point"-texture and draw the quad to the screen using a simple alpha-blending shader.






PARTNERS