I am new to WebGL. I am trying to draw a triangle using WebGL. But my program is showing nothing in the console window I am getting the following warnings:
WebGL: INVALID_OPERATION: useProgram: program not valid
(index):96 WebGL: INVALID_OPERATION: getAttribLocation: program not linked
(index):107 WebGL: INVALID_OPERATION: drawArrays: no valid shader program in use
Here is my code:
var gl;
var canvas=document.getElementById("painter");
//Step 1 Create gl Context using experimental-webgl at this stage
try
{
gl=canvas.getContext("experimental-webgl");
}catch(e)
{
alert("WebGL not Supported");
}
// Step 2 Creating the vertex shader. Pass the attribute vec4 from application
var shader_vertex_source="\n\
attribute vec4 vPosition; \n\
void main(vaoid) \n\
{\n\
gl_Position=vPosition;\n\
}";
//Step 3: Create Fragment Shader. Must pass precision variable from application. Normally specify medium precision as it should be //supported by all devices
var shader_fragment_source="\n\
precision mediump float;\n\
void main(void)\n\
{\n\
gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n\
}";
// Step 4: Configure view of WebGL
gl.viewport(0,0,canvas.width,canvas.height);
gl.clearColor(1.0,1.0,1.0,1.0);
// Step 5: Create Vertices of Triangle. Each pair represent a point (-1,-1), (0,1), (1,-1) will be three vertices of triangle
var vertice=new Float32Array([-1,-1,0,1,1,-1]);
// Step 6: Compile the shaders.
var get_shader=function(shadersource,shadertype)
{
var shader=gl.createShader(shadertype);
gl.shaderSource(shader,shadersource);
gl.compileShader(shader);
return shader;
}
// Now using the above function get compiled vertex and fragment shaders. The following two varibales are compiled shaders
var vertex_shader=get_shader(shader_vertex_source,gl.VERTEX_SHADER);
var fragment_shader=get_shader(shader_fragment_source,gl.FRAGMENT_SHADER);
// Step 7: Create a Program
var program=gl.createProgram();
// Step 8 : attach the shaders to the program
gl.attachShader(program,vertex_shader);
gl.attachShader(program,fragment_shader);
// Step 9: Link the program with gl context
gl.linkProgram(program);
// Step 10: Tell the gl Context to use the linked program
gl.useProgram(program);
// Step 11: Create Buffer to GPU. Neede for GPU
var buffer=gl.createBuffer();
// Step 12: Bind the created buffer to the gl Context
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
// Step 13: Now send the data to GPU through the buffer. We are going to sent vertice data and drawing info
gl.bufferData(gl.ARRAY_BUFFER,vertice,gl.STATIC_DRAW);
// Step 14: get the position location attirbute from the program using attribute name
var position=gl.getAttribLocation(program,"vPosition");// Our position attribute name is vPosition
// Step 14: Enable the position variable. As it will be used to draw vertices of triangle
gl.enableVertexAttribArray(position);
// Step 15: Tell to use position that gets data from GPU to draw triangle. 2 here mean use two points from the array at a time to //make a vertex
gl.vertexAttribPointer(position,2,gl.FLOAT,false,0,0);
// Step 16 Render using draw methods
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES,0,3);
I am also attaching jsfiddle Link for better help.
I tried your code, but I edited your function get_shader, with a compilation error check:
var get_shader=function(shadersource,shadertype)
{
var shader=gl.createShader(shadertype);
gl.shaderSource(shader,shadersource);
gl.compileShader(shader);
// Check for any compilation error
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
I got the following error:
ERROR: 0:3: 'vaoid' : syntax error
It was coming from your vertex shader:
var shader_vertex_source="\n\
attribute vec4 vPosition; \n\
void main(vaoid) \n\ // RIGHT HERE !
{\n\
gl_Position=vPosition;\n\
}";
So finally it was just a typing mistake.
Related
My metal default library does not contain the vertex and shader functions from the .metal file of the same directory.
Then the library.makeFunction(name: ..) returns nil for both the vertex and shader functions that should be assigned to pipelineDescriptor vars.
The metal file & headers are copied from the Apple Sample App "BasicTexturing" (Creating and Sampling Textures).
The file APPLShaders.metal and APPLShaderTypes.h contain a vertexShader and samplingShader functions that are loaded by an AAPLRenderer.m
In the sample it's really straightforward
id<MTLLibrary> defaultLibrary = [_device newDefaultLibrary];
id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:#"vertexShader"];
id<MTLFunction> fragmentFunction = [defaultLibrary newFunctionWithName:#"samplingShader"];
I have copied these files to a RayWenderlich Swift tutorial and used the swift version
There is an init to set the library
Renderer.library = device.makeDefaultLibrary()
then
let library = Renderer.library
let importVertexFunction = library?.makeFunction(name: "vertexShader")
let importShaderFunction = library?.makeFunction(name: "samplingShader")
This works just fine!
Same thing in my app with the same files copied over and it does not load the functions.
I have checked compileSources in build settings - it lists the metal file.
Comparing everything in settings and don't see a difference between the working apps and my app.
I don't see any error messages or log messages to indicate a syntax or path problem.
Any ideas?
The Apple sample code AAPLShaders.metal
/*
See LICENSE folder for this sample’s licensing information.
Abstract:
Metal shaders used for this sample
*/
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
// Include header shared between this Metal shader code and C code executing Metal API commands
#import "AAPLShaderTypes.h"
// Vertex shader outputs and per-fragment inputs. Includes clip-space position and vertex outputs
// interpolated by rasterizer and fed to each fragment generated by clip-space primitives.
typedef struct
{
// The [[position]] attribute qualifier of this member indicates this value is the clip space
// position of the vertex wen this structure is returned from the vertex shader
float4 clipSpacePosition [[position]];
// Since this member does not have a special attribute qualifier, the rasterizer will
// interpolate its value with values of other vertices making up the triangle and
// pass that interpolated value to the fragment shader for each fragment in that triangle;
float2 textureCoordinate;
} RasterizerData;
// Vertex Function
vertex RasterizerData
vertexShader(uint vertexID [[ vertex_id ]],
constant AAPLVertex *vertexArray [[ buffer(AAPLVertexInputIndexVertices) ]],
constant vector_uint2 *viewportSizePointer [[ buffer(AAPLVertexInputIndexViewportSize) ]])
{
RasterizerData out;
// Index into our array of positions to get the current vertex
// Our positions are specified in pixel dimensions (i.e. a value of 100 is 100 pixels from
// the origin)
float2 pixelSpacePosition = vertexArray[vertexID].position.xy;
// Get the size of the drawable so that we can convert to normalized device coordinates,
float2 viewportSize = float2(*viewportSizePointer);
// The output position of every vertex shader is in clip space (also known as normalized device
// coordinate space, or NDC). A value of (-1.0, -1.0) in clip-space represents the
// lower-left corner of the viewport whereas (1.0, 1.0) represents the upper-right corner of
// the viewport.
// In order to convert from positions in pixel space to positions in clip space we divide the
// pixel coordinates by half the size of the viewport.
out.clipSpacePosition.xy = pixelSpacePosition / (viewportSize / 2.0);
// Set the z component of our clip space position 0 (since we're only rendering in
// 2-Dimensions for this sample)
out.clipSpacePosition.z = 0.0;
// Set the w component to 1.0 since we don't need a perspective divide, which is also not
// necessary when rendering in 2-Dimensions
out.clipSpacePosition.w = 1.0;
// Pass our input textureCoordinate straight to our output RasterizerData. This value will be
// interpolated with the other textureCoordinate values in the vertices that make up the
// triangle.
out.textureCoordinate = vertexArray[vertexID].textureCoordinate;
return out;
}
// Fragment function
fragment float4
samplingShader(RasterizerData in [[stage_in]],
texture2d<half> colorTexture [[ texture(AAPLTextureIndexBaseColor) ]])
{
constexpr sampler textureSampler (mag_filter::linear,
min_filter::linear);
// Sample the texture to obtain a color
const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);
// We return the color of the texture
return float4(colorSample);
}
The Apple Sample code header AAPLShaderTypes.h
/*
See LICENSE folder for this sample’s licensing information.
Abstract:
Header containing types and enum constants shared between Metal shaders and C/ObjC source
*/
#ifndef AAPLShaderTypes_h
#define AAPLShaderTypes_h
#include <simd/simd.h>
// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs match
// Metal API buffer set calls
typedef enum AAPLVertexInputIndex
{
AAPLVertexInputIndexVertices = 0,
AAPLVertexInputIndexViewportSize = 1,
} AAPLVertexInputIndex;
// Texture index values shared between shader and C code to ensure Metal shader buffer inputs match
// Metal API texture set calls
typedef enum AAPLTextureIndex
{
AAPLTextureIndexBaseColor = 0,
} AAPLTextureIndex;
// This structure defines the layout of each vertex in the array of vertices set as an input to our
// Metal vertex shader. Since this header is shared between our .metal shader and C code,
// we can be sure that the layout of the vertex array in the code matches the layout that
// our vertex shader expects
typedef struct
{
// Positions in pixel space (i.e. a value of 100 indicates 100 pixels from the origin/center)
vector_float2 position;
// 2D texture coordinate
vector_float2 textureCoordinate;
} AAPLVertex;
#endif /* AAPLShaderTypes_h */
Debug print of my library
Printing description of self.library:
(MTLLibrary?) library = (object = 0x00006000004af7b0) {
object = 0x00006000004af7b0 {
baseNSObject#0 = {
isa = CaptureMTLLibrary
}
Debug print of working library from RayWenderlich sample app
The new added sampleShader and vertexShader are shown in the library along with the existing fragment and vertex functions.
▿ Optional<MTLLibrary>
- some : <CaptureMTLLibrary: 0x600000f54210> -> <MTLDebugLibrary: 0x600002204050> -> <_MTLLibrary: 0x600001460280>
label = <none>
device = <MTLSimDevice: 0x15a5069d0>
name = Apple iOS simulator GPU
functionNames: fragment_main vertex_main samplingShader vertexShader
Did you check the target membership of file? Your code is nothing to weird so please check the target.
Answer - issue of not loading functions into the metal library is resolved by removing a leftover -fcikernel flag in the Other Metal Compiler Flags option of Build Settings of the project target.
The flag was set when testing a CoreImageKernel.metal as documented in https://developer.apple.com/documentation/coreimage/cikernel/2880194-init
I removed the kernel definition file from the app but missed the compiler flag.. and missed it when visually comparing build settings.
I have a c++/cx project where I'm rendering procedural meshes using DirectX-11, it all seems to work fine, but now I wanted to also import and render meshes from files (from fbx to be exact).
I was told to use the DirectX Toolkit for this.
I followed the tutorials of the toolkit, and that all worked,
but then I tried doing that in my project but it didn't seem to work. The imported mesh was not visible, and the existing procedural meshes were rendered incorrectly (as if without a depth buffer).
I then tried manually rendering the imported mesh (identical to the procedural meshes, without using the Draw function from DirectXTK)
This works better, the existing meshes are all correct, but the imported mesh color's are wrong; I use a custom made vertex and fragment shader, that uses only vertex position and color data, but for some reason the imported mesh's normals are send to shader instead of the vertex-colors.
(I don't even want the normals to be stored in the mesh, but I don't seem to have the option to export to fbx without normals, and even if I remove them manually from the fbx, at import the DirectXTK seem to recalculate the normals)
Does anyone know what I'm doing wrong?
This is all still relatively new to me, so any help appreciated.
If you need more info, just let me know.
Here is my code for rendering meshes:
First the main render function (which is called once every update):
void Track3D::Render()
{
if (!_loadingComplete)
{
return;
}
static const XMVECTORF32 up = { 0.0f, 1.0f, 0.0f, 0.0f };
// Prepare to pass the view matrix, and updated model matrix, to the shader
XMStoreFloat4x4(&_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(_CameraPosition, _CameraLookat, up)));
// Clear the back buffer and depth stencil view.
_d3dContext->ClearRenderTargetView(_renderTargetView.Get(), DirectX::Colors::Transparent);
_d3dContext->ClearDepthStencilView(_depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// Set render targets to the screen.
ID3D11RenderTargetView *const targets[1] = { _renderTargetView.Get() };
_d3dContext->OMSetRenderTargets(1, targets, _depthStencilView.Get());
// Here I render everything:
_TrackMesh->Render(_constantBufferData);
RenderExtra();
_ImportedMesh->Render(_constantBufferData);
Present();
}
The Present-function:
void Track3D::Present()
{
DXGI_PRESENT_PARAMETERS parameters = { 0 };
parameters.DirtyRectsCount = 0;
parameters.pDirtyRects = nullptr;
parameters.pScrollRect = nullptr;
parameters.pScrollOffset = nullptr;
HRESULT hr = S_OK;
hr = _swapChain->Present1(1, 0, ¶meters);
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
OnDeviceLost();
}
else
{
if (FAILED(hr))
{
throw Platform::Exception::CreateException(hr);
}
}
}
Here's the render function which I call on every mesh:
(All of the mesh-specific data is gotten from the imported mesh)
void Mesh::Render(ModelViewProjectionConstantBuffer constantBufferData)
{
if (!_loadingComplete)
{
return;
}
XMStoreFloat4x4(&constantBufferData.model, XMLoadFloat4x4(&_modelMatrix));
// Prepare the constant buffer to send it to the Graphics device.
_d3dContext->UpdateSubresource(
_constantBuffer.Get(),
0,
NULL,
&constantBufferData,
0,
0
);
UINT offset = 0;
_d3dContext->IASetVertexBuffers(
0,
1,
_vertexBuffer.GetAddressOf(),
&_stride,
&_offset
);
_d3dContext->IASetIndexBuffer(
_indexBuffer.Get(),
DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
0
);
_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_d3dContext->IASetInputLayout(_inputLayout.Get());
// Attach our vertex shader.
_d3dContext->VSSetShader(
_vertexShader.Get(),
nullptr,
0
);
// Send the constant buffer to the Graphics device.
_d3dContext->VSSetConstantBuffers(
0,
1,
_constantBuffer.GetAddressOf()
);
// Attach our pixel shader.
_d3dContext->PSSetShader(
_pixelShader.Get(),
nullptr,
0
);
SetTexture();
// Draw the objects.
_d3dContext->DrawIndexed(
_indexCount,
0,
0
);
}
And this is the vertex shader:
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};
struct VertexShaderInput
{
float3 pos : POSITION;
//float3 normal : NORMAL0; //uncommenting these changes the color data for some reason (but always wrong)
//float2 uv1 : TEXCOORD0;
//float2 uv2 : TEXCOORD1;
float3 color : COLOR0;
};
struct VertexShaderOutput
{
float3 color : COLOR0;
float4 pos : SV_POSITION;
};
VertexShaderOutput main(VertexShaderInput input)
{
VertexShaderOutput output;
float4 pos = float4(input.pos, 1.0f);
// Transform the vertex position into projected space.
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;
output.color = input.color;
return output;
}
And this is the pixel shader:
struct PixelShaderInput
{
float3 color: COLOR0;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
return float4(input.color.r, input.color.g, input.color.b, 1);
}
The most likely issue is that you are not setting enough state for your drawing, and that the DirectX Tool Kit drawing functions are setting states that don't match what your existing code requires.
For performance reasons, DirectX Tool Kit does not 'save & restore' state. Instead each draw function sets the state it needs fully and then leaves it. I document which state is impacted in the wiki under the State management section for each class.
Your code above sets the vertex buffer, index buffer, input layout, vertex shader, pixel shader, primitive topology, and VS constant buffer in slot 0.
You did not set blend state, depth/stencil state, or the rasterizer state. You didn't provide the pixel shader so I don't know if you need any PS constant buffers, samplers, or shader resources.
Try explicitly setting the blend state, depth/stencil state, and rasterizer state before you draw your procedural meshes. If you just want to go back to the defined defaults instead of whatever DirectX Tool Kit did, call:
_d3dContext->RSSetState(nullptr);
_d3dContext->OMSetBlendState(nullptr, nullptr, 0);
_d3dContext->OMSetDepthStencilState(nullptr, 0xffffffff);
See also the CommonStates class.
It's generally not a good idea to use identifiers that start with _ in C++. Officially all identifiers that start with _X where X is a capital letter or __ are reserved for the compiler and library implementers so it could conflict with some compiler stuff. m_ or something similar is better.
My code works but i am wondering why !
I have 2 textures :
uniform sampler2D uSampler0;
uniform sampler2D uSampler1;
void main() {
vec4 color0 = texture2D(uSampler0, vTexCoord);
vec4 color1 = texture2D(uSampler1, vTexCoord);
gl_FragColor = color0 * color1;
}
and my js code
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D,my_texture_ZERO);
gl.uniform1i(program.uSampler0,0);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D,my_texture_ONE);
gl.uniform1i(program.uSampler1);
// uncomment one of the 3, it works.
// gl.bindTexture(gl.TEXTURE_2D, my_texture_ZERO);
// gl.bindTexture(gl.TEXTURE_2D, my_texture_ONE);
// gl.bindTexture(gl.TEXTURE_2D, texture_FOR_PURPOSE_ONLY);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
before gl.draw, i have tested the 3 bindings,
each one works !
So, i do not understand the real pipeline underlying .
Thanks for some explanations
This line is invalid
gl.uniform1i(program.uSampler1);
You're not passing a value to the sampler
The way WebGL texture units work is they are global state inside WebGL
gl.activeTexture sets the texture unit all other texture commands effect. For each texture unit there are 2 bind points, TEXTURE_2D and TEXTURE_CUBE_MAP.
You can think of it like this
gl = {
activeTextureUnit: 0,
textureUnits: [
{ TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
{ TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
{ TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
...
],
};
gl.activeTexture just does this
gl.activeTexture = function(unit) {
gl.activeTextureUnit = unit - gl.TEXTURE0;
};
gl.bindTexture does this
gl.bindTexture = function(bindPoint, texture) {
gl.textureUnits[gl.activeTextureUnit][bindPoint] = texture;
};
gl.texImage2D and gl.texParamteri look up which texture to work with like this
gl.texImage2D = function(bindPoint, .....) {
var texture = gl.textureUnits[gl.activeTextureUnit][bindPoint];
// now do something with texture
In other words, inside WebGL there is a global array of texture units. gl.activeTexture and gl.bindTexture manipulate that array.
gl.texXXX manipulate the textures themselves but they reference the textures indirectly through that array.
gl.uniform1i(someSamplerLocation, unitNumber) sets the shader's uniform to look at a particular index in that array of texture units.
It's working correctly because in the presented code you are sending the appropriate uniforms for the samplers.
First texture was set to unit 0 by calling glActiveTexture(GL_TEXTURE0) and was bound afterward. Then a switch was made to unit1.
At that point there were two separate bound textures in each unit.
At the end these units were passed as the uniforms for samplers - which is how to indicate which texture should be in a sampler: in this case passing 0 corresponding to the GL_TEXTURE0 unit to the first uniform and analogousy for the second uniform.
Probably even without uncommenting these lines - things should work.
I am currently creating an objective-c++ IOS OpenGL ES 3.0 3D game engine, but when I try to load shaders, glCreateProgram() returns 0.
I am using #include <OpenGLES/ES3/gl.h> as my OpenGL base.
Here is my code:
m_program = glCreateProgram(); //ERROR
if (m_program == 0)
{
fprintf(stderr, "Error creating shader program\n"); //Catches ERROR
exit(1);
}
std::string vertexShaderText = LoadShader(fileName + ".vs"); //Returns file contents.
std::string fragmentShaderText = LoadShader(fileName + ".fs"); //Returns file contents.
AddVertexShader(vertexShaderText); //Creates and attaches shader to program
AddFragmentShader(fragmentShaderText); //Creates and attaches shader to program
AddAllAttributes(vertexShaderText); //Identifies all attributes in shader and adds them.
CompileShader(); //Compile the program, link the program and use the program
AddShaderUniforms(vertexShaderText); //Identifies all uniforms and adds them.
AddShaderUniforms(fragmentShaderText); //Identifies all uniforms and adds them.
Well basically,I'm not quite sure how to properly use the Set and Get Parameter methods in DX to use the .fx files.I mean I can't find a good tutorial anywhere.I even had a book about D3D9 and while I got most of it,I'm still unable to use effect files.What's worse is the DirectX Samples provided by microsoft are packed with some DX Utility classes by microsoft and all sorts of other needless complications and I can't quite get it trough the 2k lines of code.I mean I get the basic idea(load,begin,loop with passes,end),but can anyone please point me out to a good tutorial on some simple example.The main thing I don't understand is how to work with the effect parameters :(
Here is a reference sheet I wrote back when I was first learning how to use HLSL shaders in DirectX9. Perhaps it will be of assistance.
IN THE APPLICATION:
Declare needed variables:
ID3DXEffect* shader;
Load the .fx file:
D3DXCreateEffectFromFile( d3dDevice,
_T("filepath.fx"),
0,
0,
0,
0,
&shader,
0
);
Clean up the effect object (some people use a SAFE_RELEASE macro):
if(shader)
shader->Release();
shader = nullptr;
Use the shader to render something:
void Application::Render()
{
unsigned passes = 0;
shader->Begin(&passes,0);
for(unsigned i=0;i<passes;++i)
{
shader->BeginPass(i);
// Set uniforms
shader->SetMatrix("gWorld",&theMatrix);
shader->CommitChanges(); // Not necessary if SetWhatevers are done OUTSIDE of a BeginPass/EndPass pair.
/* Insert rendering instructions here */
// BEGIN EXAMPLE:
d3dDevice->SetVertexDeclaration(vertexDecl);
d3dDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERT));
d3dDevice->SetIndices(indexBuffer);
d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,numVerts,0,8);
// END EXAMPLE
shader->EndPass();
}
shader->End();
}
IN THE .FX FILE:
Declare the uniforms (variables you want to set from within the application):
float4x4 gWorld : WORLD;
float4x4 gViewProj : VIEWPROJECTION;
float gTime : TIME;
Texture2D gDiffuseTexture; // requires a matching sampler
sampler gDiffuseSampler = sampler_state // here's the matching sampler
{
Texture = <gDiffuseTexture>;
FILTER = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
Define the vertex shader input structure:
struct VS_INPUT // make this match the vertex structure in Application
{
float3 untransformed_pos : POSITION0;
float3 untransformed_nrm : NORMAL0;
float4 color : COLOR0;
float2 uv_coords : TEXCOORD0;
};
Define the pixel shader input structure (vertex shader output):
struct PS_INPUT
{
float4 transformed_pos : POSITION0;
float4 transformed_nrm : NORMAL0;
float4 color : COLOR0;
float2 uv_coords : TEXCOORD0;
};
Define a vertex shader:
PS_INPUT mainVS (VS_INPUT input)
{
PS_INPUT output;
/* Insert shader instructions here */
return output;
}
Define a pixel shader:
float4 mainPS (PS_INPUT input) : COLOR
{
/* Insert shader instructions here */
return float4(resultColor,1.0f);
}
Define a technique:
technique myTechnique
{
// Here is a quick sample
pass FirstPass
{
vertexShader = compile vs_3_0 mainVS();
pixelShader = compile ps_3_0 mainPS();
// Setting a few of the many D3D renderstates via the effect framework
ShadeMode = FLAT; // flat color interpolation across triangles
FillMode = SOLID; // no wireframes, no point drawing.
CullMode = CCW; // cull any counter-clockwise polygons.
}
}
Can you be a bit more specific about where you're having problems?
The basic idea with the API for Effect parameters is to load your .fx file and then use ID3DXEffect::GetParameterByName() or GetParameterBySemantic() to retrieve a D3DXHANDLE to the parameters you want to modify at runtime. Then in your render loop you can set the values for those parameters using the ID3DXEffect::SetXXX() family of functions (which one you use depends on the type of the parameter you are setting, e.g. Float, Vector, Matrix), passing the D3DXHANDLE you retrieved when you loaded the effect.
The reason you work with D3DXHANDLEs and not directly with parameter name strings is performance - it saves doing lots of string compares in your render loop to look up parameters.
A simple example of how you might use this is defining a texture2D parameter called diffuseTex in your .fx file. When you load the .fx file, use
D3DXHANDLE diffuseTexHandle = effect->GetParameterByName(NULL, "diffuseTex");
and then in your render loop set the appropriate diffuse texture for each model you draw using
LPDIRECT3DTEXTURE9 diffuseTexturePtr = GetMeTheRightTexturePlease();
ID3DXEffect::SetTexture(diffuseTexHandle, diffuseTexturePtr);