frame.setIgnoreRepaint(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// Create device
final ID3D11Device device = D3D11CreateDevice(null,
D3D_DRIVER_TYPE_HARDWARE,
0,
new D3D_FEATURE_LEVEL[] { D3D_FEATURE_LEVEL_11_0 });
final ID3D11DeviceContext immediateContext = device.GetImmediateContext();
IDXGIDevice1 dxgiDevice = device.QueryInterface(IDXGIDevice1.class);
IDXGIFactory1 dxgiFactory= dxgiDevice.GetParent(IDXGIAdapter1.class)
.GetParent(IDXGIFactory1.class);
final IDXGISwapChain swapChain = dxgiFactory.CreateSwapChain(dxgiDevice, DXGI.SwapChainDescription(frame));
dxgiDevice.Release();
dxgiFactory.Release();
ID3D11Texture2D backBuffer = swapChain.GetBuffer(0, ID3D11Texture2D.class);
final ID3D11RenderTargetView rtView = device.CreateRenderTargetView(backBuffer, null);
backBuffer.Release();
immediateContext.OMSetRenderTargets(rtView, null);
immediateContext.RSSetViewport(new D3D11_VIEWPORT(frame.getWidth(), frame.getHeight()));
// Shader
String shaders = "cbuffer perFrame : register( b0 ) \n" +
"{ \n" +
" matrix world; \n" +
"} \n" +
" \n" +
"float4 VS( float4 Pos : POSITION ) : SV_POSITION \n" +
"{ \n" +
" return mul(Pos, world); \n" +
"} \n" +
" \n" +
"float4 PS( float4 Pos : SV_POSITION ) : SV_Target \n" +
"{ \n" +
" return float4( 0.0f, 1.0f, 0.0f, 1.0f ); \n" +
"}";
// Compiling for vertex shader and input layout
ID3D10Blob code = D3DCompile(shaders, null, null, null, "VS", "vs_5_0", 0, 0);
// Create input layout
D3D11_INPUT_ELEMENT_DESC layoutDesc = new D3D11_INPUT_ELEMENT_DESC("POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0);
final ID3D11InputLayout layout = device.CreateInputLayout(new D3D11_INPUT_ELEMENT_DESC[] { layoutDesc }, code);
immediateContext.IASetInputLayout(layout);
// Creating vertex shader
final ID3D11VertexShader vs = device.CreateVertexShader(code, null);
code.Release();
// Creating pixel shader
code = D3DCompile(shaders, null, null, null, "PS", "ps_5_0", 0, 0);
final ID3D11PixelShader ps = device.CreatePixelShader(code, null);
code.Release();
// Create vertex buffer
D3D11_BUFFER_DESC bufferDesc = new D3D11_BUFFER_DESC(D3D11_BIND_VERTEX_BUFFER,
D3D11_USAGE_DEFAULT,
D3D11_CPU_ACCESS_NONE,
0,
(int)(9 * sizeOf(Float.class)));
D3D11_SUBRESOURCE_DATA initData = new D3D11_SUBRESOURCE_DATA();
initData.pSysMem(pointerToFloats(0.0f, 1.0f, 0.5f, 1f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f));
initData.SysMemPitch(0).SysMemSlicePitch(0);
final ID3D11Buffer vertexBuffer = device.CreateBuffer(bufferDesc, initData);
delete(initData); // Delete data of regain memory
// Create constant buffer (size must be multiple of 16)
bufferDesc.BindFlags(D3D11_BIND_CONSTANT_BUFFER);
bufferDesc.Usage(D3D11_USAGE_DYNAMIC);
bufferDesc.CPUAccessFlags(D3D11_CPU_ACCESS_WRITE);
bufferDesc.ByteWidth((int) sizeOf(D3DXMATRIX.class));
final ID3D11Buffer constBuffer = device.CreateBuffer(bufferDesc, null);
final AtomicInteger angle = new AtomicInteger(0);
final D3DXMATRIX mat = new D3DXMATRIX();
D3DXMatrixIdentity(pointerTo(mat));
JNIEnv env = JAWTUtils.getJNIEnv();
JAWT jawt = JAWTUtils.getJAWT(env);
while(frame.isEnabled()) {
if(frame.isVisible())
/*
* Drawing shall occur inside this methods, to prevent deadlock between
* Java drawing and native drawing
*/
JAWTUtils.withLockedSurface(env, jawt, frame, new LockedComponentRunnable() {
@Override
public void run(Component comp, long peer) {
// Clear screen
immediateContext.ClearRenderTargetView(pointerTo(rtView), pointerToFloats(0.0f, 0.125f, 0.3f, 1.0f));
// Set vertex buffer
int stride = (int) (sizeOf(Float.class) * 3);
immediateContext.IASetVertexBuffers(0, 1, pointerToPointer(pointerTo(vertexBuffer)), pointerToInt(stride), pointerToInt(0));
// Set shaders and input layout
immediateContext.IASetInputLayout(layout);
immediateContext.VSSetShader(pointerTo(vs), null, 0);
immediateContext.PSSetShader(pointerTo(ps), null, 0);
// Update rotation matrix for triangle
D3DXMatrixRotationZ(pointerTo(mat), angle.addAndGet(1) * 0.01f);
D3D11_MAPPED_SUBRESOURCE mappedData = immediateContext.Map(constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0);
pointerTo(mat).copyTo(mappedData.pData());
immediateContext.Unmap(constBuffer, 0);
immediateContext.VSSetConstantBuffers(0, 1, pointerToPointer(pointerTo(constBuffer)));
// Set primitive topology and draw
immediateContext.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
immediateContext.Draw(3, 0);
// Present to screen
swapChain.Present(0, 0);
}
});
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
vs.Release();
ps.Release();
layout.Release();
vertexBuffer.Release();
swapChain.Release();
device.Release();
}