Initial commit of C vulkan code

main
noah metz 2024-10-09 10:54:19 -06:00
parent 28fc752354
commit 2accc9a952
11 changed files with 20341 additions and 221 deletions

@ -0,0 +1,55 @@
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
CFLAGS = -I $(ROOT_DIR)/include -I/usr/local/include -O0 -g -Wall -Wextra
LDFLAGS = -L/opt/homebrew/opt/llvm/lib -L/opt/homebrew/opt/llvm/lib/c++ -L/opt/homebrew/lib -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /opt/homebrew/lib
CC = /opt/homebrew/opt/llvm/bin/clang
CPP = /opt/homebrew/opt/llvm/bin/clang++
DSYM = /opt/homebrew/opt/llvm/bin/dsymutil
GDB = /opt/homebrew/opt/llvm/bin/lldb
SOURCES = src/main.c src/render.c src/vma.cpp
OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert)))
FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag)))
export MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1
.PHONY: all
all: roleplay $(VERT_SPV) $(FRAG_SPV)
roleplay: $(OBJECTS)
$(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $^
%.o: %.cpp
$(CPP) $(CFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
.PHONY: clean clean_compdb
clean:
rm -f $(FRAG_SPV)
rm -f $(VERT_SPV)
rm -f $(OBJECTS)
rm -f roleplay
rm -rf roleplay.dSYM
clean_compdb:
rm -rf .compdb
rm compile_commands.json
run: roleplay
./roleplay
roleplay.dSYM: roleplay
$(DSYM) roleplay
debug: roleplay roleplay.dSYM
$(GDB) roleplay
%.vert.spv: %.vert
glslangValidator -V -o $@ $<
%.frag.spv: %.frag
glslangValidator -V -o $@ $<

@ -0,0 +1,91 @@
#ifndef RENDER_H
#define RENDER_H
#define VK_USE_PLATFORM_MACOS_MVK
#include "vulkan/vulkan_core.h"
#include "vulkan/vk_enum_string_helper.h"
#include "vk_mem_alloc.h"
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#define GLFW_EXPOSE_NATIVE_COCOA
#include <GLFW/glfw3native.h>
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <cglm/types.h>
#include <cglm/mat4.h>
#include <cglm/vec3.h>
#include <cglm/affine.h>
#include <cglm/quat.h>
#include <cglm/cam.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct QueueStruct {
VkQueue handle;
uint32_t family;
uint32_t index;
} Queue;
typedef struct SwapchainDetailsStruct {
VkSurfaceCapabilitiesKHR capabilities;
VkSurfaceFormatKHR* formats;
uint32_t formats_count;
VkPresentModeKHR* present_modes;
uint32_t present_modes_count;
} SwapchainDetails;
typedef struct RenderContextStruct {
VkInstance instance;
VkDebugUtilsMessengerEXT debug_messenger;
VkPhysicalDevice physical_device;
VkPhysicalDeviceMemoryProperties memories;
VkSurfaceKHR surface;
Queue graphics_queue;
Queue present_queue;
Queue transfer_queue;
VkDevice device;
VmaAllocator allocator;
SwapchainDetails swapchain_details;
VkSurfaceFormatKHR swapchain_format;
VkPresentModeKHR swapchain_present_mode;
VkExtent2D swapchain_extent;
VkSwapchainKHR swapchain;
uint32_t swapchain_image_count;
VkImage* swapchain_images;
VkImageView* swapchain_image_views;
VkFramebuffer* swapchain_framebuffers;
VkFormat depth_format;
VkImageView depth_image_view;
VkImage depth_image;
VmaAllocation depth_image_memory;
VkCommandPool extra_graphics_pool;
VkCommandPool graphics_pool;
VkCommandPool transfer_pool;
VkRenderPass render_pass;
VkCommandBuffer* swapchain_command_buffers;
VkSemaphore* image_available_semaphores;
VkSemaphore* render_finished_semaphores;
VkFence* in_flight_fences;
VkPipeline ui_pipeline_rect;
VkPipeline ui_pipeline_text;
} RenderContext;
GLFWwindow* init_window();
VkResult init_vulkan(GLFWwindow* window, RenderContext* context);
#endif

File diff suppressed because it is too large Load Diff

@ -1,221 +0,0 @@
package main
import (
"time"
"github.com/gen2brain/raylib-go/raylib"
)
type ClientAuth struct {
}
type Entity struct {
}
type LoginState int
const (
LOGIN_STATE_CREDENTIALS LoginState = iota
LOGIN_STATE_ATTEMPTING
LOGIN_STATE_ERROR
)
type ButtonState int
const (
BUTTON_STATE_IDLE ButtonState = iota
BUTTON_STATE_HOVER
BUTTON_STATE_PRESSED
)
type Scale struct {
window rl.Vector2
ui uint
}
type ClientState struct {
auth *ClientAuth
login LoginState
login_button ButtonState
scale Scale
screen rl.Rectangle
camera rl.Camera
command_queue chan interface{}
network_queue chan interface{}
context *Entity
context_pos rl.Vector2
}
const (
WIDTH uint = 1600
HEIGHT uint = 1000
)
func scale(original rl.Rectangle, scale Scale) rl.Rectangle {
return rl.Rectangle{
X: original.X,
Y: original.Y,
Width: original.Width*float32(scale.ui)/scale.window.X,
Height: original.Height*float32(scale.ui)/scale.window.Y,
}
}
func offset(original rl.Rectangle, off_x, off_y int, scale Scale) rl.Rectangle {
return rl.Rectangle{
X: original.X + float32(off_x)/scale.window.X,
Y: original.Y + float32(off_y)/scale.window.Y,
Width: original.Width,
Height: original.Height,
}
}
func center(container, original rl.Rectangle) rl.Rectangle {
return rl.Rectangle{
X: (container.Width - original.Width )/2 + container.X,
Y: (container.Height - original.Height)/2 + container.Y,
Width: original.Width,
Height: original.Height,
}
}
func button(rectangle rl.Rectangle, idle, hover, pressed rl.Color, text string, font_size int32, text_color rl.Color, last_state ButtonState) (action bool, next_state ButtonState) {
over := rl.CheckCollisionPointRec(rl.GetMousePosition(), rectangle)
action = false
next_state = last_state
if(rl.IsMouseButtonPressed(rl.MouseButtonLeft) && over) {
next_state = BUTTON_STATE_PRESSED
} else if(rl.IsMouseButtonReleased(rl.MouseButtonLeft) && last_state == BUTTON_STATE_PRESSED) {
next_state = BUTTON_STATE_IDLE
if(over) {
action = true
}
} else if(rl.IsMouseButtonUp(rl.MouseButtonLeft)) {
if(last_state == BUTTON_STATE_IDLE && over) {
next_state = BUTTON_STATE_HOVER
} else if (last_state == BUTTON_STATE_HOVER && !over) {
next_state = BUTTON_STATE_IDLE
}
}
var color rl.Color
switch(next_state) {
case BUTTON_STATE_HOVER:
color = hover
case BUTTON_STATE_PRESSED:
color = pressed
default:
color = idle
}
rl.DrawRectangleRec(rectangle, color)
text_size := rl.MeasureTextEx(rl.GetFontDefault(), text, float32(font_size), 1.0)
rl.DrawText(text, int32(rectangle.X + rectangle.Width/2 - text_size.X/2), int32(rectangle.Y + rectangle.Height/2 - text_size.Y/2), font_size, text_color)
return action, next_state
}
func NetworkThread(network_queue chan interface{}) {
for(true) {
// TODO: remove
time.Sleep(time.Millisecond)
}
}
func LogicThread(state *ClientState) {
for(true) {
select {
case _ = <- state.command_queue:
case _ = <- state.network_queue:
}
time.Sleep(time.Millisecond)
}
}
func main() {
state := ClientState{
auth: nil,
login: LOGIN_STATE_CREDENTIALS,
login_button: BUTTON_STATE_IDLE,
scale: Scale{
ui: 1,
},
camera: rl.NewCamera3D(rl.Vector3{}, rl.Vector3{}, rl.Vector3{}, 90, rl.CameraOrthographic),
context: nil,
}
go LogicThread(&state)
rl.SetConfigFlags(rl.FlagWindowHighdpi)
rl.InitWindow(0, 0, "roleplay")
rl.SetExitKey(0)
rl.SetTargetFPS(60)
state.scale.window = rl.GetWindowScaleDPI()
rl.SetWindowSize(int(float32(WIDTH)/state.scale.window.X), int(float32(HEIGHT)/state.scale.window.Y))
state.screen.Width = float32(WIDTH) /state.scale.window.X
state.screen.Height = float32(HEIGHT)/state.scale.window.Y
for(rl.WindowShouldClose() == false) {
if(state.auth == nil) {
// Draw login
rl.BeginDrawing()
rl.ClearBackground(rl.Black)
logo_rect := scale(rl.Rectangle{Width: 1200, Height: 300}, state.scale)
logo_rect = center(state.screen, logo_rect)
logo_rect = offset(logo_rect, 0, -250, state.scale)
rl.DrawRectangleRec(logo_rect, rl.Gray)
form_rect := scale(rl.Rectangle{Width: 600, Height: 400}, state.scale)
form_rect = center(state.screen, form_rect)
form_rect = offset(form_rect, 0, 200, state.scale)
rl.DrawRectangleRec(form_rect, rl.Gray)
switch(state.login) {
case LOGIN_STATE_CREDENTIALS:
submit_rect := scale(rl.Rectangle{Width: 100, Height: 50}, state.scale)
submit_rect = center(form_rect, submit_rect)
submit_rect = offset(submit_rect, 0, 125, state.scale)
var submit_action bool
submit_action, state.login_button = button(submit_rect, rl.Black, rl.Brown, rl.Red, "Submit", 12, rl.White, state.login_button)
if submit_action {
// TODO: real auth via network thread
state.auth = &ClientAuth{}
}
case LOGIN_STATE_ATTEMPTING:
text := "Logging in..."
text_size := rl.MeasureTextEx(rl.GetFontDefault(), text, 20, 1.0)
text_rect := center(form_rect, rl.Rectangle{Width: text_size.X, Height: text_size.Y})
rl.DrawText(text, int32(text_rect.X), int32(text_rect.Y), 20, rl.Black)
case LOGIN_STATE_ERROR:
text := "Error: {TODO}"
text_size := rl.MeasureTextEx(rl.GetFontDefault(), text, 20, 1.0)
text_rect := center(form_rect, rl.Rectangle{Width: text_size.X, Height: text_size.Y})
rl.DrawText(text, int32(text_rect.X), int32(text_rect.Y), 20, rl.Black)
}
rl.EndDrawing()
} else {
rl.BeginDrawing()
rl.ClearBackground(rl.Black)
rl.BeginMode3D(state.camera)
if rl.IsMouseButtonPressed(rl.MouseButtonRight) {
state.context_pos = rl.GetMousePosition()
// TODO: Cast a ray into the bounding boxes
}
if state.context != nil {
}
rl.EndMode3D()
rl.EndDrawing()
}
}
}

@ -0,0 +1,34 @@
#include "render.h"
int render_thread(GLFWwindow* window, RenderContext* render_context) {
while(glfwWindowShouldClose(window) == 0) {
glfwPollEvents();
}
return 0;
}
int logic_thread() {
return 0;
}
int network_thread() {
return 0;
}
int main() {
GLFWwindow* window = init_window();
if(window == NULL) {
return 1;
}
RenderContext render_context = {};
if(init_vulkan(window, &render_context) != VK_SUCCESS) {
return 2;
}
if(render_thread(window, &render_context) != 0) {
return 3;
}
return 0;
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -0,0 +1,2 @@
#define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h"

Binary file not shown.