opencv 软光栅 初步
1 Rasterizer.hpp
#pragma once #include"Triangle.hpp" #include<algorithm> #include<iostream> #include<Eigen/Eigen> enum class BufferType{ Color = 1, Depth = 2 }; inline BufferType operator | (BufferType a,BufferType b){ return BufferType(int(a) | int(b)); } inline BufferType operator & (BufferType a,BufferType b){ return BufferType(int(a) & int(b)); } class Rasterizer{ public: Rasterizer(int w,int h); void setPixel(const Eigen::Vector3f& pt,const Eigen::Vector3f& color); void clear(BufferType buffType); std::vector<Eigen::Vector3f>& getFrameBuffer(){ return frameBuffer; } int getBufferIndex(int x,int y); private: std::vector<Eigen::Vector3f> frameBuffer; std::vector<float> depthBuffer; int width; int height; };
2 Rasterizer.cpp
#include"Rasterizer.hpp" #include<opencv2/opencv.hpp> #include<math.h> #include<stdexcept> Rasterizer::Rasterizer(int w,int h){ width = w; height = h; frameBuffer.resize(w * h); depthBuffer.resize(w * h); } int Rasterizer::getBufferIndex(int x,int y){ return x * width + y; } void Rasterizer::setPixel(const Eigen::Vector3f& pt,const Eigen::Vector3f& color){ if(pt.x() < 0 || pt.y() >= width || pt.y() < 0 || pt.y() >= width){ return; } int idx = getBufferIndex(pt.x(),pt.y()); if((size_t)idx >= frameBuffer.size()){ return; } frameBuffer[idx] = color; } void Rasterizer::clear(BufferType buffType){ if((buffType & BufferType::Color) == BufferType::Color){ std::fill(frameBuffer.begin(),frameBuffer.end(),Eigen::Vector3f(0.0f,0.0f,0.0f)); } if((buffType & BufferType::Depth) == BufferType::Depth){ std::fill(depthBuffer.begin(),depthBuffer.end(),std::numeric_limits<float>::infinity()); } }
3. main.cpp
#include <opencv2/opencv.hpp> #include <opencv2/highgui.hpp> #include <iostream> #include"Rasterizer.hpp" using namespace cv; const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 600; int main() { int key = 0; int frameCount = 0; Rasterizer rasterizer(SCREEN_WIDTH,SCREEN_HEIGHT); rasterizer.clear(BufferType::Color | BufferType::Depth); Eigen::Vector3f red(0.0f,0.0f,1.0f); for(int i = 10;i <= 30;i++){ for(int j = 20;j <= 40;j++){ rasterizer.setPixel(Eigen::Vector3f(i,j,0),red); } } cv::Mat image(SCREEN_HEIGHT,SCREEN_WIDTH,CV_32FC3,rasterizer.getFrameBuffer().data()); cv::imshow("image",image); key = cv::waitKey(); return 0; }
效果:
坐标系
所以帧缓存中获取索引是这样
int Rasterizer::getBufferIndex(int x,int y){ return x * width + y; }