Last active
December 1, 2023 20:17
-
-
Save pJotoro/72d88ce6fcc4cfd016e67704455f83de to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "jo:app" | |
import win32 "core:sys/windows" | |
import "vendor:directx/d3d11" | |
import "vendor:directx/d3d_compiler" | |
import "vendor:directx/dxgi" | |
D3D11_Context :: struct { | |
device: ^d3d11.IDevice1, | |
device_context: ^d3d11.IDeviceContext1, | |
dxgi_device: ^dxgi.IDevice1, | |
dxgi_adapter: ^dxgi.IAdapter, | |
dxgi_factory: ^dxgi.IFactory2, | |
swap_chain: ^dxgi.ISwapChain1, | |
framebuffer_texture: ^d3d11.ITexture2D, | |
framebuffer_render_target_view: ^d3d11.IRenderTargetView, | |
} | |
d3d11_init :: proc(using ctx: ^D3D11_Context) -> (hr: win32.HRESULT) { | |
feature_levels := [?]d3d11.FEATURE_LEVEL{._11_0} | |
{ | |
base_device: ^d3d11.IDevice | |
base_device_context: ^d3d11.IDeviceContext | |
d3d11_flags := d3d11.CREATE_DEVICE_FLAGS{.SINGLETHREADED, .BGRA_SUPPORT} | |
when ODIN_DEBUG { | |
d3d11_flags += {.DEBUG} | |
} | |
hr = d3d11.CreateDevice(nil, .HARDWARE, nil, d3d11_flags, raw_data(&feature_levels), u32(len(feature_levels)), d3d11.SDK_VERSION, &base_device, nil, &base_device_context) | |
if hr != 0 do return | |
hr = base_device->QueryInterface(d3d11.IDevice1_UUID, (^rawptr)(&device)) | |
if hr != 0 do return | |
hr = base_device_context->QueryInterface(d3d11.IDeviceContext1_UUID, (^rawptr)(&device_context)) | |
if hr != 0 do return | |
} | |
hr = device->QueryInterface(dxgi.IDevice1_UUID, (^rawptr)(&dxgi_device)) | |
if hr != 0 do return | |
hr = dxgi_device->GetAdapter(&dxgi_adapter) | |
if hr != 0 do return | |
hr = dxgi_adapter->GetParent(dxgi.IFactory2_UUID, (^rawptr)(&dxgi_factory)) | |
if hr != 0 do return | |
{ | |
desc := dxgi.SWAP_CHAIN_DESC1{ | |
Format = .B8G8R8A8_UNORM, | |
SampleDesc = {Count = 1}, | |
BufferUsage = {.RENDER_TARGET_OUTPUT}, | |
BufferCount = 2, | |
SwapEffect = .FLIP_DISCARD, | |
} | |
hr = dxgi_factory->CreateSwapChainForHwnd(device, win32.HWND(app.window()), &desc, nil, nil, &swap_chain) | |
if hr != 0 do return | |
swap_chain->GetDesc1(&desc) | |
assert(int(desc.Width) == app.width()) | |
assert(int(desc.Height) == app.height()) | |
} | |
hr = swap_chain->GetBuffer(0, d3d11.ITexture2D_UUID, (^rawptr)(&framebuffer_texture)) | |
if hr != 0 do return | |
hr = device->CreateRenderTargetView(framebuffer_texture, nil, &framebuffer_render_target_view) | |
if hr != 0 do return | |
return | |
} | |
d3d11_create_buffer :: proc(using ctx: ^D3D11_Context, byte_width: u32, usage: d3d11.USAGE, bind_flags: d3d11.BIND_FLAGS, cpu_access_flags: d3d11.CPU_ACCESS_FLAGS, misc_flags: d3d11.RESOURCE_MISC_FLAGS, structure_byte_stride: u32, memory: rawptr, memory_pitch, memory_slice_pitch: u32) -> (buffer: ^d3d11.IBuffer, hr: win32.HRESULT) { | |
desc := d3d11.BUFFER_DESC{ | |
ByteWidth = byte_width, | |
Usage = usage, | |
BindFlags = bind_flags, | |
CPUAccessFlags = cpu_access_flags, | |
MiscFlags = misc_flags, | |
StructureByteStride = structure_byte_stride, | |
} | |
subresource_data := d3d11.SUBRESOURCE_DATA{ | |
pSysMem = memory, | |
SysMemPitch = memory_pitch, | |
SysMemSlicePitch = memory_slice_pitch, | |
} | |
hr = device->CreateBuffer(&desc, memory != nil ? &subresource_data : nil, &buffer) | |
return | |
} | |
d3d11_compile :: proc(file_data: []byte, src_name, entry, target: cstring, loc := #caller_location) -> (blob: ^d3d_compiler.ID3D10Blob, hr: win32.HRESULT) { | |
hr = d3d_compiler.Compile(raw_data(file_data), len(file_data), src_name, nil, nil, entry, target, 0, 0, &blob, nil) | |
return | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package directx_d3d11 | |
import win32 "core:sys/windows" | |
LPCWSTR :: win32.LPCWSTR | |
DWORD :: win32.DWORD | |
IDevice1_UUID_STRING :: "a04bfb29-08ef-43d6-a49c-a9bdbdcbe686" | |
IDevice1_UUID := &IID{0xa04bfb29, 0x08ef, 0x43d6, {0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86}} | |
IDevice1 :: struct #raw_union { | |
#subtype idevice: IDevice, | |
using id3d11device1_vtable: ^IDevice1_VTable, | |
} | |
IDevice1_VTable :: struct { | |
using idevice_vtable: IDevice_VTable, | |
CreateBlendState1: proc "stdcall" (this: ^IDevice1, pBlendStateDesc: ^BLEND_DESC1, ppBlendState: ^^IBlendState1) -> HRESULT, | |
CreateDeferredContext1: proc "stdcall" (this: ^IDevice1, ContextFlags: UINT, ppDeferredContext: ^^IDeviceContext1) -> HRESULT, | |
CreateDeviceContextState: proc "stdcall" (this: ^IDevice1, Flags: UINT, pFeatureLevels: [^]FEATURE_LEVEL, FeatureLevels: UINT, SDKVersion: UINT, EmulatedInterface: ^IID, pChosenFeatureLevel: ^FEATURE_LEVEL, ppContextState: ^^IDeviceContextState) -> HRESULT, | |
CreateRasterizerState1: proc "stdcall" (this: ^IDevice1, pRasterizerDesc: ^RASTERIZER_DESC1, ppRasterizerState: ^^IRasterizerState1) -> HRESULT, | |
GetImmediateContext1: proc "stdcall" (this: ^IDevice1, ppImmediateContext: ^^IDeviceContext1),\ | |
OpenSharedResource1: proc "stdcall" (this: ^IDevice1, hResource: HANDLE, returnedInterface: ^IID, ppResource: ^rawptr) -> HRESULT, | |
OpenSharedResourceByName: proc "stdcall" (this: ^IDevice1, lpName: LPCWSTR, dwDesiredAccess: DWORD, returnedInterface: ^IID, ppResource: ^rawptr) -> HRESULT, | |
} | |
LOGIC_OP :: enum i32 { | |
CLEAR = 0, | |
SET, | |
COPY, | |
COPY_INVERTED, | |
NOOP, | |
INVERT, | |
AND, | |
NAND, | |
OR, | |
NOR, | |
XOR, | |
EQUIV, | |
AND_REVERSE, | |
AND_INVERTED, | |
OR_REVERSE, | |
OR_INVERTED, | |
} | |
RENDER_TARGET_BLEND_DESC1 :: struct { | |
BlendEnable: BOOL, | |
LogicOpEnable: BOOL, | |
SrcBlend: BLEND, | |
DestBlend: BLEND, | |
BlendOp: BLEND_OP, | |
SrcBlendAlpha: BLEND, | |
DestBlendAlpha: BLEND, | |
BlendOpAlpha: BLEND_OP, | |
LogicOp: LOGIC_OP, | |
RenderTargetWriteMask: u8, | |
} | |
BLEND_DESC1 :: struct { | |
AlphaToCoverageEnable: BOOL, | |
IndependentBlendEnable: BOOL, | |
RenderTarget: [8]RENDER_TARGET_BLEND_DESC1, | |
} | |
IBlendState1_UUID_STRING :: "CC86FABE-DA55-401D-85E7-E3C9dE2877E9" | |
IBlendState1_UUID := &IID{0xCC86FABE, 0xDA55, 0x401D, {0x85, 0xE7, 0xE3, 0xC9, 0xdE, 0x28, 0x77, 0xE9}} | |
IBlendState1 :: struct #raw_union { | |
#subtype id3d11blendstate: IBlendState, | |
using id3d11blendstate1_vtable: ^IBlendState1_VTable, | |
} | |
IBlendState1_VTable :: struct { | |
using id3d11blendstate_vtable: IBlendState_VTable, | |
GetDesc1: proc "stdcall" (this: ^IBlendState1, pDesc: ^BLEND_DESC1), | |
} | |
IDeviceContext1_UUID_STRING :: "BB2C6fAA-B5FB-4082-8E6B-388B8CFA90E1" | |
IDeviceContext1_UUID := &IID{0xBB2C6FAA, 0xB5FB, 0x4082, {0x8E, 0x6B, 0x38, 0x8B, 0x8C, 0xFA, 0x90, 0xE1}} | |
IDeviceContext1 :: struct #raw_union { | |
#subtype id3d11devicecontext: IDeviceContext, | |
using id3d11devicecontext1_vtable: ^IDeviceContext1_VTable, | |
} | |
IDeviceContext1_VTable :: struct { | |
using id3d11devicecontext_vtable: IDeviceContext_VTable, | |
ClearView: proc "stdcall" (this: ^IDeviceContext1, pView: ^IView, Color: [^]f32, pRect: ^RECT, NumRects: UINT), | |
CopySubresourceRegion1: proc "stdcall" (this: ^IDeviceContext1, pDstResource: ^IResource, DstSubresource: UINT, DstX: UINT, DstY: UINT, DstZ: UINT, pSrcResource: ^IResource, SrcSubresource: UINT, pSrcBox: ^BOX, CopyFlags: UINT), | |
CSGetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
CSSetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
DiscardResource: proc "stdcall" (this: ^IDeviceContext1, pResource: ^IResource), | |
DiscardView: proc "stdcall" (this: ^IDeviceContext1, pResourceView: ^IView), | |
DiscardView1: proc "stdcall" (this: ^IDeviceContext1, pResourceView: ^IView, pRects: [^]RECT, NumRects: UINT), | |
DSGetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
DSSetConstantBuffesr1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
GSGetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
GSSetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
HSGetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
HSSetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
PSGetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
PSSetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
SwapDeviceContextState: proc "stdcall" (this: ^IDeviceContext1, pState: ^IDeviceContextState, ppPreviousState: ^^IDeviceContextState), | |
UpdateSubresource1: proc "stdcall" (this: ^IDeviceContext1, pDstResource: ^IResource, DstSubresource: UINT, pDstBox: ^BOX, pSrcData: rawptr, SrcRowPitch: UINT, SrcDepthPitch: UINT, CopyFlags: UINT), | |
VSGetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
VSSetConstantBuffers1: proc "stdcall" (this: ^IDeviceContext1, StartSlot: UINT, NumBuffers: UINT, ppConstantBuffers: [^]^IBuffer, pFirstConstant: ^UINT, pNumConstants: ^UINT), | |
} | |
IDeviceContextState_UUID_STRING :: "5C1E0D8A-7C23-48F9-8C59-A92958CEFF11" | |
IDeviceContextState_UUID := &IID{0x5C1E0D8A, 0x7C23, 0x48F9, {0x8C, 0x59, 0xA9, 0x29, 0x58, 0xCE, 0xFF, 0x11}} | |
IDeviceContextState :: struct #raw_union { | |
#subtype id3d11devicechild: IDeviceChild, | |
using id3d11devicecontextstate_vtable: ^IDeviceContextState_VTable, | |
} | |
IDeviceContextState_VTable :: struct { | |
using id3d11devicechild_vtable: IDeviceChild_VTable, | |
} | |
IRasterizerState1_UUID_STRING :: "1217D7A6-5039-418C-B042-9CBE256AFD6E" | |
IRasterizerState1_UUID := &IID{0x1217D7A6, 0x5039, 0x418C, {0xB0, 0x42, 0x9C, 0xBE, 0x25, 0x6A, 0xFD, 0x6E}} | |
IRasterizerState1 :: struct #raw_union { | |
#subtype id3d11rasterizerstate: IRasterizerState, | |
using id3d11rasterizerstate1_vtable: ^IRasterizerState1_VTable, | |
} | |
IRasterizerState1_VTable :: struct { | |
using id3d11rasterizerstate_vtable: IRasterizerState_VTable, | |
GetDesc1: proc "stdcall" (this: ^IRasterizerState1, pDesc: ^RASTERIZER_DESC1), | |
} | |
RASTERIZER_DESC1 :: struct { | |
FillMode: FILL_MODE, | |
CullMode: CULL_MODE, | |
FrontCounterClockwise: BOOL, | |
DepthBias: i32, | |
DepthBiasClamp: f32, | |
SlopeScaledDepthBias: f32, | |
DepthClipEnable: BOOL, | |
ScissorEnable: BOOL, | |
MultisampleEnable: BOOL, | |
AntialiasedLineEnable: BOOL, | |
ForcedSampleCount: UINT, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "jo:app" | |
import "core:image/png" | |
import "core:os" | |
import "vendor:directx/d3d11" | |
import "vendor:directx/d3d_compiler" | |
main :: proc() { | |
app.init() | |
img, err := png.load("assets/jonar_idle.png") | |
assert(err == nil) | |
assert(img.channels == 4) | |
using ctx: D3D11_Context | |
hr := d3d11_init(&ctx) | |
assert(hr == 0) | |
constant_buffer: ^d3d11.IBuffer | |
constant_data := [4]f32{2 / f32(app.width()), -2 / f32(app.height()), 1 / 128, 1 / 128} | |
constant_buffer, hr = d3d11_create_buffer(&ctx, size_of(constant_data) + 0xf & 0xfffffff0, .IMMUTABLE, {.CONSTANT_BUFFER}, nil, nil, 0, raw_data(&constant_data), 0, 0) | |
assert(hr == 0) | |
atlas_texture: ^d3d11.ITexture2D | |
{ | |
desc := d3d11.TEXTURE2D_DESC{ | |
Width = u32(img.width), | |
Height = u32(img.height), | |
MipLevels = 1, | |
ArraySize = 1, | |
Format = .R8G8B8A8_UNORM, | |
SampleDesc = {Count = 1}, | |
Usage = .IMMUTABLE, | |
BindFlags = {.SHADER_RESOURCE}, | |
} | |
atlas_subresource_data := d3d11.SUBRESOURCE_DATA{ | |
pSysMem = raw_data(img.pixels.buf[:]), | |
SysMemPitch = u32(img.width * size_of(u32)), | |
} | |
hr = device->CreateTexture2D(&desc, &atlas_subresource_data, &atlas_texture) | |
assert(hr == 0) | |
} | |
atlas_shader_resource_view: ^d3d11.IShaderResourceView | |
{ | |
hr = device->CreateShaderResourceView(atlas_texture, nil, &atlas_shader_resource_view) | |
assert(hr == 0) | |
} | |
Sprite :: struct { | |
screen_pos, size, atlas_pos: [2]i32, | |
} | |
MAX_SPRITES :: 4096 | |
sprite_buffer: ^d3d11.IBuffer | |
sprite_buffer, hr = d3d11_create_buffer(&ctx, size_of(Sprite) * MAX_SPRITES, .DYNAMIC, {.SHADER_RESOURCE}, {.WRITE}, {.BUFFER_STRUCTURED}, size_of(Sprite), nil, 0, 0) | |
assert(hr == 0) | |
sprite_shader_resource_view: ^d3d11.IShaderResourceView | |
{ | |
desc := d3d11.SHADER_RESOURCE_VIEW_DESC{ | |
Format = .UNKNOWN, | |
ViewDimension = .BUFFER, | |
Buffer = {NumElements = MAX_SPRITES}, | |
} | |
hr = device->CreateShaderResourceView(sprite_buffer, &desc, &sprite_shader_resource_view) | |
assert(hr == 0) | |
} | |
point_sampler: ^d3d11.ISamplerState | |
{ | |
desc := d3d11.SAMPLER_DESC{ | |
Filter = .MIN_MAG_MIP_POINT, | |
AddressU = .CLAMP, | |
AddressV = .CLAMP, | |
AddressW = .CLAMP, | |
ComparisonFunc = .NEVER, | |
} | |
hr = device->CreateSamplerState(&desc, &point_sampler) | |
assert(hr == 0) | |
} | |
vs_blob, ps_blob: ^d3d_compiler.ID3D10Blob | |
{ | |
file_data, ok := os.read_entire_file("src/shaders.hlsl", context.temp_allocator) | |
assert(ok) | |
vs_blob, hr = d3d11_compile(file_data, "shaders.hlsl", "vs", "vs_5_0") | |
assert(hr == 0) | |
ps_blob, hr = d3d11_compile(file_data, "shaders.hlsl", "ps", "ps_5_0") | |
assert(hr == 0) | |
} | |
vertex_shader: ^d3d11.IVertexShader | |
hr = device->CreateVertexShader(vs_blob->GetBufferPointer(), vs_blob->GetBufferSize(), nil, &vertex_shader) | |
assert(hr == 0) | |
pixel_shader: ^d3d11.IPixelShader | |
hr = device->CreatePixelShader(ps_blob->GetBufferPointer(), ps_blob->GetBufferSize(), nil, &pixel_shader) | |
assert(hr == 0) | |
clear_color := [4]f32{0.1725, 0.1725, 0.1725, 1} | |
framebuffer_viewport := d3d11.VIEWPORT{0, 0, f32(app.width()), f32(app.height()), 0, 1} | |
sprite_batch := make([dynamic]Sprite, 0, MAX_SPRITES) | |
frame := 0 | |
tick := 0 | |
pos: [2]f32 | |
for !app.should_close() { | |
if app.key_pressed(.Escape) do return | |
pos += app.gamepad_left_stick(0) | |
tick += 1 | |
if tick == 20 { | |
tick = 0 | |
frame += 1 | |
if frame > 6 do frame = 0 | |
} | |
clear(&sprite_batch) | |
sprite := Sprite{ | |
screen_pos = {100, 100}, | |
size = {128, 128}, | |
atlas_pos = {i32(frame * 128), 0}, | |
} | |
append(&sprite_batch, sprite) | |
sprite_buffer_mapped_subresource: d3d11.MAPPED_SUBRESOURCE | |
hr = device_context->Map(sprite_buffer, 0, .WRITE_DISCARD, nil, &sprite_buffer_mapped_subresource) | |
assert(hr == 0) | |
copy(([^]Sprite)(sprite_buffer_mapped_subresource.pData)[:len(sprite_batch)], sprite_batch[:]) | |
device_context->Unmap(sprite_buffer, 0) | |
device_context->OMSetRenderTargets(1, &framebuffer_render_target_view, nil) | |
device_context->ClearRenderTargetView(framebuffer_render_target_view, &clear_color) | |
device_context->IASetPrimitiveTopology(.TRIANGLESTRIP) | |
device_context->VSSetShader(vertex_shader, nil, 0) | |
device_context->VSSetShaderResources(0, 1, &sprite_shader_resource_view) | |
device_context->VSSetConstantBuffers(0, 1, &constant_buffer) | |
device_context->RSSetViewports(1, &framebuffer_viewport) | |
device_context->PSSetShader(pixel_shader, nil, 0) | |
device_context->PSSetShaderResources(1, 1, &atlas_shader_resource_view) | |
device_context->PSSetSamplers(0, 1, &point_sampler) | |
device_context->DrawInstanced(4, u32(len(sprite_batch)), 0, 0) | |
hr = swap_chain->Present(1, 0) | |
assert(hr == 0) | |
free_all(context.temp_allocator) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define FAT_PIXEL_SIZE 4 | |
cbuffer constants : register(b0) | |
{ | |
float2 rn_screensize; | |
float2 r_atlassize; | |
} | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
struct sprite | |
{ | |
int2 screenpos; | |
int2 size; | |
int2 atlaspos; | |
}; | |
struct pixel | |
{ | |
float4 xy : SV_POSITION; | |
float2 uv : UV; | |
}; | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
StructuredBuffer<sprite> spritebuffer : register(t0); | |
Texture2D<float4> atlastexture : register(t1); | |
SamplerState pointsampler : register(s0); | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
pixel vs(uint spriteid : SV_INSTANCEID, uint vertexid : SV_VERTEXID) | |
{ | |
sprite spr = spritebuffer[spriteid]; | |
float4 pos = float4(spr.screenpos, spr.screenpos + spr.size); // * FAT_PIXEL_SIZE | |
float4 tex = float4(spr.atlaspos, spr.atlaspos + spr.size); | |
uint2 i = { vertexid & 2, (vertexid << 1 & 2) ^ 3 }; | |
pixel p; | |
p.xy = float4(float2(pos[i.x], pos[i.y]) * rn_screensize - float2(1, -1), 0, 1); | |
p.uv = float2(tex[i.x], tex[i.y]) * r_atlassize; | |
return p; | |
} | |
float4 ps(pixel p) : SV_TARGET | |
{ | |
float4 color = atlastexture.Sample(pointsampler, p.uv); | |
if (color.a == 0) discard; | |
return color; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment