最近刚看完UnityShader的一些介绍和例子,发现理论上的东西都是含糊过去的,就还是老老实实去看dx。之前有学过dx,dx10,11的初始化太繁琐,代码是dx9的好几倍,手上也有本《DirectX3D HLSL高级实例精讲》里面用的就是dx9,所以就选择用dx9来写。

最近刚看到不用effect来写,分成vertexshader.vs和pixeslshader.ps来写,就跟dx11的差不多,就没仔细看,直接开始写,然后遇到bug,调试了很久。刚开始还以为是用的版本太高的问题,用的是vs2017和Microsoft DirectX SDK (June 2010)。想了想effect都能用,那就应该不是这个问题。而且这本《DirectX3D HLSL高级实例精讲》书上的源码完全不跟实例相关,坑啊。只好一步步断点调试,发现有一个空指针。(抽个空会把《DirectX3D HLSL高级实例精讲》的源码上传下,不要期待有多大用处,用的是DXUT框架,vs2017+win10sdk不能编译成lib,就算编译好了,还会各种报错,也懒得弄个xp系统的,直接用之前学习的那套框架,简单粗暴点)

先来effect源码:文件名是ColorShader.fx,如果用的是vs2017的话,记得在HLSL compiler设置为effect,shader model 2

float time;
float4x4 worldMatrix;
float4x4 viewMatrix;
float4x4 projectionMatrix;
texture modelTexture;sampler ModelTextureSampler = sampler_state
{Texture = <modelTexture>;MipFilter = LINEAR;MinFilter = LINEAR;MagFilter = LINEAR;
};struct VertexInputType
{float4 vertex : POSITION;float2 texcoord : TEXCOORD0;
};struct PixelInputType
{float4 pos : POSITION;float2 texcoord : TEXCOORD0;
};PixelInputType ColorVertexShader(VertexInputType input)
{PixelInputType output;float4x4 worldViewMatrix = mul(worldMatrix, viewMatrix);float4x4 worldViewProjectionMatrix = mul(worldViewMatrix, projectionMatrix);output.pos = mul(input.vertex, worldViewProjectionMatrix);output.texcoord = input.texcoord;return output;
}float4 ColorPixelShader(PixelInputType input) : COLOR
{float4 color = tex2D(ModelTextureSampler, input.texcoord);return color;
}technique ColorTechnique
{pass pass0{CullMode = None;VertexShader = compile vs_2_0 ColorVertexShader();PixelShader = compile ps_2_0 ColorPixelShader();}
}

接着是VertexShader,文件名为ColorVertexShader.vs

float4x4 worldMatrix;
float4x4 viewMatrix;
float4x4 projectionMatrix;
sampler modelTexture;struct VertexInputType
{float4 vertex : POSITION;float2 texcoord : TEXCOORD0;
};struct PixelInputType
{float4 pos : POSITION;float2 texcoord : TEXCOORD0;
};PixelInputType ColorVertexShader(VertexInputType input)
{PixelInputType output;float4x4 worldViewMatrix = mul(worldMatrix, viewMatrix);float4x4 worldViewProjectionMatrix = mul(worldViewMatrix, projectionMatrix);output.pos = mul(input.vertex, worldViewProjectionMatrix);output.texcoord = input.texcoord;return output;
}

PixelShader,文件名为ColorPixelShader.ps

float time;
sampler modelTexture;struct PixelInputType
{float4 pos : POSITION;float2 texcoord : TEXCOORD0;
};float4 ColorPixelShader(PixelInputType input) : COLOR
{float4 color = tex2D(modelTexture, input.texcoord) * cos(time);return color;
}    

Shader代码其实很简单,就不多说了,先来说我遇到的问题:

bool ColorShaderClass::SetShaderParameters(IDirect3DDevice9* device, float time, IDirect3DTexture9* texture, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{HRESULT result;D3DXHANDLE textureHandle;D3DXCONSTANT_DESC textureDesc;UINT count;result = device->SetVertexShader(m_vertexShader);if (FAILED(result))return false;result = device->SetPixelShader(m_pixelShader);if (FAILED(result))return false;result = m_vertexShaderTable->SetMatrix(device, "worldMatrix", &worldMatrix);if (FAILED(result))return false;result = m_vertexShaderTable->SetMatrix(device, "viewMatrix", &viewMatrix);if (FAILED(result))return false;result = m_vertexShaderTable->SetMatrix(device, "projectionMatrix", &projectionMatrix);if (FAILED(result))return false;// The variable of shader must be used, otherwise ID3DXConstantTable can't find itresult = m_pixelShaderTable->SetFloat(device, "time", time);if (FAILED(result))return false;textureHandle = m_pixelShaderTable->GetConstantByName(nullptr, "modelTexture");if (!textureHandle)return false;// The first way to set texture in shader/*result = m_pixelShaderTable->GetConstantDesc(textureHandle, &textureDesc, &count);if (FAILED(result))return false;result = device->SetTexture(textureDesc.RegisterIndex, texture);if (FAILED(result))return false;*/// The second way to set texture in shaderresult = device->SetTexture(m_pixelShaderTable->GetSamplerIndex(textureHandle), texture);if (FAILED(result))return false;return true;
}

我遇到的问题就是代码第一个英文注释的地方,(我写的,英文烂,语法错误什么的就不管了,如果要装逼,我可以用日文写),其实这个问题是在pixelshader中遇到的,问题就是不能设置pixelshader的变量。而且hlsl调试只能靠猜,搞得我还以为pixelshader是不能设置变量的。后来通过dx的ID3DXConstantTable中的GetConstantByName方法调试得到,在pixelshader中获取time的D3DXHANDLE为空指针,接着我在vertexshader中添加一个新的矩阵来测试,发现了问题所在,就是在VertexShader和PixelShder中不使用的变量,如果用代码去获得和设置都会报错,因为得到的都是空指针,你对空指针操作肯定出问题,估计是dx过滤了不使用的变量。但是最主要的一点是在Effect中没有这个问题,看我effect源码中的time就没有用到,但没有任何问题。

使用effect的源码:

ModelClass:

#include "ModelClass.h"ModelClass::ModelClass()
{m_mesh = nullptr;m_colorShader = nullptr;m_texture = nullptr;
}ModelClass::ModelClass(const ModelClass& other)
{
}ModelClass::~ModelClass()
{
}bool ModelClass::Initialize(IDirect3DDevice9* device, TCHAR* modelFilePath, TCHAR* textureFilePath)
{bool result;result = InitializeMesh(device, modelFilePath);if (!result)return false;result = InitializeTexture(device, textureFilePath);if (!result)return false;m_colorShader = new ColorShaderClass();if (!m_colorShader)return false;result = m_colorShader->Initialize(device);if (!result)return false;return true;
}void ModelClass::Shutdown()
{if (m_mesh){m_mesh->Release();m_mesh = nullptr;}if (m_colorShader){m_colorShader->Shutdown();delete m_colorShader;m_colorShader = nullptr;}if (m_texture){m_texture->Shutdown();delete m_texture;m_texture = nullptr;}
}void ModelClass::Render(IDirect3DDevice9* device, float time, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{bool result;UINT passMaxNum;result = m_colorShader->Render(device, time, m_texture->GetTexture(), worldMatrix, viewMatrix, projectionMatrix);if (!result)return;m_colorShader->GetEffect()->Begin(&passMaxNum, 0);for (UINT pass = 0; pass < passMaxNum; ++pass){m_colorShader->GetEffect()->BeginPass(pass);m_mesh->DrawSubset(0);m_colorShader->GetEffect()->EndPass();}m_colorShader->GetEffect()->End();
}bool ModelClass::InitializeMesh(IDirect3DDevice9* device, TCHAR* modelFilePath)
{HRESULT result;result = ::D3DXLoadMeshFromX(modelFilePath,D3DXMESH_MANAGED,device,nullptr, nullptr,nullptr, nullptr,&m_mesh);if (FAILED(result))return false;return true;
}bool ModelClass::InitializeTexture(IDirect3DDevice9* device, TCHAR* textureFiltPath)
{bool result;m_texture = new TextureClass();if (!m_texture)return false;result = m_texture->Initialize(device, textureFiltPath);if (!result)return false;return true;
}

ColorShaderClass:

#include "ColorShaderClass.h"ColorShaderClass::ColorShaderClass()
{m_effect = nullptr;
}ColorShaderClass::ColorShaderClass(const ColorShaderClass& other)
{
}ColorShaderClass::~ColorShaderClass()
{
}bool ColorShaderClass::Initialize(IDirect3DDevice9* device)
{bool result;result = InitializeShader(device, TEXT("ColorShader.fx"));if (!result)return false;return true;
}void ColorShaderClass::Shutdown()
{if (m_effect){m_effect->Release();m_effect = nullptr;}
}bool ColorShaderClass::Render(IDirect3DDevice9* device, float time, IDirect3DTexture9* texture, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{bool result;result = SetShaderParameters(time, texture, worldMatrix, viewMatrix, projectionMatrix);if (!result)return false;return true;
}ID3DXEffect* ColorShaderClass::GetEffect()
{return m_effect;
}bool ColorShaderClass::InitializeShader(IDirect3DDevice9* device, TCHAR* shaderPath)
{HRESULT result;ID3DXBuffer* errorMessage;errorMessage = nullptr;result = ::D3DXCreateEffectFromFile(device, shaderPath, nullptr, nullptr, 0, nullptr, &m_effect, &errorMessage);if (FAILED(result)){if (errorMessage)OutputShaderErrorMessage(errorMessage, shaderPath);else::MessageBox(nullptr, shaderPath, TEXT("Missing Shader File"), MB_OK | MB_ICONERROR);return false;}return true;
}void ColorShaderClass::OutputShaderErrorMessage(ID3DXBuffer* errorMessage, TCHAR* shaderPath)
{char* compileErrors;ULONG bufferSize;ofstream fout;compileErrors = (char*)(errorMessage->GetBufferPointer());bufferSize = errorMessage->GetBufferSize();fout.open("shader-error.txt");for (ULONG i = 0; i < bufferSize; ++i)fout << compileErrors[i];fout.close();errorMessage->Release();errorMessage = nullptr;::MessageBox(nullptr, TEXT("Error compiling shader. Check shader-error.txt for message!"), shaderPath, MB_OK | MB_ICONERROR);
}bool ColorShaderClass::SetShaderParameters(float time, IDirect3DTexture9* texture, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{HRESULT result;result = m_effect->SetFloat("time", time);if (FAILED(result))return false;result = m_effect->SetTexture("modelTexture", texture);if (FAILED(result))return false;result = m_effect->SetMatrix("worldMatrix", &worldMatrix);if (FAILED(result))return false;result = m_effect->SetMatrix("viewMatrix", &viewMatrix);if (FAILED(result))return false;result = m_effect->SetMatrix("projectionMatrix", &projectionMatrix);if (FAILED(result))return false;result = m_effect->SetTechnique("ColorTechnique");if (FAILED(result))return false;return true;
}

接着是VertexShader和PixelShader的源码,MoedlClass只有渲染地方不一样其它都是一样的

ModelClass:

#include "ModelClass.h"ModelClass::ModelClass()
{m_mesh = nullptr;m_colorShader = nullptr;m_texture = nullptr;
}ModelClass::ModelClass(const ModelClass& other)
{
}ModelClass::~ModelClass()
{
}bool ModelClass::Initialize(IDirect3DDevice9* device, TCHAR* modelFilePath, TCHAR* textureFilePath)
{bool result;result = InitializeMesh(device, modelFilePath);if (!result)return false;result = InitializeTexture(device, textureFilePath);if (!result)return false;m_colorShader = new ColorShaderClass();if (!m_colorShader)return false;result = m_colorShader->Initialize(device);if (!result)return false;return true;
}void ModelClass::Shutdown()
{if (m_mesh){m_mesh->Release();m_mesh = nullptr;}if (m_colorShader){m_colorShader->Shutdown();delete m_colorShader;m_colorShader = nullptr;}if (m_texture){m_texture->Shutdown();delete m_texture;m_texture = nullptr;}
}void ModelClass::Render(IDirect3DDevice9* device, float time, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{bool result;result = m_colorShader->Render(device, time, m_texture->GetTexture(), worldMatrix, viewMatrix, projectionMatrix);if (!result)return;m_mesh->DrawSubset(0);
}bool ModelClass::InitializeMesh(IDirect3DDevice9* device, TCHAR* modelFilePath)
{HRESULT result;result = ::D3DXLoadMeshFromX(modelFilePath,D3DXMESH_MANAGED,device,nullptr,nullptr,nullptr,nullptr,&m_mesh);if (FAILED(result))return false;return true;
}bool ModelClass::InitializeTexture(IDirect3DDevice9* device, TCHAR* textureFilePath)
{bool result;m_texture = new TextureClass();if (!m_texture)return false;result = m_texture->Initialize(device, textureFilePath);if (!result)return false;return true;
}

ColorShaderClass:

#include "ColorShaderClass.h"ColorShaderClass::ColorShaderClass()
{m_vertexShader = nullptr;m_vertexShaderTable = nullptr;m_pixelShader = nullptr;m_pixelShaderTable = nullptr;
}ColorShaderClass::ColorShaderClass(const ColorShaderClass& other)
{
}ColorShaderClass::~ColorShaderClass()
{
}bool ColorShaderClass::Initialize(IDirect3DDevice9* device)
{TCHAR* vertexShaderPath; TCHAR* pixelShaderPath;DWORD flag;HRESULT result;ID3DXBuffer* tempBuffer;ID3DXBuffer* errorMessage;vertexShaderPath = TEXT("ColorVertexShader.vs");pixelShaderPath = TEXT("ColorPixelShader.ps");flag = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;errorMessage = nullptr;result = ::D3DXCompileShaderFromFile(vertexShaderPath, nullptr, nullptr, "ColorVertexShader", "vs_2_0", flag, &tempBuffer, &errorMessage, &m_vertexShaderTable);if (FAILED(result)){if (errorMessage != nullptr)OutputShaderErrorMessage(errorMessage, vertexShaderPath);else::MessageBox(nullptr, vertexShaderPath, TEXT("Missing Shader File"), MB_OK | MB_ICONERROR);return false;}result = device->CreateVertexShader((DWORD*)tempBuffer->GetBufferPointer(), &m_vertexShader);if (FAILED(result))return false;result = ::D3DXCompileShaderFromFile(pixelShaderPath, nullptr, nullptr, "ColorPixelShader", "ps_2_0", flag, &tempBuffer, &errorMessage, &m_pixelShaderTable);if (FAILED(result)){if (errorMessage != nullptr)OutputShaderErrorMessage(errorMessage, pixelShaderPath);else::MessageBox(nullptr, pixelShaderPath, TEXT("Missing Shader File"), MB_OK | MB_ICONERROR);return false;}result = device->CreatePixelShader((DWORD*)tempBuffer->GetBufferPointer(), &m_pixelShader);if (FAILED(result))return false;return true;
}void ColorShaderClass::Shutdown()
{if (m_vertexShader){m_vertexShader->Release();m_vertexShader = nullptr;}if (m_vertexShaderTable){m_vertexShaderTable->Release();m_vertexShaderTable = nullptr;}if (m_pixelShader){m_pixelShader->Release();m_pixelShader = nullptr;}if (m_pixelShaderTable){m_pixelShaderTable->Release();m_pixelShaderTable = nullptr;}
}bool ColorShaderClass::Render(IDirect3DDevice9* device, float time, IDirect3DTexture9* texture, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{bool result;result = SetShaderParameters(device, time, texture, worldMatrix, viewMatrix, projectionMatrix);if (!result)return false;return true;
}void ColorShaderClass::OutputShaderErrorMessage(ID3DXBuffer* errorMessage, TCHAR* shaderPath)
{char* compileErrors;ULONG bufferSize;ofstream fout;compileErrors = (char*)(errorMessage->GetBufferPointer());bufferSize = errorMessage->GetBufferSize();fout.open("shader-error.txt");for (ULONG i = 0; i < bufferSize; ++i)fout << compileErrors[i];fout.close();errorMessage->Release();errorMessage = nullptr;::MessageBox(nullptr, TEXT("Error compiling shader. Check shader-error.txt for message!"), shaderPath, MB_OK | MB_ICONERROR);
}bool ColorShaderClass::SetShaderParameters(IDirect3DDevice9* device, float time, IDirect3DTexture9* texture, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{HRESULT result;D3DXHANDLE textureHandle;D3DXCONSTANT_DESC textureDesc;UINT count;result = device->SetVertexShader(m_vertexShader);if (FAILED(result))return false;result = device->SetPixelShader(m_pixelShader);if (FAILED(result))return false;result = m_vertexShaderTable->SetMatrix(device, "worldMatrix", &worldMatrix);if (FAILED(result))return false;result = m_vertexShaderTable->SetMatrix(device, "viewMatrix", &viewMatrix);if (FAILED(result))return false;result = m_vertexShaderTable->SetMatrix(device, "projectionMatrix", &projectionMatrix);if (FAILED(result))return false;// The variable of shader must be used, otherwise ID3DXConstantTable can't find itresult = m_pixelShaderTable->SetFloat(device, "time", time);if (FAILED(result))return false;textureHandle = m_pixelShaderTable->GetConstantByName(nullptr, "modelTexture");if (!textureHandle)return false;// The first way to set texture in shader/*result = m_pixelShaderTable->GetConstantDesc(textureHandle, &textureDesc, &count);if (FAILED(result))return false;result = device->SetTexture(textureDesc.RegisterIndex, texture);if (FAILED(result))return false;*/// The second way to set texture in shaderresult = device->SetTexture(m_pixelShaderTable->GetSamplerIndex(textureHandle), texture);if (FAILED(result))return false;return true;
}

[DirectX]DirectX9使用Effect和Vertexshader、PixelShader的区别相关推荐

  1. directx和opengl 电子白板

    画图板的几种方法 1 使用有界面的qt 2 使用mfc 3 c# winform 4 c# wpf 5 使用html5 6 使用opencv 1 是可以跨平台的 2 是不可以跨平台的,和3,4 一起说 ...

  2. Real-Time Rendering 笔记

    里面有些公式和矩阵无法在电脑上书写, 故用纸笔记录了一些笔记, 比如公式的推算, 注意要点等. 由于电子书是黑白图, 不好理解, 所以弄了彩色配图上来 Chapter 1 Introduction 1 ...

  3. Real-time rendering笔记

    Chapter 1 Introduction 1. 实时渲染---图像在计算机上快速的显示 2. 15fps --- 实时渲染的基本fps. 72fps以及更大的fps观察者无法发现其中的差别 60f ...

  4. [转]XNA 3.1 转换到 XNA4.0 的备忘录

    XNA 3.1 转换到 XNA4.0 的备忘录 xna3.1与4.0的区别不小,但也不是很大,在转换一些项目时候下面的tip能给些帮助.原文地址是:http://blogs.msdn.com/b/sh ...

  5. XNA 3.1 转换到 XNA4.0 的备忘录

    本文原创版权归 博客园 Meta.Grfx 所有,转载请详细标明原创作者及出处,以示尊重! 作者:Meta.Grfx 原文:http://www.cnblogs.com/Baesky/archive/ ...

  6. Real-Time Rendering 翻译 3.图形处理单元

    历史上,图形硬件是从渲染管线的末端功能开始发展,最开始进行三角形的光栅化操作.经过成功的迭代,图形硬件从后往前接管渲染管线的功能,直达应用阶段直接向硬件提交数据.硬件相对于软件的唯一优势是速度,但速度 ...

  7. 图形加速卡技术(大众扫盲篇)

    图形加速卡技术论坛:1.入门篇--图形加速之 图形 (发表于GZeasy.com: Jul 20 2003, 04:14 PM) 来了这么久,也对这里的朋友有了一个大概的了解. 恕我罗索一两句,这里的 ...

  8. [资料] [转载] 图形加速卡技术 [专业的基础技术文章]

    图形加速卡技术论坛:1.入门篇--图形加速之 图形 (发表于GZeasy.com: Jul 20 2003, 04:14 PM) 来了这么久,也对这里的朋友有了一个大概的了解. 恕我罗索一两句,这里的 ...

  9. 图形加速卡技术 [专业的基础技术文章]

    最后,感谢下本文的作者,HeavenPR,原文发表在GZ论坛. --------------------------- 图形加速卡技术论坛:1.入门篇--图形加速之 图形 (发表于GZeasy.com ...

最新文章

  1. php chilkat.certstore,angularjs实现冒泡排序算法的可视化
  2. Git各区的添加与撤销[实际操作验证]
  3. 名词解释计算机网络体系结构,计算机网络技术题库(带答案).doc
  4. 【剑指offer】面试题52:两个链表的第一个公共节点(java)
  5. openGauss凝聚创新力量,云和恩墨MogDB加速社区发展
  6. 树莓派连接wifi_「树莓派已入侵工控领域」树莓派工控机助力雷诺汽车连接智能电网...
  7. Linux passwd系统错误,Linux系统处理”passwd: Authentication token manipulation error”错误...
  8. Python基础篇1
  9. SQL Server 2008 R2永久激活秘钥
  10. 大数据导论章节答案_智慧树APP大数据导论第三单元章节测试答案
  11. 梦幻古龙服务器系统,【梦幻XY单机服务端】梦幻古龙一键安装客户端+附搭建安装教程...
  12. 非线性动力学_第17届全国非线性振动暨第14届全国非线性动力学 和运动稳定性学术会议在南京召开...
  13. 任何共享软件作者都能挣到一年10万美金以上的收入,只要他想的话
  14. 有监督学习与无监督学习
  15. 缘,如雁渡寒潭,似风吹疏竹
  16. 负电阻_三极管单管震荡电路
  17. SpeechSynthesisUtterance文字转语音播报
  18. 单电源运放一阶滤波器
  19. python输出hello的字符串字数_python 字符串
  20. 前端基于百度地图实现考勤签到功能

热门文章

  1. 关于麦克风的参数介绍 - 驻极体麦克风(ECM)和硅麦(MEMS)
  2. 详解机器学习中的熵、条件熵、相对熵、交叉熵
  3. JAVA简单编写幸运抽奖
  4. k8s(二):cenos7下搭建k8s集群(kubeamd方式)
  5. Android5.0,6.0,7.0,8.0新特性整理
  6. 01-oracle学习环境配置
  7. 拥有百万粉丝的大牛讲述学Android的历程,附赠课程+题库
  8. 轻松解决 Eclipse Indigo 3.7 中文字体偏小,完美 Consolas 微软雅黑混合字体!
  9. 吴忌寒入选福布斯2019最年轻亿万富豪榜;黑客已将价值近千万EOS偷跑 | 1分钟链圈...
  10. Java开发者跳槽指南面试篇