Posted on 2008-12-14 22:03
Condor 閱讀(2067)
評論(1) 編輯 收藏 引用
上次已經繪制過基本圖元了, 這次只不過要貼張圖而已.....
本來我想用Graphics的Model渲染流程來做, 不過這一層太高級了, 都是什么場景管理資源映射之類的
做低級的事情, 就要用低級的API嘛
圖形渲染的底層是CoreGraphics, 這個層我不打算再單獨寫(翻譯)一篇了, 因為都是Direct3D概念的一些抽象. 也就是說D3D用熟了基本上一看就明白(用GL的我就不清楚啦, 嘿嘿, N3的作者都放棄用GL去實現@_@).
還記得D3D Tutorial中的Textured例子不? 需要的東西有帶紋理坐標的點, 紋理. N3中也一樣, 不過, 這里沒法用固定管線了.
N3的設計的時候就放棄了固定管線(多么明智呀, 別噴我-_-, 我只會shader.......), 所以在這之前我們要先寫一個shader來進行繪制.
因為我們只是進行簡單的演示, 就盡量簡單了, 寫一個2D的紋理繪制, 你可以用來做UI:
- //------------------------------------------------------------------------------
- // texture2d.fx
- // texture shader for 2D(UI)
- // (C) xoyojank
- //------------------------------------------------------------------------------
-
- float2 halfWidthHeight : HalfWidthHeight;
- texture diffMap : DiffMap0;
- sampler diffMapSampler = sampler_state
- {
- Texture = <diffMap>;
- AddressU = Clamp;
- AddressV = Clamp;
- MinFilter = Point;
- MagFilter = Point;
- MipFilter = None;
- };
-
- struct VS_INPUT
- {
- float3 pos : POSITION;
- float2 uv : TEXCOORD;
- };
-
- struct VS_OUTPUT
- {
- float4 pos : POSITION;
- float2 uv : TEXCOORD;
- };
-
- //------------------------------------------------------------------------------
- /**
- */
- VS_OUTPUT
- VertexShaderFunc(VS_INPUT input)
- {
- VS_OUTPUT output;
-
- output.pos.xy = float2(input.pos.x - halfWidthHeight.x, halfWidthHeight.y - input.pos.y) / halfWidthHeight;
- output.pos.zw = float2(input.pos.z, 1.0f);
- output.uv = input.uv;
-
- return output;
- }
-
- //------------------------------------------------------------------------------
- /**
- */
- float4
- PixelShaderFunc(float2 uv : TEXCOORD0) : COLOR
- {
- return tex2D(diffMapSampler, uv);
- }
-
- //------------------------------------------------------------------------------
- /**
- */
- technique Default
- {
- pass p0
- {
- ColorWriteEnable = RED|GREEN|BLUE|ALPHA;
- ZEnable = False;
- ZWriteEnable = False;
- StencilEnable = False;
- FogEnable = False;
- AlphaBlendEnable = True;
- SrcBlend = SrcAlpha;
- DestBlend = InvSrcAlpha;
- AlphaTestEnable = False;
- ScissorTestEnable = False;
- CullMode = CW;
- VertexShader = compile vs_3_0 VertexShaderFunc();
- PixelShader = compile ps_3_0 PixelShaderFunc();
- }
- }
值得一提的是CullMode = CW, 為什么? 因為N3用的右手坐標系, 這點又跟D3D不一樣了........為什么呢? 難道寫MAYA跟MAX的插件的時候比較省事?
還是要跟上一次一樣設置頂點格式并載入VertexBuffer:
- // vertex
- Array<VertexComponent> vertexComponents;
- vertexComponents.Append(VertexComponent(VertexComponent::Position, 0, VertexComponent::Float3));
- vertexComponents.Append(VertexComponent(VertexComponent::TexCoord, 0, VertexComponent::Float2));
- float vertex[4][5] = {
- {0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
- {0.0f, 256.0f, 0.0f, 0.0f, 1.0f},
- {256.0f,0.0f, 0.0f, 1.0f, 0.0f},
- {256.0f,256.0f, 0.0f, 1.0f, 1.0f}
- };
- vertexBuffer = VertexBuffer::Create();
- Ptr<MemoryVertexBufferLoader> vbLoader = MemoryVertexBufferLoader::Create();
- vbLoader->Setup(vertexComponents, 4, vertex, 4 * 5 * sizeof(float));
- vertexBuffer->SetLoader(vbLoader.upcast<ResourceLoader>());
- vertexBuffer->Load();
- vertexBuffer->SetLoader(NULL);
紋理的創建其實跟頂點差不多, 因為它都是屬于資源的一種, 詳見Nebula3資源子系統
- // texture
- texture = Texture::Create();
- texture->SetResourceId(ResourceId("bin:razor.jpg"));
- texture->SetLoader(StreamTextureLoader::Create());
- texture->Load();
- texture->SetLoader(NULL);
shader的加載跟上一次一樣, 只是參數不同:
- // shader
- this->shaderInstance = this->shaderServer->CreateShaderInstance(ResourceId("shd:texture2d"));
- Ptr<ShaderVariable> halfWidthHeight = this->shaderInstance->GetVariableBySemantic(ShaderVariable::Semantic("HalfWidthHeight"));
- float2 halfWH = float2(this->renderDevice->GetDefaultRenderTarget()->GetWidth(), this->renderDevice->GetDefaultRenderTarget()->GetHeight()) * 0.5f;
- halfWidthHeight->SetFloatArray(&halfWH.x(), 2);
- Ptr<ShaderVariable> diffMap = this->shaderInstance->GetVariableBySemantic(ShaderVariable::Semantic("DiffMap0"));
- diffMap->SetTexture(texture);
繪制嘛, 當然改成矩形了, 圖片可貼不到一跟線上:
- this->renderDevice->BeginFrame();
- this->renderDevice->BeginPass(this->renderDevice->GetDefaultRenderTarget(), this->shaderInstance);
- PrimitiveGroup primGroup;
- primGroup.SetBaseVertex(0);
- primGroup.SetNumVertices(4);
- primGroup.SetPrimitiveTopology(PrimitiveTopology::TriangleStrip);
-
- this->renderDevice->SetVertexBuffer(this->vertexBuffer);
- this->renderDevice->SetPrimitiveGroup(primGroup);
- this->renderDevice->Draw();
- this->renderDevice->EndPass();
- this->renderDevice->EndFrame();
- this->renderDevice->Present();
上圖:
