Permalink
Browse files

save the framebuffer to a file

  • Loading branch information...
ssloy committed Feb 9, 2019
1 parent 793a46d commit 90b7cfb0f2e715219f81836b8b3130a5f54c3ef2
Showing with 103 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +12 −0 .gitpod.yml
  3. +32 −0 CMakeLists.txt
  4. +6 −0 Dockerfile
  5. BIN doc/001.png
  6. +50 −0 tinyraycaster.cpp
@@ -0,0 +1,3 @@
# Ignore content built with CMake
build/

@@ -0,0 +1,12 @@
image:
file: Dockerfile
tasks:
- command: >
mkdir --parents build &&
cd build &&
cmake .. &&
make &&
./tinyraycaster &&
pnmtopng out.ppm > out.png &&
open out.png &&
cd ..
@@ -0,0 +1,32 @@
cmake_minimum_required (VERSION 2.8)
project (tinyraycaster)

set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

include(CheckCXXCompilerFlag)
function(enable_cxx_compiler_flag_if_supported flag)
string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_already_set)
if(flag_already_set EQUAL -1)
check_cxx_compiler_flag("${flag}" flag_supported)
if(flag_supported)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
endif()
unset(flag_supported CACHE)
endif()
endfunction()

enable_cxx_compiler_flag_if_supported("-Wall")
enable_cxx_compiler_flag_if_supported("-Wextra")
enable_cxx_compiler_flag_if_supported("-pedantic")
enable_cxx_compiler_flag_if_supported("-std=c++11")
enable_cxx_compiler_flag_if_supported("-O3")

file(GLOB SOURCES
"${SRC_DIR}/*.h"
"${SRC_DIR}/*.cpp"
)

add_executable(${PROJECT_NAME} ${SOURCES})
target_include_directories(${PROJECT_NAME} PRIVATE "${SRC_DIR}")


@@ -0,0 +1,6 @@
FROM gitpod/workspace-full

USER root
# add your tools here
RUN apt-get update && apt-get install -y \
netpbm
BIN +2.08 KB doc/001.png
Binary file not shown.
@@ -0,0 +1,50 @@
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <cassert>

uint32_t pack_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a=255) {
return (a<<24) + (b<<16) + (g<<8) + r;
}

void unpack_color(const uint32_t &color, uint8_t &r, uint8_t &g, uint8_t &b, uint8_t &a) {
r = (color >> 0) & 255;
g = (color >> 8) & 255;
b = (color >> 16) & 255;
a = (color >> 24) & 255;
}

void drop_ppm_image(const std::string filename, const std::vector<uint32_t> &image, const size_t w, const size_t h) {
assert(image.size() == w*h);
std::ofstream ofs(filename);
ofs << "P6\n" << w << " " << h << "\n255\n";
for (size_t i = 0; i < h*w; ++i) {
uint8_t r, g, b, a;
unpack_color(image[i], r, g, b, a);
ofs << static_cast<char>(r) << static_cast<char>(g) << static_cast<char>(b);
}
ofs.close();
}

int main() {
const size_t win_w = 512; // image width
const size_t win_h = 512; // image height
std::vector<uint32_t> framebuffer(win_w*win_h, 255); // the image itself, initialized to white

for (size_t j = 0; j<win_h; j++) { // fill the screen with color gradients
for (size_t i = 0; i<win_w; i++) {
uint8_t r = 255*j/float(win_h); // varies between 0 and 255 as j sweeps the vertical
uint8_t g = 255*i/float(win_w); // varies between 0 and 255 as i sweeps the horizontal
uint8_t b = 0;
framebuffer[i+j*win_w] = pack_color(r, g, b);
}
}

drop_ppm_image("./out.ppm", framebuffer, win_w, win_h);

return 0;
}

3 comments on commit 90b7cfb

@SpaceDandy406

This comment has been minimized.

Copy link

SpaceDandy406 replied Feb 15, 2019

Здравствуйте. Читал вашу статью на хабре, решил пофаниться, и встрял на кое чём.
В tinyraycaster.cpp на 22 строке открывается стрим, без std::ios_base::binary флага. Из-за этого у меня вместо градиента вот такая вот штука получилась. Как так получилось? 😃

image

@SpaceDandy406

This comment has been minimized.

Copy link

SpaceDandy406 replied Feb 16, 2019

Увидел, что в мастере уже исправлена эта ошибка. А как тогда у вас работало, непонятно)

@ssloy

This comment has been minimized.

Copy link
Owner Author

ssloy replied Feb 16, 2019

Windows при открытии файла в текстовом режиме при записи одного символа '\n' пишет сразу пару символов '\r' и '\n', постепенно сдвигая каналы. Так что да, нужно писать в бинарном режиме. А для линукса и макоси такой проблемы нет, можете посмотреть на гитподе. Я просто не проверял под виндой.

Please sign in to comment.