forked from LeenkxTeam/LNXSDK
		
	Update Files
This commit is contained in:
		| @ -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) {} | ||||
| @ -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; | ||||
| @ -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) {} | ||||
| @ -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 | ||||
| @ -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 | ||||
| @ -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 | ||||
| @ -0,0 +1,6 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "IndexBufferImpl.h" | ||||
| #include "RenderTargetImpl.h" | ||||
| #include "ShaderImpl.h" | ||||
| #include "VertexBufferImpl.h" | ||||
| @ -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; | ||||
| } | ||||
| @ -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 | ||||
| @ -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; | ||||
| } | ||||
| @ -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 | ||||
| @ -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) {} | ||||
| @ -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 | ||||
| @ -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) {} | ||||
| @ -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 | ||||
| @ -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) {} | ||||
| @ -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 | ||||
| @ -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) {} | ||||
| @ -0,0 +1,13 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| typedef struct { | ||||
| 	int nothing; | ||||
| } kinc_g4_texture_array_impl_t; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -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; | ||||
| } | ||||
| @ -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 | ||||
		Reference in New Issue
	
	Block a user