note-50 GLUT light_&_material_01

本文介绍了一个OpenGL灯光与材质的应用实例,同时实现了一个复杂的平面分级算法。文章详细讲解了OpenGL中灯光和材质的设置方法,并通过代码示例展示了如何避免常见错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

openGL 灯光与材质例子. 顺带完成了一个颇复杂的平面分级算法, 修正版,列出了所有易错的地方:

 

 1. 开启了 GL_XXX_ARRAY 后一定要使用对应的pointer, 否则就把 GL_XXX_ARRAY disable 掉.

 

 2. 法线不一定要设置, openGL会自动为每一Vertex生成一个默认的, 自己设置当然可控性更好.

 

 3. initLights() 等GL具体到场景内容的设置必须放在 GLUT 基本设置之后(一开始就死在这个弱智的问题).

 

 4. 灯光的 GL_POSITION, 齐次坐标最后一位如果是 0, 则为平行光, 无需设置 GL_SPOT_DIRECTION 和 GL_SPOT_CUTOFF(这个值为照射角的一半). 如果是1, 则为聚光灯.

 

 5. GL 环境光对所有面都会有影响.尝试变换灯光的颜色和环境光颜色的数组值,观察其变化. 

 

 6. 材质的 SHINESS 参数, 1 端接近橡胶与织物, 128 端接近金属与清漆. 

 

  7. 灯灯灯凳~ 最麻烦的还是平面分级算法, 理论上分级越细, 关照效果越细致, 代码如下:

 

#include <gl/GLUT.h>
#include <stdio.h>


static GLfloat LEVEL=12;
static GLfloat LENGTH=2;
static GLfloat START_PT=-1*(LENGTH/2);
static GLfloat END_PT=1*(LENGTH/2);


GLfloat angle=0;

GLfloat *vertices;
//GLfloat *colors;
short *indices;
GLfloat *normals;

//GLfloat vertices[]={-1,-1,1,
//					-0.3333f,-1,1,
//					0.3333f,-1,1,
//					1,-1,1,
//					-1,-0.3333,1,
//					-0.3333f,-0.3333,1,
//					0.3333f,-0.3333,1,
//					1,-0.3333,1,
//					-1,0.3333,1,
//					-0.3333f,0.3333,1,
//					0.3333f,0.3333,1,
//					1,0.3333,1,
//					-1,1,1,
//					-0.3333f,1,1,
//					0.3333f,1,1,
//					1,1,1};

//short indices[]={0,1,4, 1,5,4, 1,2,5, 2,6,5, 2,3,6, 3,7,6,
//				4,5,8, 5,9,8, 5,6,9, 6,10,9, 6,7,10, 7,11,10,
//				8,9,12, 9,13,12, 9,10,13, 10,14,13, 10,11,14, 11,15,14};



//lights
GLfloat lightPos[]={0,0,2.5f,1};
GLfloat lightColor[]={0.6f,0.3f,0.3f,1};		//red
GLfloat lightDir[]={0,0,-1};

//ambient light
GLfloat light_ambient[]={0.3f,0.3f,0.4f,1};		//light blue


//materials
GLfloat cubeColor[]={0.6f,0.6f,0.6f,1};		//gray color
GLfloat cubeSpecular[]={1,1,1,1};


void setMaterial(){
	glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,cubeColor);
	glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,cubeSpecular);
	//try to change the shiness from 1(rubber/frabic)-128(metal/clear painted)
	glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,20);
}


void drawPlane(){

	glVertexPointer(3,GL_FLOAT,0,vertices);
	//glNormalPointer(GL_FLOAT,0,normals);
	//glColorPointer(4,GL_FLOAT,0,colors);
	glDrawElements(GL_TRIANGLES,(GLsizei)((LEVEL-1)*(LEVEL-1)*2*3),GL_UNSIGNED_SHORT,indices);
}






void drawCube(){

	//set material
	setMaterial();


	glPushMatrix();
		drawPlane();
	glPopMatrix();

	glPushMatrix();
		glRotatef(-90,1,0,0);
		drawPlane();
	glPopMatrix();

	glPushMatrix();
		glRotatef(90,1,0,0);
		drawPlane();
	glPopMatrix();

	glPushMatrix();
		glRotatef(180,1,0,0);
		drawPlane();
	glPopMatrix();

	glPushMatrix();
		glRotatef(90,0,1,0);
		drawPlane();
	glPopMatrix();

	glPushMatrix();
		glRotatef(-90,0,1,0);
		drawPlane();
	glPopMatrix();
}


void rendering(void){

	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	glPushMatrix();
		glRotatef(angle,0,1,0);
		drawCube();
	glPopMatrix();

	glutSwapBuffers();

	angle+=0.01;

}

void reshape(int w, int h){

	if(h==0){
		h=1;
	}

	GLfloat ratio=(GLfloat)(w/h);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0,0,w,h);
	gluPerspective(45,ratio,0.1,1000);
	gluLookAt(0,5,10,0,0,0,0,1,0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();


}

void makeArrays(){
	
	//build vertices array for one face
	GLfloat step=(GLfloat)(LENGTH/(LEVEL-1));
	GLint total=LEVEL*LEVEL*3;
	GLint oneLine=LEVEL*3;	//12

	//printf("level: %f  ", step);

	vertices=new GLfloat[total];
	
	for(int i=0;i<LEVEL;i++){
		//every point x,y,z
		for(int j=0;j<LEVEL*3;j+=3){
			vertices[(i*oneLine)+j]=(GLfloat)(START_PT+(j*step/3));
			vertices[(i*oneLine)+(j+1)]=(GLfloat)(START_PT+i*step);
			vertices[(i*oneLine)+(j+2)]=(GLfloat)(LENGTH/2);

			printf("pt : x: %f, y: %f, z: %f  \n", 
				vertices[(i*oneLine)+j],
				vertices[(i*oneLine)+j+1],
				vertices[(i*oneLine)+j+2]);
		}
	}



	//build colors array, normal white color;
	/*GLint totalColor=LEVEL*LEVEL*4;
	colors=new GLfloat[totalColor];

	for(int r=0;r<totalColor;r+=4){
		colors[r]=1;
		colors[r+1]=1;
		colors[r+2]=1;
		colors[r+3]=1;
	}*/



	//build index array for one face
	//using TRIANGLES

	indices=new short[(LEVEL-1)*(LEVEL-1)*2*3];		//square of LEVEL-1, 2 triangles, 3 points;

	for(int m=0;m<LEVEL-1;m++){

		for(int n=0;n<LEVEL-1;n++){

			indices[m*((GLint)LEVEL-1)*6+n*6+0]=n+m*((GLint)LEVEL-1)+m+0;
			indices[m*((GLint)LEVEL-1)*6+n*6+1]=n+m*((GLint)LEVEL-1)+m+1;
			indices[m*((GLint)LEVEL-1)*6+n*6+2]=n+m*((GLint)LEVEL-1)+m+(LEVEL);
			indices[m*((GLint)LEVEL-1)*6+n*6+3]=n+m*((GLint)LEVEL-1)+m+1;
			indices[m*((GLint)LEVEL-1)*6+n*6+4]=n+m*((GLint)LEVEL-1)+m+(LEVEL)+1;
			indices[m*((GLint)LEVEL-1)*6+n*6+5]=n+m*((GLint)LEVEL-1)+m+(LEVEL);
		}
	}


	normals=new GLfloat[LEVEL*LEVEL*3];

	for(int s=0;s<LEVEL*LEVEL*3;s+=3){
		normals[s]=0;
		normals[s+1]=0;
		normals[s+2]=1;
	}
			
			
}


void initLights(){

	glEnable(GL_LIGHTING);

	glEnable(GL_LIGHT0);
	glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
	glLightfv(GL_LIGHT0,GL_AMBIENT,lightColor);
	glLightfv(GL_LIGHT0,GL_DIFFUSE,lightColor);
	glLightfv(GL_LIGHT0,GL_SPECULAR,lightColor);
	glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightDir);
	glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,45);
	
	//
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_ambient);


}


int main(int argc, char* args[]){

	//make arrays
	makeArrays();
	
	//basic init
	glutInit(&argc,args);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	
	//window init
	glutInitWindowPosition(100,100);
	glutInitWindowSize(600,600);
	glutCreateWindow("light cube");

	//functions init
	glutDisplayFunc(rendering);
	glutIdleFunc(rendering);
	glutReshapeFunc(reshape);

	//gl init
	glEnable(GL_DEPTH_TEST);
	glEnableClientState(GL_VERTEX_ARRAY);
	//glEnableClientState(GL_NORMAL_ARRAY);
	//glEnableClientState(GL_COLOR_ARRAY);

	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

	//init lights
	initLights();
	
	//run main loop, trigger all the funtions
	glutMainLoop();

	return 0;
}



 

 

 

 

 

内容概要:该论文聚焦于T2WI核磁共振图像超分辨率问题,提出了一种利用T1WI模态作为辅助信息的跨模态解决方案。其主要贡献包括:提出基于高频信息约束的网络框架,通过主干特征提取分支和高频结构先验建模分支结合Transformer模块和注意力机制有效重建高频细节;设计渐进式特征匹配融合框架,采用多阶段相似特征匹配算法提高匹配鲁棒性;引入模型量化技术降低推理资源需求。实验结果表明,该方法不仅提高了超分辨率性能,还保持了图像质量。 适合人群:从事医学图像处理、计算机视觉领域的研究人员和工程师,尤其是对核磁共振图像超分辨率感兴趣的学者和技术开发者。 使用场景及目标:①适用于需要提升T2WI核磁共振图像分辨率的应用场景;②目标是通过跨模态信息融合提高图像质量,解决传统单模态方法难以克服的高频细节丢失问题;③为临床诊断提供更高质量的影像资料,帮助医生更准确地识别病灶。 其他说明:论文不仅提供了详细的网络架构设计与实现代码,还深入探讨了跨模态噪声的本质、高频信息约束的实现方式以及渐进式特征匹配的具体过程。此外,作者还对模型进行了量化处理,使得该方法可以在资源受限环境下高效运行。阅读时应重点关注论文中提到的技术创新点及其背后的原理,理解如何通过跨模态信息融合提升图像重建效果。
### 关于 `GLUT_ACTIVE_LEFT` 的定义与用途 在 OpenGL 中,GLUT(OpenGL Utility Toolkit)提供了一组用于简化窗口管理、输入处理和其他常见任务的功能。其中,`GLUT_ACTIVE_LEFT` 是一个常量,表示当前状态中左修饰键的状态。 具体来说,当按下键盘上的 **Alt 键** 或者某些平台特定的 **Left Modifier Key** 时,`GLUT_ACTIVE_LEFT` 将被激活并返回非零值。此功能通常通过回调函数来检测按键组合的状态。例如,在鼠标事件或键盘事件的回调函数中可以使用它来判断是否按下了 Alt 键或其他类似的修饰键[^1]。 以下是其典型用法的一个简单示例: ```c #include &lt;GL/glut.h&gt; void keyboardFunc(unsigned char key, int x, int y) { if (key == &#39;a&#39;) { printf(&quot;Key &#39;a&#39; pressed.\n&quot;); // Check modifier state if (glutGetModifiers() &amp; GLUT_ACTIVE_LEFT) { printf(&quot;&#39;A&#39; was pressed with Left modifier active.\n&quot;); } } } int main(int argc, char** argv) { glutInit(&amp;argc, argv); glutCreateWindow(&quot;GLUT Active Left Example&quot;); glutKeyboardFunc(keyboardFunc); glutMainLoop(); return 0; } ``` 在这个例子中,程序会监听键盘输入,并检查是否有 `GLUT_ACTIVE_LEFT` 被触发的情况。如果用户同时按下 Alt 键和字母 &lsquo;a&rsquo;,则会在控制台打印相应的消息。 需要注意的是,不同操作系统可能对修饰键有不同的解释方式,因此实际效果可能会因运行环境而异[^2]。 #### 注意事项 尽管上述代码展示了如何利用 `GLUT_ACTIVE_LEFT` 来捕获修改器键的行为,但在现代开发实践中,推荐考虑更灵活的框架或者库替代原始的 GLUT 工具包,比如 GLFW 和 SDL 等更为现代化的选择。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值