opengl纹理,光照,glColor4f(),混合

OpenGL中glClear、glColor4f、glClearColor的简单说明 函数原型:     void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha); void glColor4f(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha); void glClear(GLbitfield mask); 阅读详情

glColor4f()与光照是平级的,且两者互斥,水火不容,有我没你.对于纹理图片中的某个像素P(r,g,b,1):

(1)如果有光照L(Lr,Lg,Lb,x),则glColor4f(Cr,Cg,cb,Calpha)无用,像素P应该只乘以光照L,则像素P的实际颜色P1=P*L=(r*Lr,g*Lg,b*Lb,1);(注:P1的alpha恒为1,无须乘以光照的alpha值,即光照的alpha值在此处无用。下面的程序中可验证,无论x取何值,都对结果无影响)。

(2)如果无光照,则glColor4f(Cr,Cg,cb,Calpha)有效,则P1=P*C=( r*Cr,g*Cg,b*Cb,Calpha).如果还有混合的话,则P1再按alpha比例与以前的点混合.

总结:

(1)有光照时:像素点最终颜色P1的alpha恒为1,P1的RGB=像素RGB*光照RGB。

(2)无光照时:像素点最终颜色P1的alpha为glColor4f()的alpha值,P1的RGB=像素RGB*glColor4f()的RGB。

可以通过下面的程序来验证结果(可用QQ截图查看最终显示图的像素).

代码如下(摘自nehe的opengl教程-07-灯光,且可在DrawGLScene()函数内更改混合状态(glEnable(GL_BLEND) 或者glDisable(GL_BLEND)),程序运行后按大写的L可打开/关闭光源,且为了便于计算,我把纹理图片.bmp特意做成背景为白色,里面有几个红色,绿色,和像素为100的小方框):

其中,opengl默认背景glClearColor(0.6,0.6,0.6),光照值为(0.4,0.4,0.4,x),待检验的像素为100,即(100/255,100/255,100/255),设r=100/255,无光照时glColor4f(0.2,0.2,0.2,0.1)的alpha=0.1:

一、如果混合方式为glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA):

(1)无光源:则glColor4f(0.2,0.2,0.2,0.1)有效,所以像素P的实际颜色为

P1=背景色RGB*对应alpha+像素色RGB*glColor4f颜色RGB*对应alpha

=(0.6,0.6,0.6)*0.9+(100/255,100/255,100/255)*(0.2,0.2,0.2)*0.1

=(0.6*0.9,0.6*0.9,0.6*0.9)+(100/255 *0.2*0.1,100/255 *0.2*0.1,100/255 *0.2*0.1),各乘以255后为(140, 140, 140);

(2)有光源:则glColor4f()无效,所以像素P的实际颜色为

P1=背景色RGB*对应alpha +像素色RGB*光照颜色RGB*对应alpha

=(0.6,0.6,0.6)*0+(100/255,100/255,100/255)*( 0.4,0.4,0.4)*1

=(0.6*0,0.6*0,0.6*0)+(100/255 *0.4* 1,100/255 *0.4* 1,100/255 *0.4* 1),各乘以255后为(40, 40, 40)。

 

二、如果混合方式为glBlendFunc(GL_SRC_ALPHA, GL_ONE);即已画的(目标)不变,再加上要画的源):

(1)无光源:则glColor4f(0.2,0.2,0.2,0.1)有效,所以像素P的实际颜色为

P1=背景色RGB*对应alpha+像素色RGB*glColor4f颜色RGB*对应alpha

=(0.6,0.6,0.6)*1+(100/255,100/255,100/255)*(0.2,0.2,0.2)*0.1

=(0.6,0.6,0.6)+(100/255 *0.2*0.1,100/255 *0.2*0.1,100/255 *0.2*0.1),各乘以255后为(155, 155, 155);

(2)有光源:则glColor4f()无效,所以像素P的实际颜色为

P1=背景色RGB*对应alpha +像素色RGB*光照颜色RGB*对应alpha

=(0.6,0.6,0.6)*1+(100/255,100/255,100/255)*( 0.4,0.4,0.4)*1

=(0.6,0.6,0.6)+(100/255 *0.4* 1,100/255 *0.4* 1,100/255 *0.4* 1),各乘以255后为(193, 193, 193)。

 

三、如果混合方式为glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);则与glBlendFunc(GL_SRC_ALPHA, GL_ONE);的结果一样,这表示,帧缓存中像素的alpha值就是1。

 

四、而上面有无光照的2种情况,在无混合时,无需乘以对应的alpha:

(1)无光源:则glColor4f(0.2,0.2,0.2,0.1)有效,所以像素P的实际颜色为P1=像素色RGB*glColor4f颜色RGB=(100/255,100/255,100/255)*(0.2,0.2,0.2)

=(100/255* 0.2, 100/255* 0.2, 100/255* 0.2),各乘以255后为(20, 20, 20);

(2)有光源:则glColor4f()无效,所以像素像素P的实际颜色为P1=像素色RGB*光照颜色RGB= (100/255,100/255,100/255)*( 0.4,0.4,0.4)

=(100/255* 0.4, 100/255* 0.4, 100/255* 0.4) ,各乘以255后为(40, 40, 40)。

 

验证时,为简化,可只检验一个颜色,如颜色(r,g,b)的r值。

 

下面这段代码可控制光源中只有全局环境光(为(0.4,0.4,0.4,0.7)),这样在计算某个点的光照,混合,纹理时可把光照值定下来(此处为(0.4,0.4,0.4, 0.7)),再确定其他操作(如混合)以像素产生的效果.

注:顶点光照值为:自发散光+全局环境光+光源环境光+散射光+镜面光=

Emission+ LIGHT_MODEL_AMBIENT+ Ambient+ Diffuse+ Specular

(此处只有全局环境光(0.4,0.4,0.4, 0.7))

且结果与全局环境光的alpha值0.7无关。即当前点的alpha值与光照的alpha值是无关的。

 

GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };

GLfloat mat_diffuse[] = { 0.0, 0.0, 0.0, 1.0 };//无散射光

GLfloat mat_emission[] = { 0.0, 0.0, 0.0, 1.0 };//无自发散光

GLfloat mat_specular[] = { 0.4, 0.4, 0.4, 1.0 };//

GLfloat mat_shininess[] = { 2.0 };

 

GLfloat LightPosition[] = { 1.0, 1.0, 1.0, 1.0 };//点光源(位置性光源)

GLfloat LightAmbient[] = { 0.0, 0.0, 0.0, 1.0};//无光源的环境光

GLfloat LightDiffuse[] = {1.0, 1.0, 1.0, 1.0};

GLfloat light_specular[] ={ 0.0, 0.0, 0.0, 1.0};//无镜面光

GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 0.7};//只有全局环境光

 

glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);

glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

 

glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);//点光源相对视点的位置始终不变,此处是(1,1,1)

glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);

glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);

glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

 

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);//全局环境光

 

glEnable(GL_LIGHTING);                    // 启用光源

glEnable(GL_LIGHT0);                      // 启用0号光源

 

glClearColor( 0.6f, 0.6f, 0.6f, 0.3f);//背景色

 

前面(一)glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)对应的完整源代码如下:

#pragma comment( lib, "opengl32.lib" )          

#pragma comment( lib, "glu32.lib" )   

#pragma comment( lib, "glut32.lib")

#pragma comment( lib, "glew32.lib")

#pragma comment( lib, "glaux.lib")

#pragma comment( lib, "vfw32.lib" )   

/********************************************************************************************************************************/

 

#include <windows.h>     // Windows的头文件

#include "glew.h"        // 包含最新的gl.h,glu.h库

#include <stdio.h>          // 标准输入/输出库的头文件

#include "glaux.h"          // GLaux库的头文件

 

GLfloat       xrot;         // X 旋转量

GLfloat       yrot;         // Y 旋转量

GLfloat       zrot;         // Z 旋转量

/***********************************新添的代码***********************************************************************************/

GLfloat xspeed;                                      // X 旋转速度

GLfloat yspeed;                                      // Y 旋转速度

 

BOOL   light;                                    // 光源的开/关

BOOL   lp;                                       // L键按下了么?

BOOL   fp;                                       // F键按下了么?

 

GLfloat    z=-5.0f;                                   // 深入屏幕的距离

 

GLuint filter;                                       // 滤波类型

GLuint texture[3];                                   // 3种纹理的储存空间

 

GLfloat spot1_direction[] = { 0.0f, 0,-1.0f};                  // light1的聚光方向,沿相机视线方向

GLfloat angle_Light1 = 30.370f;                                   //聚光源light1的截止角

 

 

GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };

//GLfloat mat_diffuse[] = { 0.4, 0.4, 0.4, 1.0 };

GLfloat mat_diffuse[] = { 0.0, 0.0, 0.0, 1.0 };//无散射光

GLfloat mat_emission[] = { 0.0, 0.0, 0.0, 1.0 };//无自发散光

GLfloat mat_specular[] = { 0.4, 0.4, 0.4, 1.0 };

GLfloat mat_shininess[] = { 2.0 };

 

GLfloat LightPosition[] = { 1.0, 1.0, 1.0, 1.0 };//点光源(位置性光源)

GLfloat LightAmbient[] = { 0.0, 0.0, 0.0, 1.0};//无光源的环境光

GLfloat LightDiffuse[] = {1.0, 1.0, 1.0, 1.0};

GLfloat light_specular[] ={ 0.0, 0.0, 0.0 /*1.0, 1.0, 1.0*/, 1.0};//无镜面光

GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 0.7/*1.0*/};//只有全局环境光

//GLfloat lmodel_ambient[] = { 0.0, 0.0, 0.0, 1.0};

/********************************************************************************************************************************/

 HDC          hDC=NULL;     // 窗口着色描述表句柄

HGLRC      hRC=NULL;     // OpenGL渲染描述表句柄

HWND       hWnd=NULL;    // 保存我们的窗口句柄

HINSTANCE  hInstance;    // 保存程序的实例

 

bool   keys[256];        // 保存键盘按键的数组

bool   active=TRUE;      // 窗口的活动标志,缺省为TRUE

bool   fullscreen=TRUE;  // 全屏标志缺省,缺省设定成全屏模式

 

LRESULT    CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // WndProc的定义

AUX_RGBImageRec *LoadBMP(CHAR *Filename)             // 载入位图图象

{

    FILE *File=NULL;                              // 文件句柄

    if (!Filename)                                  //确保文件名已提供

    {

       return NULL;                             //如果没提供,返回NULL

    }

    File=fopen(Filename,"r");                       //尝试打开文件

    if (File)                                    //文件存在么?

    {

       fclose(File);                             // 关闭句柄

       return auxDIBImageLoadA(Filename);           //载入位图并返回指针

    }

    return NULL;                                 //如果载入失败,返回NULL

}

 

int LoadGLTextures()                            //载入位图(调用上面的代码)并转换成纹理

{

    int Status=FALSE;                            //状态指示器

    AUX_RGBImageRec *TextureImage[1];                // 创建纹理的存储空间

    memset(TextureImage,0,sizeof(void *)*1);        //将指针设为NULL

   

/***********************************新添的代码***********************************************************************************/

    // 载入位图,检查有错,或位图不存在的话退出

    if (TextureImage[0]=LoadBMP("Data/Crate.bmp"))

    {

       Status=TRUE;                       // 状态设为TRUE

       glGenTextures(3, &texture[0]);                // 创建纹理

       // 创建Nearest滤波贴图

       glBindTexture(GL_TEXTURE_2D, texture[0]);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

       glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

 

       // 创建线性滤波纹理

       glBindTexture(GL_TEXTURE_2D, texture[1]);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

       glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

 

       // 创建MipMapped纹理

       glBindTexture(GL_TEXTURE_2D, texture[2]);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);

       gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_

OpenGL入门学习一 基本图形绘制函数介绍 颜色设置 glColor3f(1.0,0.0,0.0) #设置颜色为红色 glColor4f(0.0,1.0,1.0,1.0)#设置颜色为青色,1.0表示不透明度 glColor3ub(0,0,255) #设置颜色为蓝色 glColor3fv([0.0,1.0,0.0]) #设置颜色为青色 设置顶点 glVertex2f(1.0,0.5) #xoy平面上的点,z=0... 阅读详情

相关推荐

OpenGL入门学习笔记

文章目录Lesson1:环境搭建Lesson2:绘制三角形,四边形,多边形Lesson3:光滑着色与平面着色Lesson4:旋转Lesson5:3D空间 Lesson1:环境搭建 OpenGL开发库文件 提取码:orx1 VC++6.0安装包 提取码:944c 将开发库中的.h文件拷贝到Visual C++ 6.0的\Include\GL目录中,若无GL目录,自己建一个 ...

YoungHD的博客 433

OpenGL 核心模式与立即模式:3 个关键差异与迁移路径解析

本文深入解析OpenGL核心模式与立即模式的3个关键差异,包括状态管理机制、着色器角色和性能架构的革新。通过对比代码示例和性能数据,提供从固定管线到现代可编程管线的迁移路径,帮助开发者掌握OpenGL核心模式的优化策略和最佳实践。

1180

OpenGL与Shader入门:从固定管线到可编程渲染的实战指南

在计算机图形学中,可编程渲染管线是实现复杂视觉效果的核心技术。其原理在于将渲染流程中的关键计算阶段(如顶点变换和像素着色)从固定的硬件功能中解放出来,允许开发者通过编写着色器程序进行自定义控制。这一技术的核心价值在于极大地提升了渲染的灵活性和表现力,使得实时生成逼真的光照、材质和特效成为可能。着色器本质上是运行在GPU上的微型并行程序,使用GLSL语言编写,通过顶点着色器和片段着色器等阶段协同工作。在工程实践中,掌握Uniform、顶点属性等数据传递机制,以及VBO、VAO等缓冲区管理,是构建高效渲染流程的

tang_zongyun的博客 858

OpenGL与GDI混合编程:Visual C++图形绘制实战解析

在Windows图形编程中,GDI与OpenGL分别代表了CPU软绘制与GPU硬件加速两条技术路径。GDI擅长线条、文字等基础2D绘制,而OpenGL通过渲染管线和着色器实现复杂3D场景与高效图形输出。理解二者在像素格式、渲染上下文、双缓冲交换等底层机制上的差异,是构建混合渲染架构的关键。实际桌面应用中,常以GDI实现HUD、坐标轴等覆盖层,用OpenGL承载主场景渲染,兼顾开发效率与性能表现。本文以“OpenGL-Drawing.rar”示例工程为切入点,从工程配置、固定管线代码拆解到glUniformM

weixin_34356555的博客 303

Android车载桌面开发实战:从CarLauncher源码解析到自定义Launcher开发(Android 11)

本文深入解析了Android 11中CarLauncher的源码架构与核心模块,并提供了从零开始定制开发车载Launcher的完整实战指南。内容涵盖车载桌面的独特定位、驾驶场景优化、多屏协同、动态内容嵌入等核心挑战,以及如何构建符合安全规范、体验流畅的自定义车载桌面应用,是车载应用开发者提升系统级定制能力的实用参考。

weixin_29266647的博客 516

(2024,DDPM,DDIM,流匹配,SDE,ODE)扩散:基础教程

本文的目标是尽可能简单地教授扩散。第一节介绍扩散的基本原理。第二节和第三节展示如何构建随机和确定性扩散采样器。第四部分介绍了密切相关的流匹配,可看作是扩散的推广。​第五节,强调实践中最重要的一些设计选择,包括采样器、噪声时间表和参数化方法。

qq_44681809的博客 1万+

halcon3D 点云拟合球体

halon3D 点云拟合球面

weixin_43213429的博客 1639

基于TI C2000的CCS安装与工程创建完整示例

手把手演示基于TI C2000系列的CCS安装过程及首个工程创建步骤,涵盖环境配置与常见问题处理,助力快速上手嵌入式开发,ccs安装和工程搭建不再难。

weixin_42476987的博客 969

【Android 11】使用Android Studio调试系统应用之Settings移植(三):构建Settings、SettingsLib项目文件

基于android 11,本系列文章力争实用,讲解使用AS调试系统app的方法,并提供了配套源下载,供学习调试。上一篇文章[Android 11]使用Android Studio调试系统应用(二):依赖分析、android.bp、静态和动态依赖,讲解了如何搭建编译服务器,如何下载AOSP源码,如何切换到AOSP的指定分支(android-11-r39),以及如何编译、解决编译错误、运行模拟器,本文将开始讲解如何构建Settings的AS工程文件! 走过、路过,有用过的同学,记得给个赞O(∩_∩)O哈!

上周的博客 2679

GEE聚类分析:基于sentinel-2 影像进行 K-Means 聚类分析

这篇博客介绍了如何使用 Google Earth Engine (GEE) 进行 K-Means 聚类分析,以识别感兴趣区域(ROI)内的不同地表覆盖类型。文章详细说明了从定义用户参数、准备参考区域、加载和预处理 Sentinel-2 图像,到训练 K-Means 聚类器并对图像进行聚类的完整流程。代码示例展示了如何设置参数、采样像素数据、训练聚类器,并将结果可视化。最后,还提供了将聚类结果导出到 Google Drive 的选项。通过该教程,用户可以掌握在 GEE 平台上进行地理数据聚类分析的基本方法。

此星光明博客 263

CodeX 登录报错 os error 10013?一键修复 CodeX 无法登录问题(亲测有效)

CodeX 登录时报 os error 10013?本文提供快速修复方案,实测有效,彻底解决登录报错:登录失败:failed to start login server: 以一种访问权限不允许的方式做了一个访问套接字的尝试。 (os error 10013)的问题💡

XiaoqiangClub的博客 2925

Spring Boot入门(02):【教程】轻松搭建Spring Boot开发环境,启动你的第一个Web项目!

快速搭建开发环境和启动项目是每个开发人员必备的技能。本文将为您提供一些简单易懂的方法和技巧,以帮助您快速搭建开发环境和启动项目。我们将介绍如何选择适合您的开发工具、配置您的操作系统、安装必要的软件包和依赖项,并开始编写您的第一个应用程序。无论您是一位新手还是一位经验丰富的开发人员,本文都会给您提供有用的信息和实用的建议,让您在最短时间内快速搭建和启动开发项目。

**My Coding Family** 22万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: opengl光照方程的计算验证
下一篇: osglight解析
tmljs1988
博客等级 码龄19年 134粉丝 107原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值