Ok but what if: WGPU renderer?
This commit is contained in:
parent
a5380c4417
commit
1cca66b66f
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
|
@ -5,7 +5,7 @@ namespace hibis {
|
|||
// - Image
|
||||
/// RGBA value struct. Value is between 0 and 255
|
||||
struct Color {
|
||||
unsigned char r, g, b, a;
|
||||
double r, g, b, a;
|
||||
};
|
||||
|
||||
// - 2D
|
||||
|
|
159
external/glfw3webgpu/glfw3webgpu.c
vendored
Normal file
159
external/glfw3webgpu/glfw3webgpu.c
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
/**
|
||||
* This is an extension of GLFW for WebGPU, abstracting away the details of
|
||||
* OS-specific operations.
|
||||
*
|
||||
* This file is part of the "Learn WebGPU for C++" book.
|
||||
* https://eliemichel.github.io/LearnWebGPU
|
||||
*
|
||||
* Most of this code comes from the wgpu-native triangle example:
|
||||
* https://github.com/gfx-rs/wgpu-native/blob/master/examples/triangle/main.c
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2022-2023 Elie Michel and the wgpu-native authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glfw3webgpu.h"
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
#define WGPU_TARGET_MACOS 1
|
||||
#define WGPU_TARGET_LINUX_X11 2
|
||||
#define WGPU_TARGET_WINDOWS 3
|
||||
#define WGPU_TARGET_LINUX_WAYLAND 4
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define WGPU_TARGET WGPU_TARGET_WINDOWS
|
||||
#elif defined(__APPLE__)
|
||||
#define WGPU_TARGET WGPU_TARGET_MACOS
|
||||
#else
|
||||
#define WGPU_TARGET WGPU_TARGET_LINUX_X11
|
||||
#endif
|
||||
|
||||
#if WGPU_TARGET == WGPU_TARGET_MACOS
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <QuartzCore/CAMetalLayer.h>
|
||||
#endif
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#if WGPU_TARGET == WGPU_TARGET_MACOS
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#elif WGPU_TARGET == WGPU_TARGET_LINUX_X11
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#elif WGPU_TARGET == WGPU_TARGET_LINUX_WAYLAND
|
||||
#define GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
#elif WGPU_TARGET == WGPU_TARGET_WINDOWS
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#endif
|
||||
#include <GLFW/glfw3native.h>
|
||||
|
||||
WGPUSurface glfwGetWGPUSurface(WGPUInstance instance, GLFWwindow* window) {
|
||||
#if WGPU_TARGET == WGPU_TARGET_MACOS
|
||||
{
|
||||
id metal_layer = NULL;
|
||||
NSWindow* ns_window = glfwGetCocoaWindow(window);
|
||||
[ns_window.contentView setWantsLayer : YES] ;
|
||||
metal_layer = [CAMetalLayer layer];
|
||||
[ns_window.contentView setLayer : metal_layer] ;
|
||||
return wgpuInstanceCreateSurface(
|
||||
instance,
|
||||
&(WGPUSurfaceDescriptor){
|
||||
.label = NULL,
|
||||
.nextInChain =
|
||||
(const WGPUChainedStruct*)&(
|
||||
WGPUSurfaceDescriptorFromMetalLayer) {
|
||||
.chain =
|
||||
(WGPUChainedStruct){
|
||||
.next = NULL,
|
||||
.sType = WGPUSType_SurfaceDescriptorFromMetalLayer,
|
||||
},
|
||||
.layer = metal_layer,
|
||||
},
|
||||
});
|
||||
}
|
||||
#elif WGPU_TARGET == WGPU_TARGET_LINUX_X11
|
||||
{
|
||||
Display* x11_display = glfwGetX11Display();
|
||||
Window x11_window = glfwGetX11Window(window);
|
||||
return wgpuInstanceCreateSurface(
|
||||
instance,
|
||||
&(WGPUSurfaceDescriptor){
|
||||
.label = NULL,
|
||||
.nextInChain =
|
||||
(const WGPUChainedStruct*)&(
|
||||
WGPUSurfaceDescriptorFromXlibWindow) {
|
||||
.chain =
|
||||
(WGPUChainedStruct){
|
||||
.next = NULL,
|
||||
.sType = WGPUSType_SurfaceDescriptorFromXlibWindow,
|
||||
},
|
||||
.display = x11_display,
|
||||
.window = x11_window,
|
||||
},
|
||||
});
|
||||
}
|
||||
#elif WGPU_TARGET == WGPU_TARGET_LINUX_WAYLAND
|
||||
{
|
||||
struct wl_display* wayland_display = glfwGetWaylandDisplay();
|
||||
struct wl_surface* wayland_surface = glfwGetWaylandWindow(window);
|
||||
return wgpuInstanceCreateSurface(
|
||||
instance,
|
||||
&(WGPUSurfaceDescriptor){
|
||||
.label = NULL,
|
||||
.nextInChain =
|
||||
(const WGPUChainedStruct*)&(
|
||||
WGPUSurfaceDescriptorFromWaylandSurface) {
|
||||
.chain =
|
||||
(WGPUChainedStruct){
|
||||
.next = NULL,
|
||||
.sType =
|
||||
WGPUSType_SurfaceDescriptorFromWaylandSurface,
|
||||
},
|
||||
.display = wayland_display,
|
||||
.surface = wayland_surface,
|
||||
},
|
||||
});
|
||||
}
|
||||
#elif WGPU_TARGET == WGPU_TARGET_WINDOWS
|
||||
{
|
||||
HWND hwnd = glfwGetWin32Window(window);
|
||||
HINSTANCE hinstance = GetModuleHandle(NULL);
|
||||
return wgpuInstanceCreateSurface(
|
||||
instance,
|
||||
&(WGPUSurfaceDescriptor){
|
||||
.label = NULL,
|
||||
.nextInChain =
|
||||
(const WGPUChainedStruct*)&(
|
||||
WGPUSurfaceDescriptorFromWindowsHWND) {
|
||||
.chain =
|
||||
(WGPUChainedStruct){
|
||||
.next = NULL,
|
||||
.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND,
|
||||
},
|
||||
.hinstance = hinstance,
|
||||
.hwnd = hwnd,
|
||||
},
|
||||
});
|
||||
}
|
||||
#else
|
||||
#error "Unsupported WGPU_TARGET"
|
||||
#endif
|
||||
}
|
||||
|
49
external/glfw3webgpu/glfw3webgpu.h
vendored
Normal file
49
external/glfw3webgpu/glfw3webgpu.h
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* This is an extension of GLFW for WebGPU, abstracting away the details of
|
||||
* OS-specific operations.
|
||||
*
|
||||
* This file is part of the "Learn WebGPU for C++" book.
|
||||
* https://eliemichel.github.io/LearnWebGPU
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2022-2023 Elie Michel and the wgpu-native authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _glfw3_webgpu_h_
|
||||
#define _glfw3_webgpu_h_
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get a WGPUSurface from a GLFW window.
|
||||
*/
|
||||
WGPUSurface glfwGetWGPUSurface(WGPUInstance instance, GLFWwindow* window);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _glfw3_webgpu_h_
|
14
meson.build
14
meson.build
|
@ -1,6 +1,10 @@
|
|||
project('hibis', 'cpp', version: '0.0.0' + (not get_option('buildtype').startswith('release') ? '-' + run_command('git', 'rev-parse', '--short', 'HEAD', check: true).stdout().strip() : ''),
|
||||
project('hibis', 'cpp', 'c', version: '0.0.0' + (not get_option('buildtype').startswith('release') ? '-' + run_command('git', 'rev-parse', '--short', 'HEAD', check: true).stdout().strip() : ''),
|
||||
license: 'LGPL-3.0-only', meson_version: '>=0.60.3', default_options: ['cpp_std=c++17'])
|
||||
|
||||
# Imports
|
||||
|
||||
cmake = import('cmake')
|
||||
|
||||
# Configure data
|
||||
confdata = configuration_data()
|
||||
confdata.set('version', meson.project_version())
|
||||
|
@ -16,6 +20,7 @@ libhibis_src_renderer = files('core/renderer/renderer.cpp')
|
|||
libhibis_src_resources = files('core/resources/texture.cpp', 'core/resources/font.cpp', 'core/resources/shader.cpp')
|
||||
libhibis_src = [libhibis_src_core, libhibis_src_renderer, libhibis_src_resources]
|
||||
|
||||
libhibis_rwgpu_src = files('renderer/rwgpu/rwgpu.cpp')
|
||||
libhibis_rglcore_src = files('renderer/rglcore/rglcore.cpp')
|
||||
libhibis_test_src = files('test/app.cpp')
|
||||
|
||||
|
@ -24,9 +29,14 @@ libgl = dependency('gl')
|
|||
libglfw = dependency('glfw3')
|
||||
libglew = dependency('GLEW')
|
||||
libfmt = dependency('fmt')
|
||||
libwgpu = meson.get_compiler('cpp').find_library('wgpu_native')
|
||||
|
||||
libwgpu_glfw = static_library('glfw3webgpu', 'external/glfw3webgpu/glfw3webgpu.c', dependencies: [libglfw])
|
||||
|
||||
libfreetype2 = dependency('freetype2')
|
||||
|
||||
# Compile
|
||||
libhibis = library('hibis', libhibis_src, include_directories: include_dirs, dependencies: [libfreetype2])
|
||||
libhibis_rglcore = library('hibis_rglcore', libhibis_rglcore_src, include_directories: [include_dirs, './core'], link_with: libhibis, dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])
|
||||
hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rglcore'], link_with: [libhibis, libhibis_rglcore], dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])
|
||||
libhibis_rwgpu = library('hibis_rwgpu', libhibis_rwgpu_src, include_directories: [include_dirs, './core'], link_with: [libhibis, libwgpu_glfw], dependencies: [libfreetype2, libglfw, libfmt, libwgpu])
|
||||
hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rwgpu'], link_with: [libhibis, libhibis_rwgpu], dependencies: [libfreetype2, libglfw, libfmt, libwgpu])
|
||||
|
|
|
@ -78,8 +78,6 @@ namespace hibis::rglcore {
|
|||
glUseProgram(shader->mShaderProgram);
|
||||
glBindVertexArray(shader->mShaderVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void RGLCore::stopUsingShaders() {
|
||||
|
|
232
renderer/rwgpu/rwgpu.cpp
Normal file
232
renderer/rwgpu/rwgpu.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
#define WEBGPU_CPP_IMPLEMENTATION
|
||||
#include <fmt/format.h>
|
||||
#include <sstream>
|
||||
#include <webgpu/webgpu.hpp>
|
||||
|
||||
#include <glfw3webgpu/glfw3webgpu.h>
|
||||
|
||||
#include "rwgpu.hpp"
|
||||
|
||||
namespace hibis::rwgpu {
|
||||
RWGPU::RWGPU(std::string title, IntVec2 size, LoggerCallback callback) : Renderer(callback) {
|
||||
wgpu::InstanceDescriptor instanceDescriptor = {};
|
||||
wgpu::RequestAdapterOptions reqAdaptOpts = {};
|
||||
wgpu::DeviceDescriptor deviceDescriptor = {};
|
||||
|
||||
deviceDescriptor.nextInChain = nullptr;
|
||||
deviceDescriptor.label = "My Device"; // anything works here, that's your call
|
||||
deviceDescriptor.requiredFeaturesCount = 0; // we do not require any specific feature
|
||||
deviceDescriptor.requiredLimits = nullptr; // we do not require any specific limit
|
||||
deviceDescriptor.defaultQueue.nextInChain = nullptr;
|
||||
deviceDescriptor.defaultQueue.label = "The default queue";
|
||||
|
||||
mWebGPUInstance = wgpu::createInstance(instanceDescriptor);
|
||||
mWebGPUAdapter = requestAdapter(&reqAdaptOpts);
|
||||
mWebGPUDevice = requestDevice(&deviceDescriptor);
|
||||
mWebGPUQueue = mWebGPUDevice.getQueue();
|
||||
|
||||
if (!mWebGPUInstance) {
|
||||
mLogger(Fatal, "Could not initialize WebGPU!");
|
||||
exit(1);
|
||||
} else {
|
||||
const void * address = static_cast<const void*>(mWebGPUInstance);
|
||||
std::stringstream pointerAsStream;
|
||||
pointerAsStream << address;
|
||||
mLogger(Information, fmt::format("WGPU Instance Addr: {}", pointerAsStream.str()));
|
||||
}
|
||||
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
|
||||
mWindow = glfwCreateWindow(size.x, size.y, title.c_str(), NULL, NULL);
|
||||
|
||||
mWebGPUSurface = glfwGetWGPUSurface(mWebGPUInstance, mWindow);
|
||||
|
||||
size_t featureCount = wgpuAdapterEnumerateFeatures(mWebGPUAdapter, nullptr);
|
||||
|
||||
// Allocate memory (could be a new, or a malloc() if this were a C program)
|
||||
mWebGPUFeatures.resize(featureCount);
|
||||
|
||||
// Call the function a second time, with a non-null return address
|
||||
wgpuAdapterEnumerateFeatures(mWebGPUAdapter, mWebGPUFeatures.data());
|
||||
|
||||
mLogger(Information, "Adapter features: ");
|
||||
for (wgpu::FeatureName f : mWebGPUFeatures) {
|
||||
mLogger(Information, fmt::format("WebGPU Feature: {}", f));
|
||||
}
|
||||
|
||||
auto onDeviceError = [](WGPUErrorType type, char const* message, void* /* pUserData */) {
|
||||
std::cout << "Uncaptured device error: type " << type;
|
||||
if (message) std::cout << " (" << message << ")";
|
||||
std::cout << std::endl;
|
||||
};
|
||||
|
||||
wgpuDeviceSetUncapturedErrorCallback(mWebGPUDevice, onDeviceError, nullptr /* pUserData */);
|
||||
|
||||
// Not implemented, causes a panic
|
||||
// auto onQueueWorkDone = [](WGPUQueueWorkDoneStatus status, void* /* pUserData */) {
|
||||
// std::cout << "Queued work finished with status: " << status << std::endl;
|
||||
// };
|
||||
// wgpuQueueOnSubmittedWorkDone(mWebGPUQueue, onQueueWorkDone, nullptr /* pUserData */);
|
||||
|
||||
WGPUSwapChainDescriptor swapChainDesc = {};
|
||||
swapChainDesc.nextInChain = nullptr;
|
||||
swapChainDesc.width = size.x;
|
||||
swapChainDesc.height = size.y;
|
||||
|
||||
WGPUTextureFormat swapChainFormat = wgpuSurfaceGetPreferredFormat(mWebGPUSurface, mWebGPUAdapter);
|
||||
swapChainDesc.format = swapChainFormat;
|
||||
|
||||
swapChainDesc.usage = WGPUTextureUsage_RenderAttachment;
|
||||
swapChainDesc.presentMode = WGPUPresentMode_Fifo;
|
||||
|
||||
mWebGPUSwapChain = wgpuDeviceCreateSwapChain(mWebGPUDevice, mWebGPUSurface, &swapChainDesc);
|
||||
}
|
||||
|
||||
RWGPU::~RWGPU() {
|
||||
glfwDestroyWindow(mWindow);
|
||||
|
||||
mWebGPUSwapChain.drop();
|
||||
mWebGPUSurface.drop();
|
||||
mWebGPUDevice.drop();
|
||||
mWebGPUAdapter.drop();
|
||||
mWebGPUInstance.drop();
|
||||
}
|
||||
|
||||
WGPUAdapter RWGPU::requestAdapter(WGPURequestAdapterOptions const * options) {
|
||||
// A simple structure holding the local information shared with the
|
||||
// onAdapterRequestEnded callback.
|
||||
struct UserData {
|
||||
WGPUAdapter adapter = nullptr;
|
||||
bool requestEnded = false;
|
||||
};
|
||||
UserData userData;
|
||||
|
||||
// Callback called by wgpuInstanceRequestAdapter when the request returns
|
||||
// This is a C++ lambda function, but could be any function defined in the
|
||||
// global scope. It must be non-capturing (the brackets [] are empty) so
|
||||
// that it behaves like a regular C function pointer, which is what
|
||||
// wgpuInstanceRequestAdapter expects (WebGPU being a C API). The workaround
|
||||
// is to convey what we want to capture through the pUserData pointer,
|
||||
// provided as the last argument of wgpuInstanceRequestAdapter and received
|
||||
// by the callback as its last argument.
|
||||
auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, char const * message, void * pUserData) {
|
||||
UserData& userData = *reinterpret_cast<UserData*>(pUserData);
|
||||
if (status == WGPURequestAdapterStatus_Success) {
|
||||
userData.adapter = adapter;
|
||||
} else {
|
||||
std::cout << "Could not get WebGPU adapter: " << message << std::endl;
|
||||
}
|
||||
userData.requestEnded = true;
|
||||
};
|
||||
|
||||
// Call to the WebGPU request adapter procedure
|
||||
wgpuInstanceRequestAdapter(
|
||||
mWebGPUInstance /* equivalent of navigator.gpu */,
|
||||
options,
|
||||
onAdapterRequestEnded,
|
||||
(void*)&userData
|
||||
);
|
||||
|
||||
// In theory we should wait until onAdapterReady has been called, which
|
||||
// could take some time (what the 'await' keyword does in the JavaScript
|
||||
// code). In practice, we know that when the wgpuInstanceRequestAdapter()
|
||||
// function returns its callback has been called.
|
||||
assert(userData.requestEnded);
|
||||
|
||||
return userData.adapter;
|
||||
}
|
||||
|
||||
WGPUDevice RWGPU::requestDevice(WGPUDeviceDescriptor const * descriptor) {
|
||||
struct UserData {
|
||||
WGPUDevice device = nullptr;
|
||||
bool requestEnded = false;
|
||||
};
|
||||
UserData userData;
|
||||
|
||||
auto onDeviceRequestEnded = [](WGPURequestDeviceStatus status, WGPUDevice device, char const * message, void * pUserData) {
|
||||
UserData& userData = *reinterpret_cast<UserData*>(pUserData);
|
||||
if (status == WGPURequestDeviceStatus_Success) {
|
||||
userData.device = device;
|
||||
} else {
|
||||
std::cout << "Could not get WebGPU device: " << message << std::endl;
|
||||
}
|
||||
userData.requestEnded = true;
|
||||
};
|
||||
|
||||
wgpuAdapterRequestDevice(
|
||||
mWebGPUAdapter,
|
||||
descriptor,
|
||||
onDeviceRequestEnded,
|
||||
(void*)&userData
|
||||
);
|
||||
|
||||
assert(userData.requestEnded);
|
||||
|
||||
return userData.device;
|
||||
}
|
||||
|
||||
void RWGPU::clearScreen(Color col) {
|
||||
mCurrentClearColor = {col.r, col.g, col.b, col.a};
|
||||
}
|
||||
|
||||
void RWGPU::renderCurrent() {
|
||||
wgpu::TextureView nextTexture = mWebGPUSwapChain.getCurrentTextureView();
|
||||
if (!nextTexture) {
|
||||
mLogger(Error, "Couldn't create next texture");
|
||||
return;
|
||||
}
|
||||
WGPUCommandEncoderDescriptor encoderDesc = {};
|
||||
encoderDesc.nextInChain = nullptr;
|
||||
encoderDesc.label = "HibisDrawCommandEncoder";
|
||||
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(mWebGPUDevice, &encoderDesc);
|
||||
|
||||
WGPURenderPassDescriptor renderPassDesc = {};
|
||||
|
||||
WGPURenderPassColorAttachment renderPassColorAttachment = {};
|
||||
|
||||
renderPassDesc.colorAttachmentCount = 1;
|
||||
renderPassDesc.colorAttachments = &renderPassColorAttachment;
|
||||
|
||||
renderPassColorAttachment.view = nextTexture;
|
||||
renderPassColorAttachment.resolveTarget = nullptr;
|
||||
renderPassColorAttachment.loadOp = WGPULoadOp_Clear;
|
||||
renderPassColorAttachment.storeOp = WGPUStoreOp_Store;
|
||||
renderPassColorAttachment.clearValue = mCurrentClearColor;
|
||||
renderPassDesc.depthStencilAttachment = nullptr;
|
||||
|
||||
renderPassDesc.timestampWriteCount = 0;
|
||||
renderPassDesc.timestampWrites = nullptr;
|
||||
renderPassDesc.nextInChain = nullptr;
|
||||
|
||||
WGPURenderPassEncoder renderPass = wgpuCommandEncoderBeginRenderPass(encoder, &renderPassDesc);
|
||||
wgpuRenderPassEncoderEnd(renderPass);
|
||||
|
||||
WGPUCommandBufferDescriptor cmdBufferDescriptor = {};
|
||||
cmdBufferDescriptor.nextInChain = nullptr;
|
||||
cmdBufferDescriptor.label = "Command buffer";
|
||||
WGPUCommandBuffer command = wgpuCommandEncoderFinish(encoder, &cmdBufferDescriptor);
|
||||
wgpuQueueSubmit(mWebGPUQueue, 1, &command);
|
||||
|
||||
mWebGPUSwapChain.present();
|
||||
nextTexture.drop();
|
||||
}
|
||||
|
||||
void RWGPU::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {}
|
||||
void RWGPU::drawTexture(Texture* resource, IntRect size) {}
|
||||
|
||||
void RWGPU::useShader(Shader* shader, Point2D points[3]) {}
|
||||
void RWGPU::stopUsingShaders() {}
|
||||
|
||||
void RWGPU::preDraw() {}
|
||||
void RWGPU::postDraw() {}
|
||||
|
||||
void RWGPU::update() {
|
||||
mKeepOpen = !glfwWindowShouldClose(mWindow);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
void RWGPU::compileShader(Shader* shader) {}
|
||||
void RWGPU::toggleWireframe() {}
|
||||
void RWGPU::setWindowTitle(std::string title) {}
|
||||
}
|
55
renderer/rwgpu/rwgpu.hpp
Normal file
55
renderer/rwgpu/rwgpu.hpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <webgpu/webgpu.hpp>
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <renderer/renderer.hpp>
|
||||
|
||||
namespace hibis::rwgpu {
|
||||
class RWGPU : public Renderer {
|
||||
public:
|
||||
RWGPU(std::string title, IntVec2 size, LoggerCallback callback);
|
||||
~RWGPU();
|
||||
|
||||
// Draw
|
||||
void clearScreen(Color col = Color {0, 0, 0, 255}) override;
|
||||
void renderCurrent() override;
|
||||
|
||||
void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) override;
|
||||
void drawTexture(Texture* resource, IntRect size) override;
|
||||
|
||||
void useShader(Shader* shader, Point2D points[3]) override;
|
||||
void stopUsingShaders() override;
|
||||
|
||||
// Pre and Post draw
|
||||
void preDraw() override;
|
||||
void postDraw() override;
|
||||
|
||||
// Update
|
||||
void update() override;
|
||||
|
||||
// Util
|
||||
void compileShader(Shader* shader) override;
|
||||
void toggleWireframe() override;
|
||||
void setWindowTitle(std::string title) override;
|
||||
|
||||
std::vector<WGPUFeatureName> mWebGPUFeatures;
|
||||
private:
|
||||
WGPUAdapter requestAdapter(WGPURequestAdapterOptions const * options);
|
||||
WGPUDevice requestDevice(WGPUDeviceDescriptor const * descriptor);
|
||||
|
||||
GLFWwindow* mWindow;
|
||||
wgpu::Instance mWebGPUInstance = nullptr;
|
||||
wgpu::Adapter mWebGPUAdapter = nullptr;
|
||||
wgpu::Device mWebGPUDevice = nullptr;
|
||||
wgpu::Queue mWebGPUQueue = nullptr;
|
||||
wgpu::SwapChain mWebGPUSwapChain = nullptr;
|
||||
|
||||
wgpu::Surface mWebGPUSurface = nullptr;
|
||||
|
||||
wgpu::Color mCurrentClearColor = {0.9, 0.1, 0.2, 1.0};
|
||||
};
|
||||
}
|
14
test/app.cpp
14
test/app.cpp
|
@ -1,8 +1,7 @@
|
|||
#include <logging/types.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <renderer/renderer.hpp>
|
||||
#include <rglcore.hpp>
|
||||
#include <resources/font.hpp>
|
||||
#include <rwgpu.hpp>
|
||||
#include <resources/font.hpp>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
@ -18,7 +17,7 @@ WARNING("Please avoid using MSVC in C++ projects utilising std::chrono and std::
|
|||
#endif
|
||||
|
||||
using namespace hibis;
|
||||
using namespace hibis::rglcore;
|
||||
using namespace hibis::rwgpu;
|
||||
|
||||
void logger(LoggingSeverity severity, std::string message) {
|
||||
std::string sevString;
|
||||
|
@ -45,8 +44,9 @@ void logger(LoggingSeverity severity, std::string message) {
|
|||
|
||||
int main() {
|
||||
logger(Information, fmt::format("PWD: {}", std::getenv("PWD")));
|
||||
RGLCore renderer = RGLCore("test", IntVec2 {800, 600}, &logger);
|
||||
RWGPU renderer = RWGPU("test", IntVec2 {800, 600}, &logger);
|
||||
Engine engine = Engine(&renderer, &logger);
|
||||
/*
|
||||
|
||||
#ifdef _WIN32
|
||||
Font font = Font(engine.mFreeTypeLibrary, "C:\\Windows\\Fonts\\Arial.ttf", 16);
|
||||
|
@ -67,9 +67,10 @@ int main() {
|
|||
uint f = 0;
|
||||
|
||||
Point2D points[3] = {{-0.5f, -0.5f}, {0.5f, -0.5f}, {0.0f, 0.5f}};
|
||||
|
||||
*/
|
||||
logger(Information, "Started Hibis test app! BEHOLD: Colours.");
|
||||
while (renderer.mKeepOpen) {
|
||||
/*
|
||||
// Colour changing background!
|
||||
if ((red == 255 && increaseRed) || (red == 0 && !increaseRed)) {
|
||||
increaseRed = !increaseRed;
|
||||
|
@ -87,9 +88,10 @@ int main() {
|
|||
else size -= 2;
|
||||
font.setFontSize(size);
|
||||
}
|
||||
*/
|
||||
|
||||
// Clear screen then sleep for ~16ms
|
||||
renderer.clearScreen(Color {red, 0, 0, 255});
|
||||
//renderer.clearScreen(Color {red, 0, 0, 255});
|
||||
//renderer.useShader(&shader, points);
|
||||
//renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255});
|
||||
//renderer.drawTexture(&image, 1.0f, IntVec2 {10, 10});
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||
gl_Position = vec4(aPos, 1.0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue