refactor for desktop, z-buffer for textured triangles
This commit is contained in:
parent
9529b89127
commit
95c015d719
109
CMakeLists.txt
109
CMakeLists.txt
@ -1,9 +1,74 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
project(sdl_project)
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
# Include the command that downloads libraries
|
||||
include(FetchContent)
|
||||
|
||||
# define a function for adding git dependencies
|
||||
function(include_dependency libName gitURL gitTag)
|
||||
FetchContent_Declare(${libName}
|
||||
GIT_REPOSITORY ${gitURL}
|
||||
GIT_TAG ${gitTag}
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(${libName})
|
||||
endfunction()
|
||||
|
||||
# add SDL2 support
|
||||
find_package(SDL2 QUIET)
|
||||
if (NOT SDL2_FOUND)
|
||||
message(STATUS "Getting SDL2 from Github")
|
||||
include_dependency(SDL2 https://github.com/libsdl-org/SDL.git release-2.30.8)
|
||||
else()
|
||||
message(STATUS "Using local SDL2")
|
||||
endif()
|
||||
|
||||
# add SDL2_image support
|
||||
find_package(SDL2_image QUIET)
|
||||
if (NOT SDL2_image_FOUND)
|
||||
message(STATUS "Getting SDL2_image from Github")
|
||||
include_dependency(SDL2_image https://github.com/libsdl-org/SDL_image.git release-2.8.2)
|
||||
else()
|
||||
message(STATUS "Using local SDL2_image")
|
||||
endif()
|
||||
|
||||
## add SDL2_gfx support (NO find_package, fetch and add it manually)
|
||||
#find_package(SDL2_gfx QUIET)
|
||||
#if (NOT SDL2_gfx)
|
||||
# message(STATUS "Getting SDL2_gfx from Github")
|
||||
# include_dependency(SDL2_gfx https://github.com/giroletm/SDL2_gfx.git release-1.0.4)
|
||||
#else()
|
||||
# message(STATUS "Using local SDL2_gfx")
|
||||
#endif()
|
||||
|
||||
# SDL2_gfx (DO NOT use the function for this one)
|
||||
FetchContent_Declare(
|
||||
SDL2_gfx
|
||||
GIT_REPOSITORY https://github.com/giroletm/SDL2_gfx.git
|
||||
GIT_TAG master
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL2_gfx)
|
||||
message(STATUS "sdl2_gfx_SOURCE_DIR is: ${sdl2_gfx_SOURCE_DIR}")
|
||||
add_library(SDL2_gfx STATIC
|
||||
${sdl2_gfx_SOURCE_DIR}/SDL2_gfxPrimitives.c
|
||||
${sdl2_gfx_SOURCE_DIR}/SDL2_rotozoom.c
|
||||
)
|
||||
|
||||
target_include_directories(SDL2_gfx PUBLIC ${sdl2_gfx_SOURCE_DIR}/sdl2_gfx-src)
|
||||
target_link_libraries(SDL2_gfx PUBLIC SDL2::SDL2)
|
||||
|
||||
# add SDL2_ttf support
|
||||
#set(SDL2TTF_VENDORED ON)
|
||||
#find_package(SDL2_ttf QUIET)
|
||||
#if (NOT SDL2_ttf_FOUND)
|
||||
# message(STATUS "Getting SDL2_ttf from Github")
|
||||
# include_dependency(SDL2_ttf https://github.com/libsdl-org/SDL_ttf.git release-2.22.0)
|
||||
#else()
|
||||
# message(STATUS "Using local SDL2_ttf")
|
||||
#endif()
|
||||
|
||||
# Must set the path to the main.cpp, for example: scripts/main.cpp if it is inside a folder
|
||||
add_executable(${PROJECT_NAME} scripts/main.c
|
||||
scripts/array.c
|
||||
scripts/vector.c
|
||||
@ -14,12 +79,36 @@ add_executable(${PROJECT_NAME} scripts/main.c
|
||||
scripts/texture.c
|
||||
scripts/swap.c
|
||||
scripts/upng.c
|
||||
scripts/display.c)
|
||||
scripts/display.c
|
||||
)
|
||||
|
||||
# --- SDL2 SETUP ---
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
|
||||
set(SDL2_PATH "SDL2/x86_64-w64-mingw32")
|
||||
# Target include directories for non-gfx libs
|
||||
target_include_directories(
|
||||
${PROJECT_NAME}
|
||||
PUBLIC
|
||||
${SDL2_INCLUDE_DIRS}
|
||||
${SDL2_IMAGE_INCLUDE_DIRS}
|
||||
# ${SDL2_TTF_INCLUDE_DIRS}
|
||||
${sdl2_gfx_SOURCE_DIR} # Add SDL2_gfx headers directory
|
||||
)
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
include_directories(${SDL2_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARIES})
|
||||
# link all libraries to the project
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE
|
||||
SDL2::SDL2
|
||||
SDL2::SDL2main
|
||||
SDL2_image::SDL2_image
|
||||
# SDL2_ttf::SDL2_ttf
|
||||
SDL2_gfx # Link in the SDL2_gfx library we added
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:SDL2::SDL2>" "$<TARGET_FILE_DIR:sdl_project>"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:SDL2_image::SDL2_image>" "$<TARGET_FILE_DIR:sdl_project>"
|
||||
#COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:SDL2_ttf::SDL2_ttf>" "$<TARGET_FILE_DIR:sdl_project>"
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
Binary file not shown.
@ -2,7 +2,10 @@
|
||||
#include "display.h"
|
||||
SDL_Window* window = NULL;
|
||||
SDL_Renderer* renderer = NULL;
|
||||
|
||||
uint32_t* color_buffer = NULL;
|
||||
float* z_buffer = NULL;
|
||||
|
||||
SDL_Texture* color_buffer_texture = NULL;
|
||||
int window_width = 800;
|
||||
int window_height = 600;
|
||||
@ -14,19 +17,19 @@ bool initialize_window(void) {
|
||||
}
|
||||
|
||||
// Set width and height of the SDL window with the max screen resolution
|
||||
SDL_DisplayMode display_mode;
|
||||
/*SDL_DisplayMode display_mode;
|
||||
SDL_GetCurrentDisplayMode(0, &display_mode);
|
||||
window_width = display_mode.w;
|
||||
window_height = display_mode.h;
|
||||
|
||||
*/
|
||||
// Create a SDL Window
|
||||
window = SDL_CreateWindow(
|
||||
NULL,
|
||||
"3D Renderer",
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
window_width,
|
||||
window_height,
|
||||
SDL_WINDOW_BORDERLESS
|
||||
SDL_WINDOW_SHOWN
|
||||
);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Error creating SDL window.\n");
|
||||
@ -104,6 +107,14 @@ void clear_color_buffer(uint32_t color) {
|
||||
}
|
||||
}
|
||||
|
||||
void clear_z_buffer() {
|
||||
for (int y = 0; y < window_height; y++) {
|
||||
for (int x = 0; x < window_width; x++) {
|
||||
z_buffer[(window_width * y) + x] = 1.0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_window(void) {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
@ -25,6 +25,7 @@ enum render_method {
|
||||
extern SDL_Window* window;
|
||||
extern SDL_Renderer* renderer;
|
||||
extern uint32_t* color_buffer;
|
||||
extern float* z_buffer;
|
||||
extern SDL_Texture* color_buffer_texture;
|
||||
extern int window_width;
|
||||
extern int window_height;
|
||||
@ -36,6 +37,7 @@ void draw_line(int x0, int y0, int x1, int y1, uint32_t color);
|
||||
void draw_rect(int x, int y, int width, int height, uint32_t color);
|
||||
void render_color_buffer(void);
|
||||
void clear_color_buffer(uint32_t color);
|
||||
void clear_z_buffer();
|
||||
void destroy_window(void);
|
||||
|
||||
#endif
|
||||
|
||||
@ -33,8 +33,9 @@ void setup(void) {
|
||||
render_method = RENDER_TEXTURED_WIRE;
|
||||
cull_method = CULL_BACKFACE;
|
||||
|
||||
// Allocate the required memory in bytes to hold the color buffer
|
||||
// Allocate the required memory in bytes to hold the color buffer and z buffer
|
||||
color_buffer = (uint32_t*)malloc(sizeof(uint32_t) * window_width * window_height);
|
||||
z_buffer = (float*)malloc(sizeof(float) * window_width * window_height);
|
||||
|
||||
// Creating a SDL texture that is used to display the color buffer
|
||||
color_buffer_texture = SDL_CreateTexture(
|
||||
@ -234,19 +235,6 @@ void update(void) {
|
||||
// Save the projected triangle in the array of triangles to render
|
||||
array_push(triangles_to_render, projected_triangle);
|
||||
}
|
||||
|
||||
// Sort the triangles to render by their avg_depth
|
||||
int num_triangles = array_length(triangles_to_render);
|
||||
for (int i = 0; i < num_triangles; i++) {
|
||||
for (int j = i; j < num_triangles; j++) {
|
||||
if (triangles_to_render[i].avg_depth < triangles_to_render[j].avg_depth) {
|
||||
// Swap the triangles positions in the array
|
||||
triangle_t temp = triangles_to_render[i];
|
||||
triangles_to_render[i] = triangles_to_render[j];
|
||||
triangles_to_render[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -305,7 +293,9 @@ void render(void) {
|
||||
|
||||
render_color_buffer();
|
||||
|
||||
|
||||
clear_color_buffer(0xFF000000);
|
||||
clear_z_buffer();
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
@ -315,6 +305,7 @@ void render(void) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void free_resources(void) {
|
||||
free(color_buffer);
|
||||
free(z_buffer);
|
||||
array_free(mesh.faces);
|
||||
array_free(mesh.vertices);
|
||||
upng_free(png_texture);
|
||||
|
||||
@ -208,7 +208,19 @@ void draw_texel(
|
||||
int tex_y = abs((int)(interpolated_v * texture_height)) % texture_height;
|
||||
//tex_x = SDL_clamp(tex_x, 0, texture_width);
|
||||
//tex_y = SDL_clamp(tex_y, 0, texture_height);
|
||||
draw_pixel(x, y, texture[(texture_width * tex_y) + tex_x]);
|
||||
|
||||
int z_pos = (window_width * y) + x;
|
||||
|
||||
// Adjust 1/w so the pixels that are closer to the camera have smaller values
|
||||
interpolated_reciprocal_w = 1.0 - interpolated_reciprocal_w;
|
||||
|
||||
// only draw pixel if depth value is less than one previously stored in z-buffer
|
||||
if (interpolated_reciprocal_w < z_buffer[z_pos]) {
|
||||
draw_pixel(x, y, texture[(texture_width * tex_y) + tex_x]);
|
||||
|
||||
// update z-buffer value with the 1/w of this current pixel
|
||||
z_buffer[z_pos] = interpolated_reciprocal_w;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -326,3 +338,4 @@ void draw_textured_triangle(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user