Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,841 @@
#include <kinc/display.h>
#include <kinc/graphics4/graphics.h>
#include <kinc/graphics4/indexbuffer.h>
#include <kinc/graphics4/pipeline.h>
#include <kinc/graphics4/shader.h>
#include <kinc/graphics4/texture.h>
#include <kinc/graphics4/vertexbuffer.h>
#include <kinc/math/core.h>
#undef CreateWindow
#include <kinc/system.h>
#include <kinc/window.h>
#include <kinc/backend/SystemMicrosoft.h>
#include <kinc/backend/Windows.h>
#include <kinc/log.h>
#include <vector>
#include "Direct3D9.h"
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 device;
namespace {
HWND hWnd;
int _width;
int _height;
unsigned hz;
bool vsync;
bool resizable;
D3DVIEWPORT9 vp;
bool swapBuffers() {
HRESULT result;
if (resizable) {
RECT vRect;
GetClientRect(hWnd, &vRect);
result = device->Present(&vRect, &vRect, 0, 0);
}
else {
result = device->Present(0, 0, 0, 0);
}
return result != D3DERR_DEVICELOST;
}
kinc_g4_shader_t *pixelShader = nullptr;
kinc_g4_shader_t *vertexShader = nullptr;
IDirect3DSurface9 *backBuffer = nullptr;
IDirect3DSurface9 *depthBuffer = nullptr;
void initDeviceStates() {
D3DCAPS9 caps;
device->GetDeviceCaps(&caps);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
#ifndef USE_SHADER
device->SetRenderState(D3DRS_LIGHTING, FALSE);
#endif
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
#ifndef USE_SHADER
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
kinc_microsoft_affirm(device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE));
kinc_microsoft_affirm(device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE));
#endif
// if (d3dpp.Windowed != TRUE) Cursor->Hide();
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
for (int i = 0; i < 16; ++i) {
device->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
device->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
device->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
device->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, caps.MaxAnisotropy);
}
device->SetSamplerState(D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
device->SetSamplerState(D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
device->SetRenderState(D3DRS_ZENABLE, FALSE);
device->Clear(0, 0, D3DCLEAR_TARGET, 0, 0, 0);
}
}
void kinc_g4_internal_destroy_window(int window) {}
void kinc_g4_internal_destroy() {}
extern "C" void kinc_internal_resize(int width, int height) {
if (!resizable) {
return;
}
_width = width;
_height = height;
kinc_g4_viewport(0, 0, width, height);
/*D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = (!fullscreen) ? TRUE : FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferCount = 2;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; //D3DPRESENT_INTERVAL_IMMEDIATE;
if (antialiasing()) {
if (SUCCEEDED(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_4_SAMPLES, nullptr)))
d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
if (SUCCEEDED(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_8_SAMPLES, nullptr)))
d3dpp.MultiSampleType = D3DMULTISAMPLE_8_SAMPLES;
}
else {
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
}
device->Reset(&d3dpp);
initDeviceStates();*/
}
extern "C" void kinc_internal_change_framebuffer(int window, struct kinc_framebuffer_options *frame) {}
void kinc_g4_internal_init() {}
void kinc_g4_internal_init_window(int windowId, int depthBufferBits, int stencilBufferBits, bool vsync) {
bool fullscreen = kinc_window_get_mode(windowId) == KINC_WINDOW_MODE_FULLSCREEN || kinc_window_get_mode(windowId) == KINC_WINDOW_MODE_EXCLUSIVE_FULLSCREEN;
d3d = Direct3DCreate9(D3D_SDK_VERSION);
hWnd = kinc_windows_window_handle(windowId);
long style = GetWindowLong(hWnd, GWL_STYLE);
resizable = false;
if ((style & WS_SIZEBOX) != 0) {
resizable = true;
}
if ((style & WS_MAXIMIZEBOX) != 0) {
resizable = true;
}
// TODO (DK) just setup the primary window for now and ignore secondaries
// -this should probably be implemented via swap chain for real at a later time
// -http://www.mvps.org/directx/articles/rendering_to_multiple_windows.htm
if (windowId > 0) {
return;
}
#ifdef KINC_WINDOWS
// TODO (DK) convert depthBufferBits + stencilBufferBits to: d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = (!fullscreen) ? TRUE : FALSE;
if (resizable) {
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
d3dpp.BackBufferCount = 1;
kinc_display_mode_t mode = kinc_display_current_mode(kinc_primary_display());
d3dpp.BackBufferWidth = mode.width;
d3dpp.BackBufferHeight = mode.height;
}
else {
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferCount = 2;
d3dpp.BackBufferWidth = kinc_window_width(windowId);
d3dpp.BackBufferHeight = kinc_window_height(windowId);
}
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
// d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
if (kinc_g4_antialiasing_samples() > 1) {
for (int samples = min(kinc_g4_antialiasing_samples(), 16); samples > 1; --samples) {
if (SUCCEEDED(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, (D3DMULTISAMPLE_TYPE)samples, nullptr))) {
d3dpp.MultiSampleType = (D3DMULTISAMPLE_TYPE)samples;
break;
}
}
}
#endif
if (!SUCCEEDED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &device)))
d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
// d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
#ifdef KINC_WINDOWS
// if (System::hasShowWindowFlag(/*windowId*/)) {
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
//}
#endif
initDeviceStates();
#ifdef KINC_WINDOWS
if (fullscreen) {
// hz = d3dpp.FullScreen_RefreshRateInHz;
D3DDISPLAYMODE mode;
device->GetDisplayMode(0, &mode);
hz = mode.RefreshRate;
}
if (!fullscreen || hz == 0) {
DEVMODE devMode;
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
hz = devMode.dmDisplayFrequency;
}
#endif
// vsync = d3dpp.PresentationInterval != D3DPRESENT_INTERVAL_IMMEDIATE;
kinc_ticks_t test1 = kinc_timestamp();
for (int i = 0; i < 3; ++i) {
kinc_g4_swap_buffers();
}
kinc_ticks_t test2 = kinc_timestamp();
if (test2 - test1 < (1.0 / hz) * kinc_frequency()) {
vsync = false;
}
else {
vsync = true;
}
_width = kinc_window_width(windowId);
_height = kinc_window_height(windowId);
}
void kinc_g4_flush() {}
namespace {
DWORD convertFilter(kinc_g4_texture_filter_t filter) {
switch (filter) {
case KINC_G4_TEXTURE_FILTER_POINT:
return D3DTEXF_POINT;
case KINC_G4_TEXTURE_FILTER_LINEAR:
return D3DTEXF_LINEAR;
case KINC_G4_TEXTURE_FILTER_ANISOTROPIC:
return D3DTEXF_ANISOTROPIC;
default:
return D3DTEXF_POINT;
}
}
DWORD convertMipFilter(kinc_g4_mipmap_filter_t filter) {
switch (filter) {
case KINC_G4_MIPMAP_FILTER_NONE:
return D3DTEXF_NONE;
case KINC_G4_MIPMAP_FILTER_POINT:
return D3DTEXF_POINT;
case KINC_G4_MIPMAP_FILTER_LINEAR:
return D3DTEXF_LINEAR;
default:
return D3DTEXF_NONE;
}
}
}
void kinc_g4_set_texture_magnification_filter(kinc_g4_texture_unit_t texunit, kinc_g4_texture_filter_t filter) {
device->SetSamplerState(texunit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], D3DSAMP_MAGFILTER, convertFilter(filter));
}
void kinc_g4_set_texture3d_magnification_filter(kinc_g4_texture_unit_t texunit, kinc_g4_texture_filter_t filter) {
kinc_g4_set_texture_magnification_filter(texunit, filter);
}
void kinc_g4_set_texture_minification_filter(kinc_g4_texture_unit_t texunit, kinc_g4_texture_filter_t filter) {
device->SetSamplerState(texunit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], D3DSAMP_MINFILTER, convertFilter(filter));
}
void kinc_g4_set_texture3d_minification_filter(kinc_g4_texture_unit_t texunit, kinc_g4_texture_filter_t filter) {
kinc_g4_set_texture_minification_filter(texunit, filter);
}
void kinc_g4_set_texture_mipmap_filter(kinc_g4_texture_unit_t texunit, kinc_g4_mipmap_filter_t filter) {
device->SetSamplerState(texunit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], D3DSAMP_MIPFILTER, convertMipFilter(filter));
}
void kinc_g4_set_texture3d_mipmap_filter(kinc_g4_texture_unit_t texunit, kinc_g4_mipmap_filter_t filter) {
kinc_g4_set_texture_mipmap_filter(texunit, filter);
}
void kinc_g4_set_texture_compare_mode(kinc_g4_texture_unit_t unit, bool enabled) {}
void kinc_g4_set_texture_compare_func(kinc_g4_texture_unit_t unit, kinc_g4_compare_mode_t mode) {}
void kinc_g4_set_cubemap_compare_mode(kinc_g4_texture_unit_t unit, bool enabled) {}
void kinc_g4_set_cubemap_compare_func(kinc_g4_texture_unit_t unit, kinc_g4_compare_mode_t mode) {}
void kinc_g4_set_texture_max_anisotropy(kinc_g4_texture_unit_t unit, uint16_t max_anisotropy) {
device->SetSamplerState(unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], D3DSAMP_MAXANISOTROPY, max_anisotropy);
}
void kinc_g4_set_cubemap_max_anisotropy(kinc_g4_texture_unit_t unit, uint16_t max_anisotropy) {}
void kinc_g4_set_texture_lod(kinc_g4_texture_unit_t unit, float lod_min_clamp, float lod_max_clamp) {
// device->SetSamplerState(unit.impl.unit, D3DSAMP_, );
}
void kinc_g4_set_cubemap_lod(kinc_g4_texture_unit_t unit, float lod_min_clamp, float lod_max_clamp) {}
void kinc_g4_set_render_targets(struct kinc_g4_render_target **targets, int count) {
// if (backBuffer != nullptr) backBuffer->Release();
if (backBuffer == nullptr) {
device->GetRenderTarget(0, &backBuffer);
device->GetDepthStencilSurface(&depthBuffer);
}
kinc_microsoft_affirm(device->SetDepthStencilSurface(targets[0]->impl.depthSurface));
for (int i = 0; i < count; ++i) {
kinc_microsoft_affirm(device->SetRenderTarget(i, targets[i]->impl.colorSurface));
}
}
void kinc_g4_set_render_target_face(struct kinc_g4_render_target *texture, int face) {}
int kinc_g4_max_bound_textures(void) {
return 8;
}
// void Graphics::setDepthStencilTarget(Texture* texture) {
// //if (depthBuffer != nullptr) depthBuffer->Release();
// device->GetDepthStencilSurface(&depthBuffer);
// Microsoft::affirm(device->SetDepthStencilSurface(dcast<D3D9Texture*>(texture)->getSurface()));
//}
void kinc_g4_restore_render_target() {
if (backBuffer != nullptr) {
device->SetRenderTarget(0, backBuffer);
device->SetRenderTarget(1, nullptr);
backBuffer->Release();
backBuffer = nullptr;
device->SetDepthStencilSurface(depthBuffer);
depthBuffer->Release();
depthBuffer = nullptr;
kinc_g4_viewport(0, 0, _width, _height);
}
}
void kinc_g4_draw_indexed_vertices() {
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, kinc_g4_vertex_buffer_count(kinc_internal_current_vertex_buffer), 0,
kinc_g4_index_buffer_count(kinc_internal_current_index_buffer) / 3);
}
void kinc_g4_draw_indexed_vertices_from_to(int start, int count) {
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, kinc_g4_vertex_buffer_count(kinc_internal_current_vertex_buffer), start, count / 3);
}
void kinc_g4_draw_indexed_vertices_from_to_from(int start, int count, int vertex_offset) {
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vertex_offset, 0, kinc_g4_vertex_buffer_count(kinc_internal_current_vertex_buffer), start, count / 3);
}
void kinc_g4_draw_indexed_vertices_instanced(int instanceCount) {
kinc_microsoft_affirm(device->SetStreamSourceFreq(kinc_internal_current_vertex_buffer->impl._offset, (D3DSTREAMSOURCE_INDEXEDDATA | instanceCount)));
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, kinc_g4_vertex_buffer_count(kinc_internal_current_vertex_buffer), 0,
kinc_g4_index_buffer_count(kinc_internal_current_index_buffer) / 3);
}
void kinc_g4_draw_indexed_vertices_instanced_from_to(int instanceCount, int start, int count) {
kinc_microsoft_affirm(device->SetStreamSourceFreq(kinc_internal_current_vertex_buffer->impl._offset, (D3DSTREAMSOURCE_INDEXEDDATA | instanceCount)));
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, kinc_g4_vertex_buffer_count(kinc_internal_current_vertex_buffer), start, count / 3);
}
void kinc_g4_set_texture_addressing(kinc_g4_texture_unit_t unit, kinc_g4_texture_direction_t dir, kinc_g4_texture_addressing_t addressing) {
DWORD value = 0;
switch (addressing) {
case KINC_G4_TEXTURE_ADDRESSING_REPEAT:
value = D3DTADDRESS_WRAP;
break;
case KINC_G4_TEXTURE_ADDRESSING_MIRROR:
value = D3DTADDRESS_MIRROR;
break;
case KINC_G4_TEXTURE_ADDRESSING_CLAMP:
value = D3DTADDRESS_CLAMP;
break;
case KINC_G4_TEXTURE_ADDRESSING_BORDER:
value = D3DTADDRESS_BORDER;
break;
}
device->SetSamplerState(unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], dir == KINC_G4_TEXTURE_DIRECTION_U ? D3DSAMP_ADDRESSU : D3DSAMP_ADDRESSV, value);
}
void kinc_g4_set_texture3d_addressing(kinc_g4_texture_unit_t unit, kinc_g4_texture_direction_t dir, kinc_g4_texture_addressing_t addressing) {
kinc_g4_set_texture_addressing(unit, dir, addressing);
}
namespace {
void tod3dmatrix(kinc_matrix4x4_t *matrix, D3DMATRIX &d3dm) {
d3dm._11 = kinc_matrix4x4_get(matrix, 0, 0);
d3dm._12 = kinc_matrix4x4_get(matrix, 0, 1);
d3dm._13 = kinc_matrix4x4_get(matrix, 0, 2);
d3dm._14 = kinc_matrix4x4_get(matrix, 0, 3);
d3dm._21 = kinc_matrix4x4_get(matrix, 1, 0);
d3dm._22 = kinc_matrix4x4_get(matrix, 1, 1);
d3dm._23 = kinc_matrix4x4_get(matrix, 1, 2);
d3dm._24 = kinc_matrix4x4_get(matrix, 1, 3);
d3dm._31 = kinc_matrix4x4_get(matrix, 2, 0);
d3dm._32 = kinc_matrix4x4_get(matrix, 2, 1);
d3dm._33 = kinc_matrix4x4_get(matrix, 2, 2);
d3dm._34 = kinc_matrix4x4_get(matrix, 2, 3);
d3dm._41 = kinc_matrix4x4_get(matrix, 3, 0);
d3dm._42 = kinc_matrix4x4_get(matrix, 3, 1);
d3dm._43 = kinc_matrix4x4_get(matrix, 3, 2);
d3dm._44 = kinc_matrix4x4_get(matrix, 3, 3);
}
}
void kinc_g4_clear(unsigned flags, unsigned color, float depth, int stencil) {
device->Clear(0, nullptr, flags, color, depth, stencil);
}
void kinc_g4_begin(int window) {
// TODO (DK) ignore secondary windows for now
if (window > 0) {
return;
}
kinc_g4_viewport(0, 0, _width, _height);
device->BeginScene();
}
void kinc_g4_viewport(int x, int y, int width, int height) {
vp.X = x;
vp.Y = y;
vp.Width = width;
vp.Height = height;
device->SetViewport(&vp);
}
void kinc_g4_scissor(int x, int y, int width, int height) {
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
RECT rc;
rc.left = x;
rc.top = y;
rc.right = x + width;
rc.bottom = y + height;
device->SetScissorRect(&rc);
}
void kinc_g4_disable_scissor() {
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
}
void kinc_g4_end(int window) {
// TODO (DK) ignore secondary windows for now
if (window > 0) {
return;
}
/*if (backBuffer != nullptr) {
backBuffer->Release();
backBuffer = nullptr;
}*/
device->EndScene();
}
bool kinc_window_vsynced(int window) {
return vsync;
}
// unsigned Graphics4::refreshRate() {
// return hz;
//}
bool kinc_g4_swap_buffers() {
return ::swapBuffers();
}
void kinc_g4_set_stencil_reference_value(int value) {}
void kinc_g4_set_blend_constant(float r, float g, float b, float a) {
device->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA((int)(r * 255), (int)(g * 255), (int)(b * 255), (int)(a * 255)));
}
void kinc_g4_set_bool(kinc_g4_constant_location_t position, bool value) {
if (position.impl.shaderType == -1)
return;
BOOL bools[4];
bools[0] = value ? 1 : 0;
bools[1] = bools[0];
bools[2] = bools[0];
bools[3] = bools[0];
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantB(position.impl.reg.regindex, &bools[0], 1);
else
device->SetPixelShaderConstantB(position.impl.reg.regindex, &bools[0], 1);
}
void kinc_g4_set_int(kinc_g4_constant_location_t position, int value) {
if (position.impl.shaderType == -1)
return;
if (position.impl.reg.regtype == 'f') {
kinc_g4_set_float(position, (float)value);
}
else {
int ints[4];
ints[0] = value;
ints[1] = value;
ints[2] = value;
ints[3] = value;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
else
device->SetPixelShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
}
}
void kinc_g4_set_int2(kinc_g4_constant_location_t position, int value1, int value2) {
if (position.impl.shaderType == -1)
return;
if (position.impl.reg.regtype == 'f') {
kinc_g4_set_float2(position, (float)value1, (float)value2);
}
else {
int ints[4];
ints[0] = value1;
ints[1] = value2;
ints[2] = value1;
ints[3] = value2;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
else
device->SetPixelShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
}
}
void kinc_g4_set_int3(kinc_g4_constant_location_t position, int value1, int value2, int value3) {
if (position.impl.shaderType == -1)
return;
if (position.impl.reg.regtype == 'f') {
kinc_g4_set_float3(position, (float)value1, (float)value2, (float)value3);
}
else {
int ints[4];
ints[0] = value1;
ints[1] = value2;
ints[2] = value3;
ints[3] = value1;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
else
device->SetPixelShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
}
}
void kinc_g4_set_int4(kinc_g4_constant_location_t position, int value1, int value2, int value3, int value4) {
if (position.impl.shaderType == -1)
return;
if (position.impl.reg.regtype == 'f') {
kinc_g4_set_float4(position, (float)value1, (float)value2, (float)value3, (float)value4);
}
else {
int ints[4];
ints[0] = value1;
ints[1] = value2;
ints[2] = value3;
ints[3] = value4;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
else
device->SetPixelShaderConstantI(position.impl.reg.regindex, &ints[0], 1);
}
}
void kinc_g4_set_ints(kinc_g4_constant_location_t location, int *values, int count) {
if (location.impl.shaderType == -1)
return;
int registerCount = (count + 3) / 4; // round up
if (registerCount == count / 4) { // round down
if (location.impl.shaderType == 0)
device->SetVertexShaderConstantI(location.impl.reg.regindex, values, registerCount);
else
device->SetPixelShaderConstantI(location.impl.reg.regindex, values, registerCount);
}
else {
int *data = (int *)alloca(registerCount * 4 * sizeof(int));
memcpy(data, values, count * sizeof(int));
if (location.impl.shaderType == 0)
device->SetVertexShaderConstantI(location.impl.reg.regindex, data, registerCount);
else
device->SetPixelShaderConstantI(location.impl.reg.regindex, data, registerCount);
}
}
void kinc_g4_set_float(kinc_g4_constant_location_t position, float value) {
if (position.impl.shaderType == -1)
return;
float floats[4];
floats[0] = value;
floats[1] = value;
floats[2] = value;
floats[3] = value;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantF(position.impl.reg.regindex, floats, 1);
else
device->SetPixelShaderConstantF(position.impl.reg.regindex, floats, 1);
}
void kinc_g4_set_float2(kinc_g4_constant_location_t position, float value1, float value2) {
if (position.impl.shaderType == -1)
return;
float floats[4];
floats[0] = value1;
floats[1] = value2;
floats[2] = value1;
floats[3] = value2;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantF(position.impl.reg.regindex, floats, 1);
else
device->SetPixelShaderConstantF(position.impl.reg.regindex, floats, 1);
}
void kinc_g4_set_float3(kinc_g4_constant_location_t position, float value1, float value2, float value3) {
if (position.impl.shaderType == -1)
return;
float floats[4];
floats[0] = value1;
floats[1] = value2;
floats[2] = value3;
floats[3] = value1;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantF(position.impl.reg.regindex, floats, 1);
else
device->SetPixelShaderConstantF(position.impl.reg.regindex, floats, 1);
}
void kinc_g4_set_float4(kinc_g4_constant_location_t position, float value1, float value2, float value3, float value4) {
if (position.impl.shaderType == -1)
return;
float floats[4];
floats[0] = value1;
floats[1] = value2;
floats[2] = value3;
floats[3] = value4;
if (position.impl.shaderType == 0)
device->SetVertexShaderConstantF(position.impl.reg.regindex, floats, 1);
else
device->SetPixelShaderConstantF(position.impl.reg.regindex, floats, 1);
}
void kinc_g4_set_floats(kinc_g4_constant_location_t location, float *values, int count) {
if (location.impl.shaderType == -1)
return;
int registerCount = (count + 3) / 4; // round up
if (registerCount == count / 4) { // round down
if (location.impl.shaderType == 0)
device->SetVertexShaderConstantF(location.impl.reg.regindex, values, registerCount);
else
device->SetPixelShaderConstantF(location.impl.reg.regindex, values, registerCount);
}
else {
float *data = (float *)alloca(registerCount * 4 * sizeof(float));
memcpy(data, values, count * sizeof(float));
if (location.impl.shaderType == 0)
device->SetVertexShaderConstantF(location.impl.reg.regindex, data, registerCount);
else
device->SetPixelShaderConstantF(location.impl.reg.regindex, data, registerCount);
}
}
void kinc_g4_set_matrix4(kinc_g4_constant_location_t location, kinc_matrix4x4_t *value) {
if (location.impl.shaderType == -1)
return;
float floats[16];
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
floats[y * 4 + x] = kinc_matrix4x4_get(value, y, x);
}
}
if (location.impl.shaderType == 0)
device->SetVertexShaderConstantF(location.impl.reg.regindex, floats, 4);
else
device->SetPixelShaderConstantF(location.impl.reg.regindex, floats, 4);
}
void kinc_g4_set_matrix3(kinc_g4_constant_location_t location, kinc_matrix3x3_t *value) {
if (location.impl.shaderType == -1)
return;
float floats[12];
for (int y = 0; y < 3; ++y) {
for (int x = 0; x < 3; ++x) {
floats[y * 4 + x] = kinc_matrix3x3_get(value, y, x);
}
}
if (location.impl.shaderType == 0)
device->SetVertexShaderConstantF(location.impl.reg.regindex, floats, 3);
else
device->SetPixelShaderConstantF(location.impl.reg.regindex, floats, 3);
}
void kinc_g4_set_vertex_buffers(kinc_g4_vertex_buffer_t **buffers, int count) {
for (int i = 0; i < count; ++i) {
kinc_internal_g4_vertex_buffer_set(buffers[i], i);
}
}
void kinc_g4_set_index_buffer(kinc_g4_index_buffer_t *buffer) {
kinc_internal_g4_index_buffer_set(buffer);
}
#ifdef KINC_KONG
void kinc_internal_texture_set(kinc_g4_texture_t *texture, uint32_t unit);
void kinc_g4_set_texture(uint32_t unit, struct kinc_g4_texture *texture) {
kinc_internal_texture_set(texture, unit);
}
#else
void kinc_internal_texture_set(kinc_g4_texture_t *texture, kinc_g4_texture_unit_t unit);
void kinc_g4_set_texture(kinc_g4_texture_unit_t unit, struct kinc_g4_texture *texture) {
kinc_internal_texture_set(texture, unit);
}
#endif
void kinc_g4_set_image_texture(kinc_g4_texture_unit_t unit, struct kinc_g4_texture *texture) {}
unsigned queryCount = 0;
std::vector<IDirect3DQuery9 *> queryPool;
bool kinc_g4_init_occlusion_query(unsigned *occlusionQuery) {
// check if the runtime supports queries
HRESULT result = device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL);
if (FAILED(result)) {
kinc_log(KINC_LOG_LEVEL_WARNING, "Internal query creation failed, result: 0x%X.", result);
return false;
}
IDirect3DQuery9 *pQuery = nullptr;
device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &pQuery);
queryPool.push_back(pQuery);
*occlusionQuery = queryCount;
++queryCount;
return true;
}
void kinc_g4_delete_occlusion_query(unsigned occlusionQuery) {
if (occlusionQuery < queryPool.size())
queryPool[occlusionQuery] = nullptr;
}
void kinc_g4_start_occlusion_query(unsigned occlusionQuery) {
IDirect3DQuery9 *pQuery = queryPool[occlusionQuery];
if (pQuery != nullptr) {
pQuery->Issue(D3DISSUE_BEGIN);
}
}
void kinc_g4_end_occlusion_query(unsigned occlusionQuery) {
IDirect3DQuery9 *pQuery = queryPool[occlusionQuery];
if (pQuery != nullptr) {
pQuery->Issue(D3DISSUE_END);
}
}
bool kinc_g4_are_query_results_available(unsigned occlusionQuery) {
IDirect3DQuery9 *pQuery = queryPool[occlusionQuery];
if (pQuery != nullptr) {
if (S_OK == pQuery->GetData(0, 0, 0)) {
return true;
}
}
return false;
}
void kinc_g4_get_query_results(unsigned occlusionQuery, unsigned *pixelCount) {
IDirect3DQuery9 *pQuery = queryPool[occlusionQuery];
if (pQuery != nullptr) {
DWORD numberOfPixelsDrawn;
HRESULT result = pQuery->GetData(&numberOfPixelsDrawn, sizeof(DWORD), 0);
if (S_OK == result) {
*pixelCount = numberOfPixelsDrawn;
}
else {
kinc_log(KINC_LOG_LEVEL_WARNING, "Check first if results are available");
*pixelCount = 0;
}
}
}
void kinc_g4_set_texture_array(kinc_g4_texture_unit_t unit, struct kinc_g4_texture_array *array) {}
void kinc_g4_set_pipeline(struct kinc_g4_pipeline *pipeline) {
kinc_g4_internal_set_pipeline(pipeline);
}
bool kinc_g4_supports_instanced_rendering() {
return true;
}
bool kinc_g4_supports_compute_shaders() {
return false;
}
bool kinc_g4_supports_blend_constants() {
D3DCAPS9 pCaps = {};
if (FAILED(device->GetDeviceCaps(&pCaps))) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to get device caps");
return false;
}
return ((pCaps.SrcBlendCaps & D3DPBLENDCAPS_BLENDFACTOR) != 0) && ((pCaps.DestBlendCaps & D3DPBLENDCAPS_BLENDFACTOR) != 0);
}
bool kinc_g4_supports_non_pow2_textures() {
D3DCAPS9 pCaps = {};
if (FAILED(device->GetDeviceCaps(&pCaps))) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to get device caps");
return false;
}
// only advertise full npot support
return ((pCaps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0) && ((pCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0);
}
bool kinc_g4_render_targets_inverted_y(void) {
return false;
}
void kinc_g4_set_constant_buffer(uint32_t id, struct kinc_g4_constant_buffer *buffer) {}

View File

@ -0,0 +1,12 @@
#pragma once
#include <kinc/graphics4/graphics.h>
#include <kinc/math/matrix.h>
#ifndef NDEBUG
#define D3D_DEBUG_INFO
#endif
#include <d3d9.h>
extern IDirect3D9 *d3d;
extern IDirect3DDevice9 *device;

View File

@ -0,0 +1,22 @@
#include <kinc/graphics4/compute.h>
#include <kinc/graphics4/rendertarget.h>
#include <kinc/graphics4/texture.h>
#include <kinc/math/core.h>
void kinc_g4_compute_shader_init(kinc_g4_compute_shader *shader, void *source, int length) {}
void kinc_g4_compute_shader_destroy(kinc_g4_compute_shader *shader) {}
kinc_g4_constant_location_t kinc_g4_compute_shader_get_constant_location(kinc_g4_compute_shader *shader, const char *name) {
kinc_g4_constant_location_t location = {0};
return location;
}
kinc_g4_texture_unit_t kinc_g4_compute_shader_get_texture_unit(kinc_g4_compute_shader *shader, const char *name) {
kinc_g4_texture_unit_t unit = {0};
return unit;
}
void kinc_g4_set_compute_shader(kinc_g4_compute_shader *shader) {}
void kinc_g4_compute(int x, int y, int z) {}

View File

@ -0,0 +1,13 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef struct kinc_g4_compute_shader_impl {
int nothing;
} kinc_g4_compute_shader_impl;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,34 @@
#ifdef KINC_KONG
#include <kinc/graphics4/constantbuffer.h>
#include "Direct3D9.h"
void kinc_g4_constant_buffer_init(kinc_g4_constant_buffer *buffer, size_t size) {
buffer->impl.size = size;
buffer->impl.last_start = 0;
buffer->impl.last_size = size;
}
void kinc_g4_constant_buffer_destroy(kinc_g4_constant_buffer *buffer) {}
uint8_t *kinc_g4_constant_buffer_lock_all(kinc_g4_constant_buffer *buffer) {
return NULL;
}
uint8_t *kinc_g4_constant_buffer_lock(kinc_g4_constant_buffer *buffer, size_t start, size_t size) {
buffer->impl.last_start = start;
buffer->impl.last_size = size;
return NULL;
}
void kinc_g4_constant_buffer_unlock_all(kinc_g4_constant_buffer *buffer) {}
void kinc_g4_constant_buffer_unlock(kinc_g4_constant_buffer *buffer, size_t count) {}
size_t kinc_g4_constant_buffer_size(kinc_g4_constant_buffer *buffer) {
return buffer->impl.size;
}
#endif

View File

@ -0,0 +1,11 @@
#pragma once
#ifdef KINC_KONG
typedef struct kinc_g4_constant_buffer_impl {
size_t size;
size_t last_start;
size_t last_size;
} kinc_g4_constant_buffer_impl;
#endif

View File

@ -0,0 +1,6 @@
#pragma once
#include "IndexBufferImpl.h"
#include "RenderTargetImpl.h"
#include "ShaderImpl.h"
#include "VertexBufferImpl.h"

View File

@ -0,0 +1,56 @@
#include <kinc/graphics4/graphics.h>
#include <kinc/graphics4/indexbuffer.h>
#include <kinc/backend/SystemMicrosoft.h>
#include "Direct3D9.h"
struct kinc_g4_index_buffer *kinc_internal_current_index_buffer = NULL;
void kinc_g4_index_buffer_init(kinc_g4_index_buffer_t *buffer, int count, kinc_g4_index_buffer_format_t format, kinc_g4_usage_t usage) {
buffer->impl.count = count;
buffer->impl.format = format;
DWORD usageFlags = D3DUSAGE_WRITEONLY;
if (usage == KINC_G4_USAGE_DYNAMIC) {
usageFlags = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
}
kinc_microsoft_affirm(device->CreateIndexBuffer(
sizeof(int) * count, usageFlags, format == KINC_G4_INDEX_BUFFER_FORMAT_32BIT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, D3DPOOL_DEFAULT, &buffer->impl.ib, 0));
}
void kinc_g4_index_buffer_destroy(kinc_g4_index_buffer_t *buffer) {
buffer->impl.ib->Release();
}
static int kinc_g4_internal_index_buffer_stride(kinc_g4_index_buffer_t *buffer) {
return buffer->impl.format == KINC_G4_INDEX_BUFFER_FORMAT_32BIT ? 4 : 2;
}
void *kinc_g4_index_buffer_lock_all(kinc_g4_index_buffer_t *buffer) {
return kinc_g4_index_buffer_lock(buffer, 0, kinc_g4_index_buffer_count(buffer));
}
void *kinc_g4_index_buffer_lock(kinc_g4_index_buffer_t *buffer, int start, int count) {
uint8_t *data;
kinc_microsoft_affirm(buffer->impl.ib->Lock(0, sizeof(int) * kinc_g4_index_buffer_count(buffer), (void **)&data, D3DLOCK_DISCARD));
return &data[start * kinc_g4_internal_index_buffer_stride(buffer)];
}
void kinc_g4_index_buffer_unlock_all(kinc_g4_index_buffer_t *buffer) {
kinc_microsoft_affirm(buffer->impl.ib->Unlock());
}
void kinc_g4_index_buffer_unlock(kinc_g4_index_buffer_t *buffer, int count) {
kinc_g4_index_buffer_unlock_all(buffer);
}
void kinc_internal_g4_index_buffer_set(kinc_g4_index_buffer_t *buffer) {
kinc_internal_current_index_buffer = buffer;
kinc_microsoft_affirm(device->SetIndices(buffer->impl.ib));
}
int kinc_g4_index_buffer_count(kinc_g4_index_buffer_t *buffer) {
return buffer->impl.count;
}

View File

@ -0,0 +1,21 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct IDirect3DIndexBuffer9;
typedef struct {
struct IDirect3DIndexBuffer9 *ib;
int count;
int format;
} kinc_g4_index_buffer_impl_t;
struct kinc_g4_index_buffer;
extern struct kinc_g4_index_buffer *kinc_internal_current_index_buffer;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,365 @@
#include <kinc/graphics4/graphics.h>
#include <kinc/graphics4/pipeline.h>
#include <kinc/graphics4/shader.h>
#include <kinc/graphics4/vertexstructure.h>
#include <kinc/log.h>
#include <kinc/system.h>
#include <kinc/backend/SystemMicrosoft.h>
#include "Direct3D9.h"
#include <assert.h>
#include <malloc.h>
namespace {
_D3DBLEND convert_blend_factor(kinc_g4_blending_factor_t factor) {
switch (factor) {
case KINC_G4_BLEND_ONE:
return D3DBLEND_ONE;
case KINC_G4_BLEND_ZERO:
return D3DBLEND_ZERO;
case KINC_G4_BLEND_SOURCE_ALPHA:
return D3DBLEND_SRCALPHA;
case KINC_G4_BLEND_DEST_ALPHA:
return D3DBLEND_DESTALPHA;
case KINC_G4_BLEND_INV_SOURCE_ALPHA:
return D3DBLEND_INVSRCALPHA;
case KINC_G4_BLEND_INV_DEST_ALPHA:
return D3DBLEND_INVDESTALPHA;
case KINC_G4_BLEND_CONSTANT:
return D3DBLEND_BLENDFACTOR;
case KINC_G4_BLEND_INV_CONSTANT:
return D3DBLEND_INVBLENDFACTOR;
default:
assert(false);
return D3DBLEND_SRCALPHA;
}
}
_D3DBLENDOP convert_blend_operation(kinc_g4_blending_operation_t op) {
switch (op) {
case KINC_G4_BLENDOP_ADD:
return D3DBLENDOP_ADD;
case KINC_G4_BLENDOP_SUBTRACT:
return D3DBLENDOP_SUBTRACT;
case KINC_G4_BLENDOP_REVERSE_SUBTRACT:
return D3DBLENDOP_REVSUBTRACT;
case KINC_G4_BLENDOP_MIN:
return D3DBLENDOP_MIN;
case KINC_G4_BLENDOP_MAX:
return D3DBLENDOP_MAX;
default:
assert(false);
return D3DBLENDOP_ADD;
}
}
_D3DCMPFUNC convert(kinc_g4_compare_mode_t mode) {
switch (mode) {
default:
case KINC_G4_COMPARE_ALWAYS:
return D3DCMP_ALWAYS;
case KINC_G4_COMPARE_NEVER:
return D3DCMP_NEVER;
case KINC_G4_COMPARE_EQUAL:
return D3DCMP_EQUAL;
case KINC_G4_COMPARE_NOT_EQUAL:
return D3DCMP_NOTEQUAL;
case KINC_G4_COMPARE_LESS:
return D3DCMP_LESS;
case KINC_G4_COMPARE_LESS_EQUAL:
return D3DCMP_LESSEQUAL;
case KINC_G4_COMPARE_GREATER:
return D3DCMP_GREATER;
case KINC_G4_COMPARE_GREATER_EQUAL:
return D3DCMP_GREATEREQUAL;
}
}
}
void kinc_g4_pipeline_init(kinc_g4_pipeline_t *state) {
memset(state, 0, sizeof(kinc_g4_pipeline));
kinc_g4_internal_pipeline_set_defaults(state);
}
void kinc_g4_pipeline_destroy(kinc_g4_pipeline_t *state) {}
static int find_attribute(struct ShaderAttribute *attributes, const char *name) {
for (int i = 0; i < KINC_INTERNAL_MAX_ATTRIBUTES; ++i) {
if (attributes[i].name == 0) {
return -1;
}
if (strcmp(attributes[i].name, name) == 0) {
return i;
}
}
return -1;
}
static int find_constant(struct ShaderRegister *constants, const char *name) {
for (int i = 0; i < KINC_INTERNAL_MAX_CONSTANTS; ++i) {
if (constants[i].name == 0) {
return -1;
}
if (strcmp(constants[i].name, name) == 0) {
return i;
}
}
return -1;
}
void kinc_g4_pipeline_compile(kinc_g4_pipeline_t *state) {
int highestIndex = 0;
for (int i = 0;; ++i) {
if (state->vertex_shader->impl.attributes[i].name[0] == 0) {
break;
}
int index = state->vertex_shader->impl.attributes[i].index;
if (index > highestIndex) {
highestIndex = index;
}
}
int all = 0;
for (int stream = 0; state->input_layout[stream] != nullptr; ++stream) {
for (int index = 0; index < state->input_layout[stream]->size; ++index) {
if (state->input_layout[stream]->elements[index].data == KINC_G4_VERTEX_DATA_F32_4X4) {
all += 4;
}
else {
all += 1;
}
}
}
D3DVERTEXELEMENT9 *elements = (D3DVERTEXELEMENT9 *)_alloca(sizeof(D3DVERTEXELEMENT9) * (all + 1));
int i = 0;
for (int stream = 0; state->input_layout[stream] != nullptr; ++stream) {
int stride = 0;
for (int index = 0; index < state->input_layout[stream]->size; ++index) {
if (state->input_layout[stream]->elements[index].data != KINC_G4_VERTEX_DATA_F32_4X4) {
elements[i].Stream = stream;
elements[i].Offset = stride;
}
stride += kinc_g4_vertex_data_size(state->input_layout[stream]->elements[index].data);
switch (state->input_layout[stream]->elements[index].data) {
case KINC_G4_VERTEX_DATA_F32_1X:
elements[i].Type = D3DDECLTYPE_FLOAT1;
break;
case KINC_G4_VERTEX_DATA_F32_2X:
elements[i].Type = D3DDECLTYPE_FLOAT2;
break;
case KINC_G4_VERTEX_DATA_F32_3X:
elements[i].Type = D3DDECLTYPE_FLOAT3;
break;
case KINC_G4_VERTEX_DATA_F32_4X:
elements[i].Type = D3DDECLTYPE_FLOAT4;
break;
case KINC_G4_VERTEX_DATA_U8_4X:
elements[i].Type = D3DDECLTYPE_UBYTE4;
break;
case KINC_G4_VERTEX_DATA_U8_4X_NORMALIZED:
elements[i].Type = D3DDECLTYPE_UBYTE4N;
break;
case KINC_G4_VERTEX_DATA_I16_2X:
elements[i].Type = D3DDECLTYPE_SHORT2;
break;
case KINC_G4_VERTEX_DATA_I16_2X_NORMALIZED:
elements[i].Type = D3DDECLTYPE_SHORT2N;
break;
case KINC_G4_VERTEX_DATA_U16_2X_NORMALIZED:
elements[i].Type = D3DDECLTYPE_USHORT2N;
break;
case KINC_G4_VERTEX_DATA_I16_4X:
elements[i].Type = D3DDECLTYPE_SHORT4;
break;
case KINC_G4_VERTEX_DATA_I16_4X_NORMALIZED:
elements[i].Type = D3DDECLTYPE_SHORT4N;
break;
case KINC_G4_VERTEX_DATA_U16_4X_NORMALIZED:
elements[i].Type = D3DDECLTYPE_USHORT4N;
break;
case KINC_G4_VERTEX_DATA_I8_1X:
case KINC_G4_VERTEX_DATA_U8_1X:
case KINC_G4_VERTEX_DATA_I8_1X_NORMALIZED:
case KINC_G4_VERTEX_DATA_U8_1X_NORMALIZED:
case KINC_G4_VERTEX_DATA_I8_2X:
case KINC_G4_VERTEX_DATA_U8_2X:
case KINC_G4_VERTEX_DATA_I8_2X_NORMALIZED:
case KINC_G4_VERTEX_DATA_U8_2X_NORMALIZED:
case KINC_G4_VERTEX_DATA_I8_4X:
case KINC_G4_VERTEX_DATA_I8_4X_NORMALIZED:
case KINC_G4_VERTEX_DATA_I16_1X:
case KINC_G4_VERTEX_DATA_U16_1X:
case KINC_G4_VERTEX_DATA_I16_1X_NORMALIZED:
case KINC_G4_VERTEX_DATA_U16_1X_NORMALIZED:
case KINC_G4_VERTEX_DATA_U16_2X:
case KINC_G4_VERTEX_DATA_U16_4X:
case KINC_G4_VERTEX_DATA_I32_1X:
case KINC_G4_VERTEX_DATA_U32_1X:
case KINC_G4_VERTEX_DATA_I32_2X:
case KINC_G4_VERTEX_DATA_U32_2X:
case KINC_G4_VERTEX_DATA_I32_3X:
case KINC_G4_VERTEX_DATA_U32_3X:
case KINC_G4_VERTEX_DATA_I32_4X:
case KINC_G4_VERTEX_DATA_U32_4X:
elements[i].Type = D3DDECLTYPE_UNUSED;
assert(false);
break;
case KINC_G4_VERTEX_DATA_F32_4X4:
for (int i2 = 0; i2 < 4; ++i2) {
elements[i].Stream = stream;
elements[i].Offset = stride;
elements[i].Type = D3DDECLTYPE_FLOAT4;
elements[i].Method = D3DDECLMETHOD_DEFAULT;
elements[i].Usage = D3DDECLUSAGE_TEXCOORD;
char name[101];
strcpy(name, state->input_layout[stream]->elements[index].name);
strcat(name, "_");
size_t length = strlen(name);
_itoa(i2, &name[length], 10);
name[length + 1] = 0;
int attribute_index = find_attribute(state->vertex_shader->impl.attributes, name);
if (attribute_index < 0) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Could not find attribute %s.", name);
elements[i].UsageIndex = ++highestIndex;
}
else {
elements[i].UsageIndex = state->vertex_shader->impl.attributes[attribute_index].index;
}
++i;
}
break;
}
if (state->input_layout[stream]->elements[index].data != KINC_G4_VERTEX_DATA_F32_4X4) {
elements[i].Method = D3DDECLMETHOD_DEFAULT;
elements[i].Usage = D3DDECLUSAGE_TEXCOORD;
int attribute_index = find_attribute(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name);
if (attribute_index < 0) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Could not find attribute %s.", state->input_layout[stream]->elements[index].name);
elements[i].UsageIndex = ++highestIndex;
}
else {
elements[i].UsageIndex = state->vertex_shader->impl.attributes[attribute_index].index;
}
++i;
}
}
}
elements[all].Stream = 0xff;
elements[all].Offset = 0;
elements[all].Type = D3DDECLTYPE_UNUSED;
elements[all].Method = 0;
elements[all].Usage = 0;
elements[all].UsageIndex = 0;
state->impl.vertexDecleration = nullptr;
kinc_microsoft_affirm(device->CreateVertexDeclaration(elements, &state->impl.vertexDecleration));
int constant_index = find_constant(state->vertex_shader->impl.constants, "gl_HalfPixel");
state->impl.halfPixelLocation = state->vertex_shader->impl.constants[constant_index].regindex;
}
void kinc_g4_internal_set_pipeline(kinc_g4_pipeline_t *pipeline) {
kinc_microsoft_affirm(device->SetVertexShader((IDirect3DVertexShader9 *)pipeline->vertex_shader->impl.shader));
kinc_microsoft_affirm(device->SetPixelShader((IDirect3DPixelShader9 *)pipeline->fragment_shader->impl.shader));
kinc_microsoft_affirm(device->SetVertexDeclaration(pipeline->impl.vertexDecleration));
// TODO (DK) System::screenWidth/Height are only main-window dimensions, what about other windows?
float floats[4];
floats[0] = 1.0f / kinc_width();
floats[1] = 1.0f / kinc_height();
floats[2] = floats[0];
floats[3] = floats[1];
kinc_microsoft_affirm(device->SetVertexShaderConstantF(pipeline->impl.halfPixelLocation, floats, 1));
DWORD flags = 0;
if (pipeline->color_write_mask_red[0]) {
flags |= D3DCOLORWRITEENABLE_RED;
}
if (pipeline->color_write_mask_green[0]) {
flags |= D3DCOLORWRITEENABLE_GREEN;
}
if (pipeline->color_write_mask_blue[0]) {
flags |= D3DCOLORWRITEENABLE_BLUE;
}
if (pipeline->color_write_mask_alpha[0]) {
flags |= D3DCOLORWRITEENABLE_ALPHA;
}
device->SetRenderState(D3DRS_COLORWRITEENABLE, flags);
device->SetRenderState(D3DRS_ALPHABLENDENABLE,
(pipeline->blend_source != KINC_G4_BLEND_ONE || pipeline->blend_destination != KINC_G4_BLEND_ZERO) ? TRUE : FALSE);
device->SetRenderState(D3DRS_SRCBLEND, convert_blend_factor(pipeline->blend_source));
device->SetRenderState(D3DRS_DESTBLEND, convert_blend_factor(pipeline->blend_destination));
device->SetRenderState(D3DRS_BLENDOP, convert_blend_operation(pipeline->blend_operation));
switch (pipeline->cull_mode) {
case KINC_G4_CULL_CLOCKWISE:
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
break;
case KINC_G4_CULL_COUNTER_CLOCKWISE:
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
break;
case KINC_G4_CULL_NOTHING:
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
break;
}
device->SetRenderState(D3DRS_ZENABLE, pipeline->depth_mode != KINC_G4_COMPARE_ALWAYS ? TRUE : FALSE);
device->SetRenderState(D3DRS_ZFUNC, convert(pipeline->depth_mode));
device->SetRenderState(D3DRS_ZWRITEENABLE, pipeline->depth_write ? TRUE : FALSE);
/*
case AlphaTestState:
device->SetRenderState(D3DRS_ALPHATESTENABLE, on ? TRUE : FALSE);
device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
break;
case AlphaReferenceState:
device->SetRenderState(D3DRS_ALPHAREF, (DWORD)v);
break;
*/
}
kinc_g4_constant_location_t kinc_g4_pipeline_get_constant_location(kinc_g4_pipeline_t *state, const char *name) {
kinc_g4_constant_location_t location;
int fragment_index = find_constant(state->fragment_shader->impl.constants, name);
int vertex_index = find_constant(state->vertex_shader->impl.constants, name);
if (fragment_index >= 0) {
location.impl.reg = state->fragment_shader->impl.constants[fragment_index];
location.impl.shaderType = 1;
}
else if (vertex_index >= 0) {
location.impl.reg = state->vertex_shader->impl.constants[vertex_index];
location.impl.shaderType = 0;
}
else {
location.impl.shaderType = -1;
kinc_log(KINC_LOG_LEVEL_WARNING, "Could not find uniform %s.", name);
}
return location;
}
kinc_g4_texture_unit_t kinc_g4_pipeline_get_texture_unit(kinc_g4_pipeline_t *state, const char *name) {
int fragment_index = find_constant(state->fragment_shader->impl.constants, name);
int vertex_index = find_constant(state->vertex_shader->impl.constants, name);
kinc_g4_texture_unit_t unit;
for (int i = 0; i < KINC_G4_SHADER_TYPE_COUNT; ++i) {
unit.stages[i] = -1;
}
if (fragment_index >= 0) {
unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] = state->fragment_shader->impl.constants[fragment_index].regindex;
}
if (vertex_index >= 0) {
unit.stages[KINC_G4_SHADER_TYPE_VERTEX] = state->vertex_shader->impl.constants[vertex_index].regindex;
}
return unit;
}

View File

@ -0,0 +1,18 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct IDirect3DVertexDeclaration9;
typedef struct {
struct IDirect3DVertexDeclaration9 *vertexDecleration;
int halfPixelLocation;
} kinc_g4_pipeline_impl_t;
void kinc_internal_set_constants(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,133 @@
#include <kinc/graphics4/rendertarget.h>
#include <kinc/log.h>
#include <kinc/backend/SystemMicrosoft.h>
#include "Direct3D9.h"
void kinc_g4_render_target_init_with_multisampling(kinc_g4_render_target_t *renderTarget, int width, int height, kinc_g4_render_target_format_t format,
int depthBufferBits, int stencilBufferBits, int samples_per_pixel) {
renderTarget->width = width;
renderTarget->height = height;
renderTarget->texWidth = width;
renderTarget->texHeight = height;
renderTarget->isCubeMap = false;
renderTarget->isDepthAttachment = false;
const bool antialiasing = samples_per_pixel > 1;
renderTarget->impl.antialiasing = antialiasing;
D3DFORMAT d3dformat;
switch (format) {
case KINC_G4_RENDER_TARGET_FORMAT_64BIT_FLOAT:
d3dformat = D3DFMT_A16B16G16R16F;
break;
case KINC_G4_RENDER_TARGET_FORMAT_32BIT_RED_FLOAT:
d3dformat = D3DFMT_R32F;
break;
case KINC_G4_RENDER_TARGET_FORMAT_32BIT:
default:
d3dformat = D3DFMT_A8R8G8B8;
}
#if defined(_DEBUG)
kinc_log(KINC_LOG_LEVEL_INFO, "depthBufferBits not implemented yet, using defaults (D3DFMT_D24S8)");
kinc_log(KINC_LOG_LEVEL_INFO, "stencilBufferBits not implemented yet, using defaults (D3DFMT_D24S8)");
#endif
renderTarget->impl.colorSurface = nullptr;
renderTarget->impl.depthSurface = nullptr;
renderTarget->impl.colorTexture = nullptr;
renderTarget->impl.depthTexture = nullptr;
if (antialiasing) {
kinc_microsoft_affirm(
device->CreateRenderTarget(width, height, d3dformat, D3DMULTISAMPLE_8_SAMPLES, 0, FALSE, &renderTarget->impl.colorSurface, nullptr));
kinc_microsoft_affirm(
device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_8_SAMPLES, 0, TRUE, &renderTarget->impl.depthSurface, nullptr));
kinc_microsoft_affirm(
device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, d3dformat, D3DPOOL_DEFAULT, &renderTarget->impl.colorTexture, nullptr));
// Microsoft::affirm(device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &depthTexture, nullptr));
renderTarget->impl.depthTexture = nullptr;
}
else {
if (format == KINC_G4_RENDER_TARGET_FORMAT_16BIT_DEPTH) {
kinc_microsoft_affirm(device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)MAKEFOURCC('N', 'U', 'L', 'L'), D3DPOOL_DEFAULT,
&renderTarget->impl.colorTexture, nullptr));
kinc_microsoft_affirm(device->CreateTexture(width, height, 1, D3DUSAGE_DEPTHSTENCIL, (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'), D3DPOOL_DEFAULT,
&renderTarget->impl.depthTexture, nullptr));
renderTarget->isDepthAttachment = true;
}
else {
kinc_microsoft_affirm(
device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, d3dformat, D3DPOOL_DEFAULT, &renderTarget->impl.colorTexture, nullptr));
kinc_microsoft_affirm(
device->CreateTexture(width, height, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_D24S8, D3DPOOL_DEFAULT, &renderTarget->impl.depthTexture, nullptr));
}
kinc_microsoft_affirm(renderTarget->impl.colorTexture->GetSurfaceLevel(0, &renderTarget->impl.colorSurface));
kinc_microsoft_affirm(renderTarget->impl.depthTexture->GetSurfaceLevel(0, &renderTarget->impl.depthSurface));
}
}
void kinc_g4_render_target_init_cube_with_multisampling(kinc_g4_render_target_t *renderTarget, int cubeMapSize, kinc_g4_render_target_format_t format,
int depthBufferBits, int stencilBufferBits, int samples_per_pixel) {
renderTarget->isCubeMap = true;
renderTarget->isDepthAttachment = false;
}
void kinc_g4_render_target_destroy(kinc_g4_render_target_t *renderTarget) {
if (renderTarget->impl.colorSurface != nullptr) {
renderTarget->impl.colorSurface->Release();
}
if (renderTarget->impl.depthSurface != nullptr) {
renderTarget->impl.depthSurface->Release();
}
if (renderTarget->impl.colorTexture != nullptr) {
renderTarget->impl.colorTexture->Release();
}
if (renderTarget->impl.depthTexture != nullptr) {
renderTarget->impl.depthTexture->Release();
}
}
#ifdef KINC_KONG
void kinc_g4_render_target_use_color_as_texture(kinc_g4_render_target_t *renderTarget, uint32_t unit) {
if (renderTarget->impl.antialiasing) {
IDirect3DSurface9 *surface;
renderTarget->impl.colorTexture->GetSurfaceLevel(0, &surface);
kinc_microsoft_affirm(device->StretchRect(renderTarget->impl.colorSurface, nullptr, surface, nullptr, D3DTEXF_NONE));
surface->Release();
}
device->SetTexture(unit, renderTarget->isDepthAttachment ? renderTarget->impl.depthTexture : renderTarget->impl.colorTexture);
}
#else
void kinc_g4_render_target_use_color_as_texture(kinc_g4_render_target_t *renderTarget, kinc_g4_texture_unit_t unit) {
if (renderTarget->impl.antialiasing) {
IDirect3DSurface9 *surface;
renderTarget->impl.colorTexture->GetSurfaceLevel(0, &surface);
kinc_microsoft_affirm(device->StretchRect(renderTarget->impl.colorSurface, nullptr, surface, nullptr, D3DTEXF_NONE));
surface->Release();
}
device->SetTexture(unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT],
renderTarget->isDepthAttachment ? renderTarget->impl.depthTexture : renderTarget->impl.colorTexture);
}
#endif
void kinc_g4_render_target_set_depth_stencil_from(kinc_g4_render_target_t *renderTarget, kinc_g4_render_target_t *source) {
renderTarget->impl.depthTexture = source->impl.depthTexture;
renderTarget->impl.depthSurface = source->impl.depthSurface;
}
void kinc_g4_render_target_use_depth_as_texture(kinc_g4_render_target_t *renderTarget, kinc_g4_texture_unit_t unit) {
if (renderTarget->impl.antialiasing) {
IDirect3DSurface9 *surface;
renderTarget->impl.depthTexture->GetSurfaceLevel(0, &surface);
kinc_microsoft_affirm(device->StretchRect(renderTarget->impl.depthSurface, nullptr, surface, nullptr, D3DTEXF_NONE));
surface->Release();
}
device->SetTexture(unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], renderTarget->impl.depthTexture);
}
void kinc_g4_render_target_get_pixels(kinc_g4_render_target_t *renderTarget, uint8_t *data) {}
void kinc_g4_render_target_generate_mipmaps(kinc_g4_render_target_t *renderTarget, int levels) {}

View File

@ -0,0 +1,20 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct IDirect3DSurface9;
struct IDirect3DTexture9;
typedef struct {
struct IDirect3DSurface9 *colorSurface;
struct IDirect3DSurface9 *depthSurface;
struct IDirect3DTexture9 *colorTexture;
struct IDirect3DTexture9 *depthTexture;
bool antialiasing;
} kinc_g4_render_target_impl_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,54 @@
#include <kinc/graphics4/shader.h>
#include <kinc/math/core.h>
#include <kinc/backend/SystemMicrosoft.h>
#include "Direct3D9.h"
#include <cstdio>
void kinc_g4_shader_init(kinc_g4_shader_t *shader, const void *void_data, size_t length, kinc_g4_shader_type_t type) {
unsigned index = 0;
uint8_t *data = (uint8_t *)void_data;
int attributesCount = data[index++];
for (int i = 0; i < attributesCount; ++i) {
char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
strcpy(shader->impl.attributes[i].name, name);
shader->impl.attributes[i].index = data[index++];
}
shader->impl.attributes[attributesCount].name[0] = 0;
uint8_t constantCount = data[index++];
for (unsigned i = 0; i < constantCount; ++i) {
char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
strcpy(shader->impl.constants[i].name, name);
shader->impl.constants[i].regtype = data[index++];
shader->impl.constants[i].regindex = data[index++];
shader->impl.constants[i].regcount = data[index++];
}
shader->impl.constants[constantCount].name[0] = 0;
if (type == KINC_G4_SHADER_TYPE_VERTEX) {
kinc_microsoft_affirm(device->CreateVertexShader((DWORD *)&data[index], (IDirect3DVertexShader9 **)&shader));
}
else {
kinc_microsoft_affirm(device->CreatePixelShader((DWORD *)&data[index], (IDirect3DPixelShader9 **)&shader));
}
}
int kinc_g4_shader_init_from_source(kinc_g4_shader_t *shader, const char *source, kinc_g4_shader_type_t type) {
return 1;
}
void kinc_g4_shader_destroy(kinc_g4_shader_t *shader) {}

View File

@ -0,0 +1,41 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ShaderRegister {
char name[128];
uint8_t regtype;
uint8_t regindex;
uint8_t regcount;
};
struct ShaderAttribute {
char name[128];
int index;
};
typedef struct {
struct ShaderRegister reg;
int shaderType; // 0: Vertex, 1: Fragment
} kinc_g4_constant_location_impl_t;
typedef struct {
int unit;
} kinc_g4_texture_unit_impl_t;
#define KINC_INTERNAL_MAX_CONSTANTS 64
#define KINC_INTERNAL_MAX_ATTRIBUTES 64
typedef struct {
struct ShaderRegister constants[KINC_INTERNAL_MAX_CONSTANTS];
struct ShaderAttribute attributes[KINC_INTERNAL_MAX_ATTRIBUTES];
void *shader;
} kinc_g4_shader_impl_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,110 @@
#include <kinc/graphics4/texture.h>
#include <kinc/io/filereader.h>
#include <kinc/backend/SystemMicrosoft.h>
#include "Direct3D9.h"
namespace {
kinc_g4_texture_t *setTextures[16] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
D3DFORMAT convert(kinc_image_format_t format) {
switch (format) {
case KINC_IMAGE_FORMAT_RGBA32:
default:
return D3DFMT_A8R8G8B8;
case KINC_IMAGE_FORMAT_GREY8:
return D3DFMT_L8;
}
}
}
void kinc_g4_texture_init_from_image(kinc_g4_texture_t *texture, kinc_image_t *image) {
texture->impl.stage = 0;
texture->impl.mipmap = true;
DWORD usage = 0;
texture->tex_width = image->width;
texture->tex_height = image->height;
texture->tex_depth = 1;
usage = D3DUSAGE_DYNAMIC;
kinc_microsoft_affirm_message(
device->CreateTexture(image->width, image->height, 1, usage, convert(image->format), D3DPOOL_DEFAULT, &texture->impl.texture, 0),
"Texture creation failed.");
D3DLOCKED_RECT rect;
kinc_microsoft_affirm(texture->impl.texture->LockRect(0, &rect, 0, 0));
texture->impl.pitch = rect.Pitch;
uint8_t *from = (uint8_t *)image->data;
uint8_t *to = (uint8_t *)rect.pBits;
// memcpy(to, from, width * height * sizeOf(format));
for (int y = 0; y < image->height; ++y) {
for (int x = 0; x < image->width; ++x) {
to[rect.Pitch * y + x * 4 + 0 /* blue*/] = (from[y * image->width * 4 + x * 4 + 2]); /// 255.0f;
to[rect.Pitch * y + x * 4 + 1 /*green*/] = (from[y * image->width * 4 + x * 4 + 1]); /// 255.0f;
to[rect.Pitch * y + x * 4 + 2 /* red*/] = (from[y * image->width * 4 + x * 4 + 0]); /// 255.0f;
to[rect.Pitch * y + x * 4 + 3 /*alpha*/] = (from[y * image->width * 4 + x * 4 + 3]); /// 255.0f;
}
}
kinc_microsoft_affirm(texture->impl.texture->UnlockRect(0));
}
void kinc_g4_texture_init3d(kinc_g4_texture_t *texture, int width, int height, int depth, kinc_image_format_t format) {}
void kinc_g4_texture_init(kinc_g4_texture_t *texture, int width, int height, kinc_image_format_t format) {
texture->impl.stage = 0;
texture->impl.mipmap = true;
DWORD usage = 0;
texture->tex_width = width;
texture->tex_height = height;
texture->tex_depth = 1;
usage = D3DUSAGE_DYNAMIC;
kinc_microsoft_affirm_message(device->CreateTexture(width, height, 1, usage, convert(format), D3DPOOL_DEFAULT, &texture->impl.texture, 0),
"Texture creation failed.");
}
void kinc_g4_texture_destroy(kinc_g4_texture_t *texture) {
kinc_internal_texture_unset(texture);
texture->impl.texture->Release();
}
#ifdef KINC_KONG
void kinc_internal_texture_set(kinc_g4_texture_t *texture, uint32_t unit) {
kinc_microsoft_affirm(device->SetTexture(unit, texture->impl.texture));
texture->impl.stage = unit;
setTextures[texture->impl.stage] = texture;
}
#else
void kinc_internal_texture_set(kinc_g4_texture_t *texture, kinc_g4_texture_unit_t unit) {
kinc_microsoft_affirm(device->SetTexture(unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], texture->impl.texture));
texture->impl.stage = unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT];
setTextures[texture->impl.stage] = texture;
}
#endif
void kinc_internal_texture_unset(struct kinc_g4_texture *texture) {
if (setTextures[texture->impl.stage] == texture) {
device->SetTexture(texture->impl.stage, nullptr);
setTextures[texture->impl.stage] = nullptr;
}
}
unsigned char *kinc_g4_texture_lock(kinc_g4_texture_t *texture) {
D3DLOCKED_RECT rect;
kinc_microsoft_affirm(texture->impl.texture->LockRect(0, &rect, 0, 0));
texture->impl.pitch = rect.Pitch;
return (uint8_t *)rect.pBits;
}
void kinc_g4_texture_unlock(kinc_g4_texture_t *texture) {
kinc_microsoft_affirm(texture->impl.texture->UnlockRect(0));
}
void kinc_g4_texture_clear(kinc_g4_texture_t *texture, int x, int y, int z, int width, int height, int depth, unsigned color) {}
int kinc_g4_texture_stride(kinc_g4_texture_t *texture) {
return texture->impl.pitch;
}
void kinc_g4_texture_generate_mipmaps(kinc_g4_texture_t *texture, int levels) {}
void kinc_g4_texture_set_mipmap(kinc_g4_texture_t *texture, kinc_image_t *mipmap, int level) {}

View File

@ -0,0 +1,26 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct IDirect3DTexture9;
typedef struct {
struct IDirect3DTexture9 *texture;
int stage;
bool mipmap;
uint8_t pixfmt;
int pitch;
} kinc_g4_texture_impl_t;
struct kinc_g4_texture;
void kinc_internal_texture_unmipmap(struct kinc_g4_texture *texture);
void kinc_internal_texture_unset(struct kinc_g4_texture *texture);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,5 @@
#include <kinc/graphics4/texturearray.h>
void kinc_g4_texture_array_init(kinc_g4_texture_array_t *array, kinc_image_t *textures, int count) {}
void kinc_g4_texture_array_destroy(kinc_g4_texture_array_t *array) {}

View File

@ -0,0 +1,13 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int nothing;
} kinc_g4_texture_array_impl_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,75 @@
#include <kinc/graphics4/graphics.h>
#include <kinc/graphics4/vertexbuffer.h>
#include <kinc/backend/SystemMicrosoft.h>
#include "Direct3D9.h"
struct kinc_g4_vertex_buffer *kinc_internal_current_vertex_buffer = NULL;
void kinc_g4_vertex_buffer_init(kinc_g4_vertex_buffer_t *buffer, int count, kinc_g4_vertex_structure_t *structure, kinc_g4_usage_t usage,
int instance_data_step_rate) {
buffer->impl.myCount = count;
buffer->impl.instanceDataStepRate = instance_data_step_rate;
DWORD usageFlags = D3DUSAGE_WRITEONLY;
if (usage == KINC_G4_USAGE_DYNAMIC) {
usageFlags = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
}
buffer->impl.myStride = 0;
for (int i = 0; i < structure->size; ++i) {
buffer->impl.myStride += kinc_g4_vertex_data_size(structure->elements[i].data);
}
kinc_microsoft_affirm(device->CreateVertexBuffer(kinc_g4_vertex_buffer_stride(buffer) * count, usageFlags, 0, D3DPOOL_DEFAULT, &buffer->impl.vb, 0));
}
void kinc_g4_vertex_buffer_destroy(kinc_g4_vertex_buffer_t *buffer) {
buffer->impl.vb->Release();
}
float *kinc_g4_vertex_buffer_lock_all(kinc_g4_vertex_buffer_t *buffer) {
return kinc_g4_vertex_buffer_lock(buffer, 0, kinc_g4_vertex_buffer_count(buffer));
}
float *kinc_g4_vertex_buffer_lock(kinc_g4_vertex_buffer_t *buffer, int start, int count) {
float *vertices;
kinc_internal_vertex_buffer_unset(buffer);
kinc_microsoft_affirm(buffer->impl.vb->Lock(start, count * kinc_g4_vertex_buffer_stride(buffer), (void **)&vertices, D3DLOCK_DISCARD));
return vertices;
}
void kinc_g4_vertex_buffer_unlock_all(kinc_g4_vertex_buffer_t *buffer) {
kinc_microsoft_affirm(buffer->impl.vb->Unlock());
}
void kinc_g4_vertex_buffer_unlock(kinc_g4_vertex_buffer_t *buffer, int count) {
kinc_microsoft_affirm(buffer->impl.vb->Unlock());
}
int kinc_internal_g4_vertex_buffer_set(kinc_g4_vertex_buffer_t *buffer, int offset) {
buffer->impl._offset = offset;
if (buffer->impl.instanceDataStepRate == 0) {
kinc_internal_current_vertex_buffer = buffer;
}
else {
kinc_microsoft_affirm(device->SetStreamSourceFreq(offset, (D3DSTREAMSOURCE_INSTANCEDATA | buffer->impl.instanceDataStepRate)));
}
kinc_microsoft_affirm(device->SetStreamSource(offset, buffer->impl.vb, 0, kinc_g4_vertex_buffer_stride(buffer)));
return 0;
}
void kinc_internal_vertex_buffer_unset(struct kinc_g4_vertex_buffer *buffer) {
if (kinc_internal_current_vertex_buffer == buffer) {
kinc_microsoft_affirm(device->SetStreamSource(0, NULL, 0, 0));
kinc_internal_current_vertex_buffer = NULL;
}
}
int kinc_g4_vertex_buffer_count(kinc_g4_vertex_buffer_t *buffer) {
return buffer->impl.myCount;
}
int kinc_g4_vertex_buffer_stride(kinc_g4_vertex_buffer_t *buffer) {
return buffer->impl.myStride;
}

View File

@ -0,0 +1,25 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct IDirect3DVertexBuffer9;
typedef struct {
struct IDirect3DVertexBuffer9 *vb;
int myCount;
int myStride;
int instanceDataStepRate;
int _offset;
} kinc_g4_vertex_buffer_impl_t;
struct kinc_g4_vertex_buffer;
void kinc_internal_vertex_buffer_unset(struct kinc_g4_vertex_buffer *buffer);
extern struct kinc_g4_vertex_buffer *kinc_internal_current_vertex_buffer;
#ifdef __cplusplus
}
#endif