Initial commit of C vulkan code
parent
28fc752354
commit
2accc9a952
@ -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.
Loading…
Reference in New Issue