Cube rendering in c!

This commit is contained in:
Adog64 2023-11-29 14:01:37 -05:00
commit ef44b24798
14 changed files with 502 additions and 0 deletions

62
Makefile Normal file
View File

@ -0,0 +1,62 @@
# the name of your executable
TARGET = PlanetMiner
# launches your target in terminal
RUN = ./$(TARGET)
# directory for your source files
SRC_DIR = src
# directory for your object files
BUILD_DIR = bin
# add more CompilerFLAGS as your project requires
CFLAGS = -Wall -Wextra -O3
# add libraries for your project here
LDFLAGS =
# add library linker commands here (start with -l)
LOADLIBS = -lglfw -lGLEW -lGL
# add library search paths here (start with -L)
LDLIBS =
# add include paths (start with -I)
INC =
# finds all your objects that corrispond to your .cpp files, system agnostic version
OBJECTS := $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c))
.PHONY: all
# makes build directory, updates your objects, builds your executable
all:
mkdir -p $(BUILD_DIR)
+$(MAKE) $(TARGET)
# updates your objects, builds your executable
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(CFLAGS) -o $@ $(LOADLIBS) $(LDFLAGS) $(LDLIBS) $(INC)
# builds your objects
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@ $(LOADLIBS) $(LDFLAGS) $(LDLIBS) $(INC)
# deletes your built objects and executable
.PHONY: clean
clean:
-rm -rf $(BUILD_DIR) $(TARGET)
clear
# makes build direcotry, updates your objects, builds your executable, launches your program
.PHONY: run
run:
+$(MAKE) all
$(RUN)
# explains the only three options you should be using (unless you build more of your own)
.PHONY: help
help:
@echo "`make` - builds/updates everything, is ready to run with `$(RUN)` after completion"
@echo "`make clean` - removes object file folder and executable"
@echo "`make run` - builds/updates everything, runs immediately"

BIN
PlanetMiner Executable file

Binary file not shown.

BIN
bin/main.o Normal file

Binary file not shown.

BIN
bin/textfiles.o Normal file

Binary file not shown.

32
devlog.md Normal file
View File

@ -0,0 +1,32 @@
# Planet Miner Development Log
## November 24th, 2023
### General Comments
- Messed around with Godot, didn't really find it all that interesting.
- Started writing a game engine in C.
- Really liking it so far
- Feels like I have finer control
- I'll definitely be using my mouse less, so that's nice
### C-Based Game Engine
- Boiler plate! Boiler plate! Boiler plate!
- I can't render a boiler or its plate yet.
- Window opens
- Can draw triangle with vertex and fragment shader
- Text file loading works
#### Text File Reading Functions
- Very nice
- Nice wrapper for builtin functions
- Probably will be used a lot, better keep it simple
### Error Codes?
- Gonna be writing a lot of code that throws errors, especially when writing all this darn ***BOILER PLATE***
- Error code standards to be implemented - will be documented when done
## November 25th, 2023
### Boiler plate
- Fixed text file loading not always null terminating stream
- Cube rendering!

View File

@ -0,0 +1,7 @@
#version 330 core
// Ouput data
out vec3 color;
void main()
{
color = vec3(1,1,1);
}

View File

@ -0,0 +1,9 @@
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
uniform mat4 MVP;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
}

14
src/controls.h Normal file
View File

@ -0,0 +1,14 @@
#include <cglm/structs.h>
typedef struct camera
{
vec3s pos;
vec3s dir;
vec3s
}
void goForward();
void goBackward();
void goLeft();
void goRight();
void yawLeft();

250
src/main.c Normal file
View File

@ -0,0 +1,250 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow* window;
#include <cglm/struct.h>
#define WINW 800
#define WINH 450
#define FOV 1.4f
#define SHADER_BUF_SIZE 1000
GLuint loadShaders(const char*, const char*);
int main()
{
glewExperimental = true;
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW :(\n" );
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(WINW, WINH, "Planet Miner", NULL, NULL);
if( window == NULL )
{
fprintf( stderr, "Failed to create window. If you are using an Intel GPU, please note that they are not compatible with OpenGL 3.3\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = true;
if( glewInit() != GLEW_OK )
{
fprintf( stderr, "Failed to initialize GLEW\n" );
getchar();
glfwTerminate();
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLuint vertexArrayID;
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
GLuint programID = loadShaders( "src/SimpleVertexShader.vertexshader", "src/SimpleFragmentShader.fragmentshader" );
GLuint matrixID = glGetUniformLocation(programID, "MVP");
mat4s projection = glms_perspective(FOV, 16.0f / 9.0f, 0.1f, 100.0f);
vec3s eye = {0.0f, 0.0f, 5.0f};
vec3s center = {0.0f, 0.0f, 0.0f};
vec3s up = {0.0f, 1.0f, 0.0f};
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, // triangle 1 : end
1.0f, 1.0f,-1.0f, // triangle 2 : begin
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f, // triangle 2 : end
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
vec3s direction = {0.0f, 0.0f, -5.0f};
do
{
glClear( GL_COLOR_BUFFER_BIT );
g
if( glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS )
{
eye.z -= 0.05f;
}
if( glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS )
{
eye.z += 0.05f;
}
if( glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS )
{
eye.x += 0.05f;
}
if( glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS )
{
eye.x -= 0.05f;
}
if( glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS )
{
eye.y += 0.05f;
}
if( glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS )
{
eye.y -= 0.05f;
}
center = glms_vec3_add(eye, direction);
mat4s view = glms_lookat(eye, center, up);
mat4s model = glms_mat4_identity();
mat4s mvp = glms_mat4_mul(glms_mat4_mul(projection, view), model);
glUseProgram(programID);
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &mvp);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glDrawArrays(GL_TRIANGLES, 0, 12*3);
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
while( glfwGetKey(window, GLFW_KEY_Q) | glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && !glfwWindowShouldClose(window));
glDeleteBuffers(1, &vertexbuffer);
glDeleteProgram(programID);
glDeleteVertexArrays(1, &vertexArrayID);
glfwTerminate();
return 0;
}
GLuint loadShaders(const char* vertexShaderPath, const char* fragmentShaderPath)
{
char* vertexShaderCode = readTextFile( vertexShaderPath );
char* fragmentShaderCode = readTextFile( fragmentShaderPath );
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLint result = GL_FALSE;
int infoLogLength;
printf("Compiling vertex shader...\n");
glShaderSource(vertexShaderID, 1, &vertexShaderCode, NULL);
glCompileShader(vertexShaderID);
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &result);
glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
if( infoLogLength > 0 )
{
char vertexShaderErrorMessage[infoLogLength + 1];
glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, &vertexShaderErrorMessage);
printf("%s\n", &vertexShaderErrorMessage);
}
printf("Compiling fragment shader...\n");
glShaderSource(fragmentShaderID, 1, &fragmentShaderCode, NULL);
glCompileShader(fragmentShaderID);
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &result);
glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
if( infoLogLength > 0 )
{
char fragmentShaderErrorMessage[infoLogLength + 1];
glGetShaderInfoLog(fragmentShaderID, infoLogLength, NULL, &fragmentShaderErrorMessage);
printf("%s\n", &fragmentShaderErrorMessage);
}
printf("Linking program\n");
GLuint programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
glGetProgramiv(programID, GL_LINK_STATUS, &result);
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
if( infoLogLength > 0 )
{
char programErrorMessage[infoLogLength + 1];
glGetProgramInfoLog(programID, infoLogLength, NULL, &programErrorMessage);
printf("%s\n", &programErrorMessage);
}
free( vertexShaderCode );
free( fragmentShaderCode );
glDetachShader( programID, vertexShaderID );
glDetachShader( programID, fragmentShaderID );
glDeleteShader( vertexShaderID );
glDeleteShader( fragmentShaderID );
return programID;
}

46
src/textfiles.c Normal file
View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#pragma once
// Reads an entire text file into a buffer.
// USES MALLOC BE SURE TO FREE
char* readTextFile(char* fname)
{
FILE* inFile;
long fileLength;
char* fileBuffer;
size_t result;
inFile = fopen( fname, "rb" );
if( inFile == NULL )
{
fprintf( stderr, "Failed open file, [%s].\n", fname );
exit(1);
}
fseek( inFile, 0, SEEK_END );
fileLength = ftell( inFile );
printf("File length: %d\n", fileLength);
rewind( inFile );
fileBuffer = (char*) malloc(sizeof(char) * (fileLength + 1));
if( fileBuffer == NULL )
{
fprintf( stderr, "Failed to allocate memory for reading the file, [%s].\n", fname);
exit(2);
}
result = fread( fileBuffer, 1, fileLength, inFile );
if( result != fileLength )
{
fprintf( stderr, "Failed while reading [%s] into the file buffer.\n", fname);
exit(3);
}
fileBuffer[fileLength] = '\0';
fclose( inFile );
return fileBuffer;
}

1
src/textfiles.h Normal file
View File

@ -0,0 +1 @@
char* readTextFile(char*);

21
src/worldgen.c Normal file
View File

@ -0,0 +1,21 @@
#include "worldgen.h"
#include <cglm/struct.h>
#define ORDER 1
#define RSQRT5 0.4472135954999579
#define TWICE_RSQRT5 = 0.8944271909999159
worldMesh generateWorld(vec3s position)
{
// placeholder struct for world mesh
worldMesh mesh;
vertex.count = 20 * ORDER * 3; // Icosahedron has 20 triangular sides
mesh.vertices = (GLfloat*) malloc(sizeof(GLfloat) * mesh.count);
populateIcosphere(mesh, ORDER, 1);
}
void populateIcosphere(worldMesh mesh, unsigned char order, float radius)
{
}

15
src/worldgen.h Normal file
View File

@ -0,0 +1,15 @@
#include <cglm/struct.h>
typedef struct worldMesh {
long int count;
GLfloat* vertices;
} worldMesh;
/*!
* @brief top-level world generation function
*
* @param[in] pos the position of the center of the roughly spherical world
* @return the world mesh as a heap-allocated list of vertices.
*/
worldMesh generateWorld(vec3s pos);

45
todo.md Normal file
View File

@ -0,0 +1,45 @@
# Planet Miner To Do List
## Priority List
1. Render stuff
1. Render a cube
2. Render a bunch of cubes
3. Diffuse lighting
4. Ray tracing?
2. Procedural worlds
1. Optimize rendering for this many cubes
3. Block game
1. World editing
## Idea Categories
1. Game Engine?
- Custom in C
- Started work on one, kinda liking it so far
- Don't really like pre-built game engines
- If I use one it'll likely be Godot
2. Voxelization
- Zoning
- Each planet has its own coordinate system (non-voxelized)
- Material is distributed in amorphous blobs containing a certain percent resource
- Before world editing can begin, a work zone must be established to create a local voxelized coordinate system
-
3. Progression
- The cores of planets exist as large non-voxelized structures
- Requires high level tools to mine
- Contain lots of resources
- Nickel
- Iron
- Asteroids can be mined like planet cores
- Less valuable resources
- Mostly rock
- Requires lower level tools
- Game starts on an Earth-like planet
- Make basic tool with sticks rope and stone fragments
- Stone fragments from smashing stones on rock
4. Documentation
- Error Codes!
- In-Game Wiki-System