图形学笔记(一)——图形显示原理

CRT(阴极射线管):

  • 余辉时间:从屏幕发光到衰减为其光亮度十分之一的时间。
    • 通常采用余辉时间为10到60μS的材料构成。
  • 电子束轰击荧光屏产生亮点(发光点:像素)强度满足高斯分布。两相邻亮点的间隔长度应保证大于具有亮点中心强度约60%处的亮点直径。
  • 显示分辨率
    • 在水平和垂直方向单位长度上可绘制的点数(水平分辨率和垂直分辨率)。
    • 当两个荧光发光点间隔大于亮度衰减到最大值60%时的光点直径(两亮点是可区分的)时,荧光屏在水平和垂直方向单位长度上所分布的最大光点数
  • CRT的物理尺寸是由屏幕对角线的长度给定的。

颜色模型:

  • 互补色:混合成白色光的两种彩色光源称为互补色。
  • 人眼对颜色的三种特征作出反应:色度/相(chromaticity)或色度(Hue),光纯度/彩度(purity)或饱和度(saturation),明度/亮度(brightness)。
CIE-XYZ加色模型:
  • 舌头状曲线:边界和内部表示所有可见光色度值
  • 边界上的点:对应于色纯度为100%的纯彩色
  • 内部点:表示所有可能的可见颜色的组合
  • C点:对应于照明体白色位置,色度坐标近似 (1/3,1/3,1/3);是平均日光(白色)的近似标准。
  • 紫红线:连接红色和紫色点的直线,不属于光谱
  • 在舌头状曲线上不可能有一个三角形能包含所有颜色。没有一个三基色组可通过加色混合生成所有颜色。
  • 互补色:色度图上为位于C的两侧且通过C的直线上两个点C3、C4
  • 主波长:C与C1连线与光谱曲线相交于Cs,颜色C1可表示成光C与光谱颜色Cs的混合,C1的主波长就是Cs。
    • 若Cs落在紫红线上则C1为非光谱颜色,主波长为Cs的补点
  • 颜色纯度:“C到C1的距离”与“C到Cs的距离”的比率dc1/dcs
  • RGB典型的加色模型
    • 黑(0,0,0),白(1,1,1),品红(1,0,1),黄(1,1,0),青(0,1,1)
    • 明暗度由原点到白色顶点的主对角线表示
CIE-Lab减色模型
  • 人的肉眼能感知的色彩都能通过Lab模型表现。
  • L为亮度,a成分(红色到绿色的变化),b成分(黄色到蓝色的变化)
  • a和b的值域都是由+120至-120
CMY减色模型
  • CMY使用青©、品红(M)、黄(Y)作为三基色
  • 与RGB相反,(1,1,1)为白色,(0,0,0)为黑色,(C,M,K)=(1,1,1)-(R,G,B)
  • 对于CMYK,Y=max1-max(R,G,B),(R,G,B)=(1-(C,M,Y))(1-K)
  • 在实际应用中CMY混合为土棕色,因此加入黑色油墨(K)构成CMYK模型。
HSV模型
  • 色彩(H);饱和度(S);明度值(V)
  • 向原色中加白色减小S,加黑色减小V,(V,S)=(1,1)为纯色,(V,S)=(1,0)为白色
HLS模型
  • 色彩(H),亮度(L)和色饱和度(S)

扫描原理

光栅扫描
  • 从左至右(扫描线),从上至下
  • 水平回归(返回到屏幕的左边),垂直回归(返回到屏幕左上角)
  • 隔行扫描(消除闪烁):奇场扫描+偶场扫描
  • 对所有存储器存储单元I,执行:read(I,x,y,z);write(x,y,z)。每执行一次循环称为屏幕刷新,显示一帧执行N对指令。
    全彩色系统(真彩色系统): 0~255的RGB系统(24位)
  • 帧缓冲器分页:帧缓冲器容量远大于屏幕像素图,通过控制器实现不同画面的切换。
    • 组合像素结构:每个像素的所有位均集中存储在单个存储器中
    • 位平面结构(降低帧缓冲器工作速度要求):使用多个存储体,像素每一位各自存放在不同的存储体。
      • 帧缓冲器(颜色)深度:位平面的数目
  • 彩色查找表技术(调色板):对不同颜色索引,画面上能同时出现颜色的种类仍然是由帧缓冲器单元位长决定,每一种独立颜色成分可定义为更高的精度,颜色可以变化得更细致。
随机扫描显示

一般具有比光栅系统更高的分辨率,能生成光滑线条

  • 1.系统周期地按显示列表中的一组画线命令依次画出其组成线条
  • 2.所有画线命令处理完后,周期地返回到列表的第一条画线命令
  • 3.当显示的线条很少时,则需延迟每个刷新周期,避免刷新速率超过每秒60帧,烧坏荧光层。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程解决的问题: 作为游戏行业或者图形从业者,你是否面临以下问题: 到底openGL底层如何实现的? 到底矩阵操作变换是怎么做到的? 到底光栅化的算法以及原理是什么? 到底如何才能从3D世界投射到2D屏幕呢? 图形有这么多的矩阵操作,到底如何推导如何应用呢? 完这门课程,你应该就可以从底层了解一个初级的openGL图形接口如何实现,图形最底层的封装到底面临哪些挑战;跟随我们一行一行写完代码,你就会得到一个迷你版本的openGL图形库,你可以深度体会图形从模型变换,观察矩阵变换,投影矩阵变换一直到光栅化纹理操作的全套模拟流程。 课程介绍: 本课程将带领员不使用任何图形库,实现从0到1的图形接口封装以及算法讲解,并且带领大家手敲代码,一行一行进行实现。 涵盖了(环境搭建,绘制点,Bresenham算法绘制完美直线,三角形拆分绘制算法,颜色插值算法,图片操作,图片二次插值放缩算法,纹理系统接口搭建及封装,矩阵操作理论以及实践,openGL类似接口封装,3D世界的图形理论及接口封装等) 最终将带领大家通过C++实现一个3D世界的图形接口,方便所有人入门图形,进行接下来的openGL接口以及GPU编程的习   本课程为系列课程的第一步入门,且带领所有人进行实现,更加实用,可以让大家打牢图形的基础知识及编程技能
用MFC VC++实现的时钟源代码 // MFCFrame1View.cpp : implementation of the CMFCFrame1View class // #include "stdafx.h" #include "MFCFrame1.h" #include "MFCFrame1Doc.h" #include "MFCFrame1View.h" #include "PointDialog.h" #include "math.h" GLUquadricObj *objCylinder = gluNewQuadric(); #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View IMPLEMENT_DYNCREATE(CMFCFrame1View, CView) BEGIN_MESSAGE_MAP(CMFCFrame1View, CView) //{{AFX_MSG_MAP(CMFCFrame1View) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SIZE() ON_COMMAND(IDM_ZIXUAN, OnZixuan) ON_WM_TIMER() ON_COMMAND(IDM_ChangDirect, OnChangDirect) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View construction/destruction CMFCFrame1View::CMFCFrame1View() { // TODO: add construction code here this->m_GLPixelIndex = 0; this->m_hGLContext = NULL; Angle1=0.0; Angle2=30.0; Timer=0; x=0.0; z=0.0; juli=40.0; } CMFCFrame1View::~CMFCFrame1View() { } BOOL CMFCFrame1View::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View drawing ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View printing BOOL CMFCFrame1View::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CMFCFrame1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CMFCFrame1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View diagnostics #ifdef _DEBUG void CMFCFrame1View::AssertValid() const { CView::AssertValid(); } void CMFCFrame1View::Dump(CDumpContext& dc) const { CView::Dump(dc); } CMFCFrame1Doc* CMFCFrame1View::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCFrame1Doc))); return (CMFCFrame1Doc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View message handlers BOOL CMFCFrame1View::SetWindowPixelFormat(HDC hDC) { PIXELFORMATDESCRIPTOR pixelDesc= { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI, PFD_TYPE_RGBA, 24, 0,0,0,0,0,0, 0, 0, 0, 0,0,0,0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0,0,0 }; this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc); if(this->m_GLPixelIndex==0) { this->m_GLPixelIndex = 1; if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0) { return FALSE; } } if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE) { return FALSE; } return TRUE; } int CMFCFrame1View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here HWND hWnd = this->GetSafeHwnd(); HDC hDC = ::GetDC(hWnd); if(this->SetWindowPixelFormat(hDC)==FALSE) { return 0; } if(this->CreateViewGLContext(hDC)==FALSE) { return 0; } return 0; } BOOL CMFCFrame1View::CreateViewGLContext(HDC hDC) { this->m_hGLContext = wglCreateContext(hDC); if(this->m_hGLContext==NULL) {//创建失败 return FALSE; } if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE) {//选为当前RC失败 return FALSE; } return TRUE; } void CMFCFrame1View::OnDestroy() { CView::OnDestroy(); // TODO: Add your message handler code here if(wglGetCurrentContext()!=NULL) { wglMakeCurrent(NULL,NULL); } if(this->m_hGLContext!=NULL) { wglDeleteContext(this->m_hGLContext); this->m_hGLContext = NULL; } } void CMFCFrame1View::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here GLsizei width,height; GLdouble aspect; width = cx; height = cy; if(cy==0) { aspect = (GLdouble)width; } else { aspect = (GLdouble)width/(GLdouble)height; } glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0,aspect,5.0,1000.0); } void CMFCFrame1View::OnDraw(CDC* pDC) { CMFCFrame1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CPaintDC dc(this); glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0,0.0,10.0,0.0,0.0,0.0,0.0,1.0,0.0); glRotatef(-90.0,1.0,0.0,0.0);/*返回原坐标*/ glTranslatef(-3.0,0.0,0.0); SwapBuffers(dc.m_ps.hdc); glDrawBuffer (GL_BACK); glFlush(); } void CMFCFrame1View::OnZixuan() { // TODO: Add your command handler code here Timer=1; SetTimer(1,100,NULL); } void CMFCFrame1View::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default CPaintDC dc(this); if (Timer==1) { Angle1=Angle1-1; Angle2=Angle2-1; glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW);/**/ glLoadIdentity(); gluLookAt(0.0,20.0,0.000000001,0.0,0.0,0.0,0.0,1.0,0.0); glPushMatrix(); glColor3f(0.7,0.7,0.7); glTranslatef(0.0,0.0,1.1); glRotatef(-90.0,1.0,0.0,0.0); glutSolidCone(5.0,0.0,60.0,60.0); /*底盘*/ glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(3.9,0.99,1.0); /*刻度*/ glRotatef(90.0,0.0,1.0,0.0); gluCylinder(objCylinder, 0.05, 0.05, 0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(-4.7,0.99,1.0); /*刻度*/ glRotatef(90.0,0.0,1.0,0.0); gluCylinder(objCylinder,0.05, 0.05, 0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(0.0,0.99,-2.9); /*刻度*/ glRotatef(180.0,0.0,1.0,0.0); gluCylinder(objCylinder,0.05, 0.05, 0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(0.0,0.99,5.8); /*刻度*/ glRotatef(180.0,0.0,1.0,0.0); gluCylinder(objCylinder,0.05, 0.05,0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,1.0,0.0); glRotatef(45.0,0.0,1.0,0.0); glTranslatef(-0.67,0.99,0.7); /*时针*/ glRotatef(Angle1/129600,0.0,1.0,0.0); gluCylinder(objCylinder, 0.07, 0.02, 2.5, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,0.0); glTranslatef(0.0,0.99,1.0); /*分针*/ glRotatef(Angle2/360,0.0,1.0,0.0); gluCylinder(objCylinder, 0.05, 0.02, 3.5, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.5); glTranslatef(0.0,0.99,1.0); /*秒针*/ glRotatef(Angle1,0.0,1.0,0.0); gluCylinder(objCylinder, 0.07, 0.02, 4.5, 9999, 9); glPopMatrix(); SwapBuffers(dc.m_ps.hdc); glDrawBuffer (GL_BACK); glFlush(); } else if(Timer==2) { glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT); if (juli>12.0) { glMatrixMode(GL_MODELVIEW);/*建立了从世界坐标系到观察坐标系的转换矩阵*/ glLoadIdentity(); gluLookAt(0.0,8.0,juli,0.0,0.0,0.0,0.0,1.0,0.0); juli=juli-0.1; glPushMatrix(); glColor3f(0.0,0.0,0.0); glRotatef(-90.0,1.0,0.0,0.0); glutWireCone(40.0,0.0,30.0,30.0); /*画高度为0的圆锥*/ glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glLineWidth(4.0); glTranslatef(4.0,1.0,0.0); glutWireOctahedron(); /*画八面体*/ glLineWidth(1.0); glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glTranslatef(0.0,1.1,0.0); glRotatef(Angle2,0.0,1.0,0.0); gluCylinder(objCylinder, 1.0, 1.0, 10.0, 9999, 9); /*画壶*/ glPopMatrix(); } else if(juli<=12.0) { Angle2=Angle2+0.01; if (Angle2==360.0) Angle2=0.0; glMatrixMode(GL_MODELVIEW);/*建立了从世界坐标系到观察坐标系的转换矩阵*/ glLoadIdentity(); x=12.0*sin(Angle2); z=12.0*cos(Angle2); gluLookAt(x,5.0,z,0.0,0.0,0.0,0.0,1.0,0.0); glPushMatrix(); glColor3f(0.0,0.0,0.0); glRotatef(-90.0,1.0,0.0,0.0); glutWireCone(40.0,0.0,30.0,30.0); /*画高度为0的圆锥*/ glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glLineWidth(4.0); glTranslatef(4.0,1.0,0.0); glutWireOctahedron(); /*画八面体*/ glLineWidth(1.0); glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glTranslatef(0.0,1.1,0.0); gluCylinder(objCylinder, 1.0, 1.0, 10.0, 9999, 9); /*画壶*/ glPopMatrix(); } SwapBuffers(dc.m_ps.hdc); glDrawBuffer (GL_BACK); glFlush(); } CView::OnTimer(nIDEvent); } void CMFCFrame1View::OnChangDirect() { // TODO: Add your command handler code here Timer=2; SetTimer(1,100 ,NULL); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值