======================Barycentric interpolation======================================

<1>2d/3d Check point in triangle test

float areas(vector p1;vector p2;vector p3)
{
return length(cross(p1-p2,p3-p2)) * 0.5f;
} int ptInTri(vector inpt;vector p1;vector p2; vector p3)
{
float s = areas(p1,p2,p3);
float s1 = areas(inpt,p2,p3) / s;
float s2 = areas(inpt,p3,p1) / s;
float s3 = areas(inpt,p1,p2) / s;
if(s1<0.0f || s1>1.0f)
{
return false;
}
if(s2 < 0.0f || s2 >)
{
return false;
}
if(s3 < 0.0f || s3 >)
{
return false;
}
float all = s1 + s2 + s3;
if (all-1.0f<0.000001f)
return true;
else
return false;
}

<2>2d check can use :

<test 3d in houdini found problem>

int ptInTri2(vector P;vector A;vector B; vector C)
{
vector u = B - A;
vector v = C - A;
vector w = P - A; vector vCrossW = cross(v, w);
vector vCrossU = cross(v, u); if (dot(vCrossW, vCrossU) < )
return false; vector uCrossW = cross(u, w);
vector uCrossV = cross(u, v); // Test sign of t
if (dot(uCrossW, uCrossV) < )
return false; float denom = length(uCrossV);
float r = length(vCrossW) / denom;
float t = length(uCrossW) / denom; return (r + t <= );
}

<3> Color Interpolation:

float areas(vector p1;vector p2;vector p3)
{
return length(cross(p1-p2,p3-p2)) * 0.5f;
} vector P = getInputP();
float s = areas(p1,p2,p3);
float s1 = areas(P,p2,p3) / s;
float s2 = areas(P,p3,p1) / s;
float s3 = areas(P,p1,p2) / s; vector PColor = p1.color * s1 + p2.color*s2 + p3.color*s3;

<4>we can use this method to getPointAt uv like maya function or houdini primuv();

float areas(vector p1;vector p2;vector p3)
{
return length(cross(p1-p2,p3-p2)) * 0.5f;
} vector getPointAtUV(float u;float v)
{
clamp(u,,);
clamp(v,,); // get current gdp's points
vector gdpPtsPos[];
for(int i=;i<;i++)
{
vector curl = point(,"P",i);
//printf("%f ,%f , %f \n",curl[0],curl[1],curl[2]);
append(gdpPtsPos,curl);
} vector p1 = gdpPtsPos[];
vector p2 = gdpPtsPos[];
vector p3 = gdpPtsPos[]; // tri area
float s = areas(p1,p2,p3);
// reverse to get base on u value float uArea = u * 0.5 / s; // reverse to get base on v value
float vArea = v * 0.5 / s ; // the w value
float wArea =;
if( - uArea - vArea < )
{
wArea = ;
}
else
{
wArea =( - u - v )*0.5 / s;
} //https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates //P=uA+vB+wC. vector retP = p1 * uArea + p2*vArea + p3*wArea;
return retP; } #define maxscatter 100000 for(int i=;i<maxscatter;i++)
{
float u = rand(i);
float v = rand(i*);
vector retPos = getPointAtUV(u,v);
addpoint(geoself(),retPos);
}

<4>Color Define:

(1)ARGB:uint32_t,也就是单位为uint8_t ,共4个,a ,r ,g ,b    0xFF FF FF FF (255,255,255,255)

//  uint32_t c;

A:(uint8_t)   ( (c & 0xFF   ) >>)
R:(uint8_t) ( (c & 0x00 FF ) >>)
G:(uint8_t) ( (c & 0x00 FF ) >>)
B:(uint8_t) ( (c & 0x00 FF) >>)

(2)从uint8_t r,g,b,a转换到uint32_t,用位和求回去

((uint32_t)a<<) | ((uint32_t)r<<) | ((uint32_t)g<<) | ((uint32_t)b<<)

(2)float color:sixteen bytes:

struct color{float a, float r,float g,float b}

转换成ARGB(uint32_t)颜色也简单.

color fc = {1.0f,0.5f,0.0f,1.0f};
uint8_t r = (uint8_t) (floorf(fc.r*255.0f))
uint8_t g = (uint8_t) (floorf(fc.g*255.0f))
uint8_t b = (uint8_t) (floorf(fc.b*255.0f))
uint8_t a = (uint8_t) (floorf(fc.a*255.0f))

=========================Rasterization==================================================

<1>Line:

画斜线没用到斜率方程,直接用的线性差值。

DrawApi.h

#ifndef DRAWAPI_H
#define DRAWAPI_H #include <QImage>
#include "LineSegment.h"
#include <glm/glm.hpp>
#include <iostream>
#include "MathUtility.h"
using namespace TopVertex;
class DrawApi
{
public:
template <typename T = glm::vec3>
static void drawLine(QImage &image ,LineSegment<T> &line,const glm::vec3 &color)
{ auto &sp = line.startPoint();
auto &ep = line.endPoint();
float m = line.getSlope(); if(line.getType() == LineSegment<T>::HORIZON)
{
std::cout << "write horizon line\n";
auto y = sp[];
for(int x=sp[] ; x <= ep[]; x++)
{
image.setPixel(x,y,qRgb(color[],color[],color[]));
}
return;
}
if(line.getType() == LineSegment<T>::VERTICAL)
{
std::cout << "write verticle line\n";
auto x = sp[];
auto y0 = sp[];
auto y1 = ep[];
if(y0 < y1)
{
for(int y=y0;y<=y1;y++)
{
image.setPixel(x,y,qRgb(color[],color[],color[]));
}
}
else
{
for(int y=y1;y<=y0;y++)
{
image.setPixel(x,y,qRgb(color[],color[],color[]));
}
}
return;
}
if(line.getType() == LineSegment<T>::NORMAL)
{
std::cout << "write normal line\n";
int startRow = ;
int endRow = ; if(sp[] < ep[])
{
startRow = sp[];
endRow = ep[];
}
else
{
startRow = ep[];
endRow = sp[];
}
for(int r = startRow;r<=endRow;r++)
{
auto bias = GLY_MATH::fit<float>(r,startRow,endRow,0.1f,1.0f);
auto pos = GLY_MATH::linearInterpolation(sp,ep,bias);
image.setPixel(pos[],pos[],qRgb(color[],color[],color[]));
}
return;
} }
}; #endif // DRAWAPI_H

LineSegment.h

#ifndef LINESEGMENT_H
#define LINESEGMENT_H
#include <algorithm>
#include <cmath>
#include <string>
#include <iostream>
#include <glm/glm.hpp>
template <typename T>
class LineSegment
{
public:
typedef T value_type;
enum TYPE{VERTICAL,HORIZON,NORMAL};
LineSegment(T startPoint,T endPoint):
mStartPoint(startPoint),mEndPoint(endPoint)
{
// LINE PROPERTY
evalLineProperty();
// LINE PROPERTY
}
LineSegment()=default;
void setPoints(const T &startPoint , const T &endPoint)
{
mStartPoint = startPoint;
mEndPoint = endPoint;
evalLineProperty();
}
inline T & operator[](int i)
{
if(i == )
{
return mStartPoint;
}
else if(i == )
{
return mEndPoint;
}
else
{
throw std::string("Can't get point over 2\n").c_str();
} }
TYPE getType();
T &startPoint();
T &endPoint();
T startPoint()const;
T endPoint()const;
float getSlope()const; template <typename T2,typename T3>
inline T2 intersect(const LineSegment<T3> &Line)
{
auto st_y = Line.startPoint()[]; // get line y value
auto it_x = (st_y - startPoint()[] + startPoint()[]*getSlope())/getSlope(); // y slope function get x pos
return T2(it_x,st_y);
} private:
void evalLineProperty()
{ auto x0 = mStartPoint[];
auto x1 = mEndPoint[]; if(x0 > x1)
{
swap(mStartPoint,mEndPoint);
} x0 = mStartPoint[];
x1 = mEndPoint[];
auto y0 = mStartPoint[];
auto y1 = mEndPoint[]; if(fabs(y1-y0) <= 0.0000001f) // horizon line slope = 0
{
mSlope = 0.0f;
mLineType = HORIZON;
}
else if(fabs(x1-x0) <= 0.000001f) // verticle line slope = 0
{
mSlope = 0.0f;
mLineType = VERTICAL;
}
else // slope !=0
{
mSlope = (y1 - y0) / (x1-x0);
mLineType = NORMAL;
}
} T mStartPoint;
T mEndPoint;
TYPE mLineType;
float mSlope;
}; template<typename T>
typename LineSegment<T>::TYPE LineSegment<T>::getType()
{
return mLineType;
} template<typename T>
float LineSegment<T>::getSlope() const
{
return mSlope;
} template<typename T>
T &LineSegment<T>::startPoint()
{
return mStartPoint;
} template<typename T>
T &LineSegment<T>::endPoint()
{
return mEndPoint;
} template<typename T>
T LineSegment<T>::startPoint()const
{
return mStartPoint;
} template<typename T>
T LineSegment<T>::endPoint()const
{
return mEndPoint;
} // ostream
inline std::ostream& operator<<(std::ostream &os,LineSegment<glm::vec3> line)
{
os << "Line start points:" << line.startPoint()[] << " " <<line.startPoint()[] << " "<<line.startPoint()[]
<< " | "
<< "end:" << line.endPoint()[]<< " "<< line.endPoint()[] << " "<< line.endPoint()[] ;
return os;
} inline std::ostream& operator<<(std::ostream &os,LineSegment<glm::vec2> line)
{
os << "Line start points:" << line.startPoint()[] << " " <<line.startPoint()[] << "|"
<< "end:" << line.endPoint()[]<< " "<< line.endPoint()[] ;
return os;
} #endif // LINESEGMENT_H

MathUtility.h

#ifndef MATHUTILITY_H
#define MATHUTILITY_H #include <string>
#include <vector>
#include <iostream>
#include <sstream>
using namespace std; namespace TopVertex
{
class GLY_MATH
{
public: template<typename T>
static T linearInterpolation(T val1 , T val2,float bias)
{
return val1*(-bias) + val2*bias;
} template<typename T>
static T min(T a, T b) {
if (a > b) {
return b;
} else {
return a;
}
} template<typename T>
static T max(T a, T b) {
if (a > b) {
return a;
} else {
return b;
}
} template<typename T>
static bool zero_compare(T a, double tol = 0.00001) {
return a >= -tol && a <= tol;
} // DO NOT USE THIS FIT TO FIT VECTOR VALUE
template<typename T>
static T fit(T var, T omin, T omax, T nmin, T nmax) {
T d = omax - omin;
if (zero_compare(d)) {
return (nmin + nmax) * 0.5;
}
if (omin < omax) {
if (var < omin) return nmin;
if (var > omax) return nmax;
} else {
if (var < omax) return nmax;
if (var > omin) return nmin;
}
return nmin + (nmax - nmin) * (var - omin) / d;
} //return -1 to 1
template<typename T>
static T fit_negate(T var, T omin, T omax) {
return fit(var, omin, omax, -1.0, 1.0);
} //string split
static std::vector<std::string> split_string(std::string &inputString, char &split_char) {
std::stringstream ss(inputString);
std::string sub_str;
std::vector<std::string> sp_strPath;
sp_strPath.clear();
while (getline(ss, sub_str, split_char)) {
sp_strPath.push_back(sub_str);
}
return sp_strPath;
} //value to string
template<typename T>
// T must be a value int/float/double
static std::string value_to_str(T &value) {
std::ostringstream os;
os << value;
return os.str();
} static int wang_inthash(int key) {
// From http://www.concentric.net/~Ttwang/tech/inthash.htm
key += ~(key << );
key ^= (key >> );
key += (key << );
key ^= (key >> );
key += ~(key << );
key ^= (key >> );
return key;
} static int fastRandomInt(int seed) {
int nseed = seed * +0XFFFFFFF;
return wang_inthash(nseed);
} static float fastRandom01(int seed)
{
return float(fastRandomInt(seed) % ) / 1000000.0f;
} };
} #endif // MATHUTILITY_H

Renderer.h

#ifndef RENDERER_H
#define RENDERER_H #include <QImage>
#include <iostream>
#include <glm/glm.hpp> using namespace std; class Renderer
{
public:
Renderer();
void render();
}; #endif // RENDERER_H

Renderer.cpp

#include "Renderer.h"
#include "DrawApi.h" Renderer::Renderer()
{ } void Renderer::render()
{ QImage image(,,QImage::Format_RGB32);
image.fill(Qt::gray);
glm::vec3 p0(,,);
glm::vec3 p1(,,);
glm::vec3 p2(,,); // write horizon line
glm::vec3 p3(,,);
glm::vec3 p4(,,);
auto hline1 = LineSegment<glm::vec3>(p3,p4);
DrawApi::drawLine(image,hline1,glm::vec3(,,)); // write verticle line
glm::vec3 p5(,,);
glm::vec3 p6(,,);
auto hline2 = LineSegment<glm::vec3>(p5,p6);
DrawApi::drawLine(image,hline2,glm::vec3(,,)); // write normal line
glm::vec3 p7(,,);
glm::vec3 p8(,,);
auto hline3 = LineSegment<glm::vec3>(p8,p7);
DrawApi::drawLine(image,hline3,glm::vec3(,,)); image.save("c:/Raster.jpg",,);
return ;
}

main.cpp

auto render =  Renderer();
render.render();

以上的方法不过还是垃圾,因为还是循环像素row。对于以上的方法如果不考虑计算成本,直接暴力法循环row,

然后判断pixelPos是不是在triangle里面。是就给他画出来。

最好的方法:

线求交:

2,矩阵大法:

计算 :

rotate:

Scale:

translate:

得到的XF = 1*x + 0*y + 1*tx = x + tx;

得到的YF = 0*x + 1*y + 1*ty = y + ty;

总体带x,y,w

3d:

Orthographic Matrix:

Perspective Matrix

Viewport Transform:

Raster Pipeline:

..

Rasterization 学习笔记的更多相关文章

  1. DirectX 总结和DirectX 9.0 学习笔记

    转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...

  2. DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  3. DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  4. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  5. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  6. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  7. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  8. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  9. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

随机推荐

  1. Shell 同步时间脚本

    Linux系统同步时间脚本 Linux操作系统,如果时间和网络时间差距太大的话.可能会导致程序,进程启动不了.所以linux系统时间同步显得尤为重要,本文在借鉴网上众多资料后,以centos_6.X系 ...

  2. 【C#】使用bat文件安装卸载Window服务

    1.安装服务 @echo off @title 安装windows服务path %SystemRoot%\Microsoft.NET\Framework\v4.0.30319echo========= ...

  3. Hadoop记录-yarn ResourceManager Active频繁易主问题排查(转载)

    一.故障现象 两个节点的ResourceManger频繁在active和standby角色中切换.不断有active易主的告警发出 许多任务的状态没能成功更新,导致一些任务状态卡在NEW_SAVING ...

  4. SpringBoot+Thyemleaf

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过 ...

  5. js验证登录注册

    js验证登录注册的优势,在前台直接验证,不需要在后台读取返回数据验证,减轻服务器压力. 登陆验证得必要性,拦截恶意脚本的登录注册攻击.哈哈,当然有些高手是可以直接跳过js验证的. 所以还是后台验证,并 ...

  6. windows cmd命令 批处理bat 导增量jar包【原】

    下载地址 https://pan.baidu.com/s/1cIyCbG 导jar包 @echo off setlocal enabledelayedexpansion echo ---------- ...

  7. 【2】【leetcode-105,106】 从前序与中序遍历序列构造二叉树,从中序与后序遍历序列构造二叉树

    105. 从前序与中序遍历序列构造二叉树 (没思路,典型记住思路好做) 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [ ...

  8. Hibernate的注解和检索

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自 ...

  9. 账号管理文件/etc/passwd和/etc/shadow

    /etc/passwd和/etc/shadow是Linux中两个账号管理的重要文件 一./etc/passwd        这个文件中每一行代表一个账号,有几行就代表系统中存在几个账号.有些账号是系 ...

  10. Docker摘要

    Docker https://www.docker.com/ 消除应用的依赖矩阵. 消除硬件依赖 和 软件依赖. Escape the app dependency matrix Eliminate ...