Skip to content

Commit

Permalink
update camera system & implement swap buffer and real-time display
Browse files Browse the repository at this point in the history
Signed-off-by: ZhuohaoHe <[email protected]>
  • Loading branch information
ZzzhHe committed Sep 16, 2024
1 parent b2155a5 commit 892a97c
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 97 deletions.
39 changes: 28 additions & 11 deletions src/include/buffer.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SIMPLERENDER_SRC_INCLUDE_BUFFER_HPP_
#define SIMPLERENDER_SRC_INCLUDE_BUFFER_HPP_

#include <algorithm>
#include <memory>

#include "math.hpp"
Expand Down Expand Up @@ -35,29 +36,45 @@ class Buffer {
Buffer(size_t width, size_t height)
: width_(width),
height_(height),
size_(width * height),
framebuffer_(new uint32_t[size_](), std::default_delete<uint32_t[]>()),
matrix_(1.0f) {}
size_(width_ * height_),
framebuffer_1_(new uint32_t[size_](),
std::default_delete<uint32_t[]>()),
framebuffer_2_(new uint32_t[size_](),
std::default_delete<uint32_t[]>()) {
ClearBuffer(framebuffer_1_.get());
ClearBuffer(framebuffer_2_.get());
drawBuffer_ = framebuffer_1_.get();
displayBuffer_ = framebuffer_2_.get();
}

void ClearDrawBuffer(Color color) { ClearBuffer(drawBuffer_, color); }

uint32_t* GetFramebuffer() { return framebuffer_.get(); }
void SwapBuffer() { std::swap(drawBuffer_, displayBuffer_); }

uint32_t* GetDisplayBuffer() { return displayBuffer_; }
uint32_t* GetDrawBuffer() { return drawBuffer_; }

uint32_t& operator[](size_t index) {
if (index >= size_) {
throw std::out_of_range("Index out of range");
}
return framebuffer_.get()[index];
return drawBuffer_[index];
}

const Matrix4f& GetMatrix() const { return matrix_; }

void SetMatrix(const Matrix4f& matrix) { matrix_ = matrix; }

private:
size_t width_;
size_t height_;
size_t size_;
std::shared_ptr<uint32_t[]> framebuffer_;
Matrix4f matrix_;
std::unique_ptr<uint32_t[]> framebuffer_1_;
std::unique_ptr<uint32_t[]> framebuffer_2_;
uint32_t* drawBuffer_;
uint32_t* displayBuffer_;

void ClearBuffer(uint32_t* buffer, Color color) {
std::fill(buffer, buffer + size_, uint32_t(color));
}

void ClearBuffer(uint32_t* buffer) { std::fill(buffer, buffer + size_, 0); }
};

} // namespace simple_renderer
Expand Down
14 changes: 5 additions & 9 deletions src/include/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,14 @@ namespace simple_renderer {

class SimpleRenderer {
public:
typedef std::function<void(size_t, size_t, uint32_t, uint32_t *)>
DrawPixelFunc;

/**
* 构造函数
* @param width
* @param height
* @param buffer 要进行绘制的内存区域,大小为 width*height*sizeof(uint32_t)
* @param
*/
SimpleRenderer(size_t width, size_t height, uint32_t *buffer,
DrawPixelFunc draw_pixel_func);
SimpleRenderer(size_t width, size_t height);

/// @name 默认构造/析构函数
/// @{
Expand All @@ -57,14 +53,12 @@ class SimpleRenderer {
virtual ~SimpleRenderer() = default;
/// @}

bool render(const Model &model, const Shader &shader);
bool Render(const Model &model, const Shader &shader, uint32_t *buffer);

private:
const size_t height_;
const size_t width_;
uint32_t *buffer_;
std::shared_ptr<float[]> depth_buffer_;
DrawPixelFunc draw_pixel_func_;
LogSystem log_system_;

std::shared_ptr<Shader> shader_;
Expand All @@ -74,7 +68,9 @@ class SimpleRenderer {
* 绘制模型
* @param model 模型
*/
void DrawModel(const Model &model);
void DrawModel(const Model &model, uint32_t *buffer);

void ClearDepthBuffer();
};
} // namespace simple_renderer

Expand Down
31 changes: 20 additions & 11 deletions src/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,31 @@

namespace simple_renderer {

SimpleRenderer::SimpleRenderer(size_t width, size_t height, uint32_t *buffer,
DrawPixelFunc draw_pixel_func)
SimpleRenderer::SimpleRenderer(size_t width, size_t height)
: height_(height),
width_(width),
buffer_(buffer),
draw_pixel_func_(draw_pixel_func),
log_system_(LogSystem(kLogFilePath, kLogFileMaxSize, kLogFileMaxCount)) {
rasterizer_ = std::make_shared<Rasterizer>(width, height);
// init depth buffer
depth_buffer_ = std::shared_ptr<float[]>(new float[width * height],
std::default_delete<float[]>());
std::fill(depth_buffer_.get(), depth_buffer_.get() + width * height,
std::numeric_limits<float>::infinity());
}

bool SimpleRenderer::render(const Model &model, const Shader &shader) {
bool SimpleRenderer::Render(const Model &model, const Shader &shader,
uint32_t *buffer) {
SPDLOG_INFO("render model: {}", model.GetModelPath());
ClearDepthBuffer();
shader_ = std::make_shared<Shader>(shader);
DrawModel(model);
DrawModel(model, buffer);
return true;
}

void SimpleRenderer::DrawModel(const Model &model) {
void SimpleRenderer::ClearDepthBuffer() {
std::fill(depth_buffer_.get(), depth_buffer_.get() + width_ * height_,
std::numeric_limits<float>::infinity());
}

void SimpleRenderer::DrawModel(const Model &model, uint32_t *buffer) {
SPDLOG_INFO("draw {}", model.GetModelPath());
std::vector<Vertex> processedVertex;

Expand Down Expand Up @@ -83,19 +85,26 @@ void SimpleRenderer::DrawModel(const Model &model) {
auto v0 = processedVertex[f.GetIndex(0)];
auto v1 = processedVertex[f.GetIndex(1)];
auto v2 = processedVertex[f.GetIndex(2)];

/* * * Rasterization * * */
auto fragments = rasterizer_->Rasterize(v0, v1, v2);
// material

shader_->SetUniform("material", f.GetMaterial());

for (const auto &fragment : fragments) {
size_t x = fragment.screen_coord[0];
size_t y = fragment.screen_coord[1];

if (x >= width_ || y >= height_) {
continue;
}

if (fragment.depth < depth_buffer_[x + y * width_]) {
depth_buffer_[x + y * width_] = fragment.depth;

/* * * Fragment Shader * * */
auto color = shader_->FragmentShader(fragment);
draw_pixel_func_(x, y, color, buffer_);
buffer[x + y * width_] = static_cast<uint32_t>(color);
}
}
}
Expand Down
81 changes: 57 additions & 24 deletions test/system_test/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,66 @@

namespace simple_renderer {

/**
* camera 抽象
*/
#pragma once

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string>

class Camera {
public:
/// 光照名称
std::string name_ = "default light name";
/// 位置
Vector3f pos_;
/// 方向
Vector3f dir_;

/**
* 构造函数
* @param _name camera 名称
*/
explicit Camera(const std::string &_name);

/// @name 默认构造/析构函数
/// @{
Camera() = default;
Camera(const Camera &light) = default;
Camera(Camera &&light) = default;
auto operator=(const Camera &light) -> Camera & = default;
auto operator=(Camera &&light) -> Camera & = default;
Camera(Vector3f position)
: position_(position), front_(0.0f, 0.0f, -1.0f), up_(0.0f, 1.0f, 0.0f) {}

Camera(const Camera& camera) = default;
Camera(Camera&& camera) = default;
auto operator=(const Camera& camera) -> Camera& = default;
auto operator=(Camera&& camera) -> Camera& = default;
~Camera() = default;
/// @}

// Getters and Setters
void SetPosition(const glm::vec3& pos) { position_ = pos; }
void SetFront(const glm::vec3& frontVec) {
front_ = glm::normalize(frontVec);
}
void SetUp(const glm::vec3& upVec) { up_ = glm::normalize(upVec); }

glm::vec3 GetPosition() const { return position_; }
glm::vec3 GetFront() const { return front_; }
glm::vec3 GetUp() const { return up_; }

// Methods to get view and projection matrices
glm::mat4 GetViewMatrix() const {
return glm::lookAt(position_, position_ + front_, up_);
}

glm::mat4 GetProjectionMatrix(float fov, float aspectRatio, float nearPlane,
float farPlane) const {
return glm::perspective(glm::radians(fov), aspectRatio, nearPlane,
farPlane);
}

// Additional methods for camera movement (optional)
void MoveForward(float distance) { position_ += front_ * distance; }

void MoveRight(float distance) {
position_ += glm::normalize(glm::cross(front_, up_)) * distance;
}

void MoveUp(float distance) { position_ += up_ * distance; }

void Rotate(float yaw, float pitch) {
glm::vec3 newFront;
newFront.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
newFront.y = sin(glm::radians(pitch));
newFront.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
front_ = glm::normalize(newFront);
}

private:
Vector3f position_;
Vector3f front_;
Vector3f up_;
};

} // namespace simple_renderer
Expand Down
15 changes: 8 additions & 7 deletions test/system_test/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,38 +92,39 @@ void Display::loopBegin() { is_exit_ = false; }

bool Display::loopShouldClose() { return is_exit_; }

void Display::handleKeyboardEvent(SDL_Event& event) {
void Display::handleKeyboardEvent(SDL_Event& event,
simple_renderer::Camera& camera) {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_q:
is_exit_ = true;
break;
case SDLK_UP:
std::cout << "UP" << std::endl;
camera.MoveUp(1.0f);
break;
case SDLK_DOWN:
std::cout << "DOWN" << std::endl;
camera.MoveUp(-1.0f);
break;
case SDLK_LEFT:
std::cout << "LEFT" << std::endl;
camera.MoveRight(-1.0f);
break;
case SDLK_RIGHT:
std::cout << "RIGHT" << std::endl;
camera.MoveRight(1.0f);
break;
default:
break;
}
}

void Display::handleEvents() {
void Display::handleEvents(simple_renderer::Camera& camera) {
SDL_Event event = SDL_Event();
while (SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_QUIT:
is_exit_ = true;
break;
case SDL_KEYDOWN:
handleKeyboardEvent(event);
handleKeyboardEvent(event, camera);
break;
}
}
Expand Down
10 changes: 3 additions & 7 deletions test/system_test/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <span>

#include "buffer.hpp"
#include "camera.h"

/**
* 显示抽象
Expand Down Expand Up @@ -57,17 +58,12 @@ class Display {
*/
void fill(const uint32_t *buffer);

/**
* 运行
*/
void run();

/**
* 显示循环
*/
void loopBegin();
void handleKeyboardEvent(SDL_Event &event);
void handleEvents();
void handleKeyboardEvent(SDL_Event &event, simple_renderer::Camera &camera);
void handleEvents(simple_renderer::Camera &camera);
bool loopShouldClose();

private:
Expand Down
Loading

0 comments on commit 892a97c

Please sign in to comment.