OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图

4 篇文章 0 订阅

读取bmp等图片格式中的像素还有难度,就先用这个棋盘图象素来弄了

代码打错一个就一直First-chance exception ,貌似还有一个要用q或者Q才能成功退出,不知道缺少哪句,我用窗口红叉退出也会First-chance exception 

glTexParameterf写错成glTextureParameteri

随手来个链接https://www.opengl.org/sdk/docs/man/html/glTexParameter.xhtml

工程资源http://download.csdn.net/detail/u014646950/9528502

//
// 绘制一个旋转的OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用
// 使用空闲回调函数增加旋转的角度
//  立方体的旋转角度被发送到用于实现立方体旋转的顶点着色器中

#include "Angel.h"
#pragma comment(lib, "glew32.lib")

typedef Angel::vec4  color4;
typedef Angel::vec4  point4;



const int NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle)

point4 points[NumVertices];
vec3 normals[NumVertices];//法向量标记

// Vertices of a unit cube centered at origin, sides aligned with axes
point4 vertices[8] = {
	point4(-0.5, -0.5, 0.5, 1.0),
	point4(-0.5, 0.5, 0.5, 1.0),
	point4(0.5, 0.5, 0.5, 1.0),
	point4(0.5, -0.5, 0.5, 1.0),
	point4(-0.5, -0.5, -0.5, 1.0),
	point4(-0.5, 0.5, -0.5, 1.0),
	point4(0.5, 0.5, -0.5, 1.0),
	point4(0.5, -0.5, -0.5, 1.0)
};
 



const int texturesize = 64; //新增或有更改
GLuint textureloc;//新增或有更改
GLubyte imageRBG[texturesize][texturesize][3];//新增或有更改
vec2 tex_coords[NumVertices];//新增或有更改

void imageinit()//新增或有更改
{
	for (int i = 0; i < 64; i++)
	{
		for (int j = 0; j < 64; j++)
		{
			GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0) )*255;
			imageRBG[i][j][0] = imageRBG[i][j][1] = imageRBG[i][j][2] = c;
		}
	}
	glGenTextures(1, &textureloc);//产生一个纹理对象标志符并存在地址textureloc中

	glBindTexture(GL_TEXTURE_2D, textureloc);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texturesize, texturesize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageRBG);
	//target90FL_TEXTURE_[1,2,3]D或者GL_TEXTURE_CUBE_MAP;level,iformat,width,height,border,format,type,&textureeloc;
	
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//写错成glTextureParameteri
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, textureloc);

}//新增或有更改











// Array of rotation angles (in degrees) for each coordinate axis
//enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
//enum { Xdist = 0, Ydist = 1, Zdist = 2, NumAxes1 = 3 };
color4 gr = color4(1.0, 1.0, 1.0, 1.0); 
color4 onecolor = color4(1.0, 0.0, 0.0, 1.0);
color4 light_ex;
int      Axi = 0;//Xaxis;
GLfloat  Thet[3] = { 0.0, 0.0, 0.0 };
//GLfloat  Atha[3] = { 0.0, 0.0, 0.0 };
GLfloat Disx = 0;
GLfloat Dis = 0;
GLfloat fd = 1;

GLuint  thet;  // The location of the "theta" shader uniform variable
GLuint atha;
GLuint direct;
GLuint f;
GLuint vam;
//----------------------------------------------------------------------------

// quad generates two triangles for each face and assigns colors
//    to the vertices
int Index = 0;
void
quad(int a, int b, int c, int d)
{
	vec4 u = vertices[b] - vertices[a];
	vec4 v = vertices[c] - vertices[b];
	vec3 normal = normalize(cross(u, v));//normalize叉乘得到法向量
	normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;新增或有更改
	normals[Index] = normal; points[Index] = vertices[b]; tex_coords[Index] = vec2(0.0, 1.0); Index++;新增或有更改
	normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;新增或有更改
	normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;新增或有更改
	normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;新增或有更改
	normals[Index] = normal; points[Index] = vertices[d]; tex_coords[Index] = vec2(1.0, 0.0); Index++;新增或有更改
}

//----------------------------------------------------------------------------

// generate 12 triangles: 36 vertices and 36 colors
void
colorcube()
{
	quad(1, 0, 3, 2);
	quad(2, 3, 7, 6);
	quad(3, 0, 4, 7);
	quad(6, 5, 1, 2);
	quad(4, 5, 6, 7);
	quad(5, 4, 0, 1);
}

//----------------------------------------------------------------------------

// OpenGL initialization
void
init()
{
	colorcube();//新增或有更改
	imageinit();//新增或有更改

	// Create a vertex array object
	GLuint vao;
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	// Create and initialize a buffer object
	GLuint buffer;
	glGenBuffers(1, &buffer);

	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals) + sizeof(tex_coords), NULL, GL_STATIC_DRAW);//

	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
	glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(normals), normals);
	glBufferSubData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals), sizeof(tex_coords), tex_coords);//新增或有更改

	// Load shaders and use the resulting shader program
	GLuint program = InitShader("vshader.glsl", "fshader.glsl");
	glUseProgram(program);

	// set up vertex arrays
	GLuint vPosition = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(vPosition);
	glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0,BUFFER_OFFSET(0));

	GLuint vNormal = glGetAttribLocation(program, "vNormal");
	glEnableVertexAttribArray(vNormal);
	glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)));


	GLuint vTexCoord = glGetAttribLocation(program, "vtexCoord");新增或有更改
	glEnableVertexAttribArray(vTexCoord);新增或有更改
	glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points) + sizeof(normals)));新增或有更改

	//初始化光照参数la,ld,ls环境,漫反射,镜面反射
	point4 light_position(0.0, 0.0, 2.0,-0.0);
	//color4 light_ambient(1.0,0.0,0.0,1.0);//R红_G绿_B蓝
	color4 light_diffuse(1.0, 1.0, 1.0, 1.0);
	color4 light_specular(1.0, 1.0, 1.0, 1.0);

	
	color4 material_ambient(1.0, 0.0, 1.0, 1.0);
	color4 material_diffuse(1.0, 0.8, 0.0, 1.0);
	color4 material_specular(1.0, 0.8, 0.0, 1.0);
	float material_shininess = 20.0;//高光系数 高金属 低塑料
	
	light_ex = material_ambient;
	//color4 ambient_product = light_ambient*material_ambient;
	color4 diffuse_product = light_diffuse*material_diffuse;
	color4 specular_product = light_specular*material_specular;

	glUniform4fv(glGetUniformLocation(program, "DiffuseProduct"), 1, diffuse_product);
	glUniform4fv(glGetUniformLocation(program, "SpecularProduct"), 1, specular_product);
	glUniform4fv(glGetUniformLocation(program, "LightPosition"), 1, light_position);
	glUniform1f(glGetUniformLocation(program,"Shininess"),material_shininess);

	vam = glGetUniformLocation(program, "AmbientProduct");
	thet = glGetUniformLocation(program, "theta");
	atha = glGetUniformLocation(program, "athat");
	direct = glGetUniformLocation(program, "direct");
	f = glGetUniformLocation(program, "ff");


	
	glUniform1i(glGetUniformLocation(program, "texture"), 1);//新增或有更改
	//texture在vshader里面,后面的1对应glActiveTexture(GL_TEXTURE1);
	//如果0,那么对应glActiveTexture(GL_TEXTURE0);
	//如果3,那么对应glActiveTexture(GL_TEXTURE3);



	glEnable(GL_DEPTH_TEST);///开启深度缓存测试
	glEnable(GL_CULL_FACE);///启动多边形剔除功能
	
	//glOrtho(1.0, 0.0, 0.0, 1.0, 0.0, 1.0);

}

//----------------------------------------------------------------------------

void
display(void)
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	//glMatrixMode(GL_PROJECTION);
    //glMatrixMode(GL_MODELVIEW);
	//glLoadIdentity(); 
	//gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0);
	glUniform4fv(vam, 1, light_ex*onecolor);
	glUniform3fv(thet, 1, Thet);
	glUniform1f(atha, Disx);
	glUniform1f(direct, Dis);//传递单个的 
	glUniform1f(f, fd);  
	glDrawArrays(GL_TRIANGLES, 0, NumVertices);
	glClearColor(gr[0], gr[1], gr[2], gr[3]);
	glFlush(); 
}


void ProcessMenu(int value)
{
	if (value == 0)
		exit(0);

	if (value == 100)
	{
		gr = vec4(1.0f, 1.0f, 1.0f, 1.0f);
		onecolor = vec4(1.0, 0.0, 1.0, 1.0);
	}
	else{

		switch (value)
		{
		case 21:gr = vec4(0.75f, 0.0f, 1.0f, 1.0f); break;
		case 22:gr = vec4(0.75f, 0.75f, 1.0f, 1.0f); break;
		case 23:gr = vec4(1.75f, 1.75f, 0.75f, 1.0f); break;
		case 24:gr = vec4(1.75f, 1.0f, 1.55f, 1.0f); break;
		case 25:gr = vec4(0.0f, 1.0f, 0.75f, 0.0f); break;
		case 1:onecolor = color4(0.0, 0.0, 0.0, 1.0); break;//黑色
		case 2:onecolor = color4(0.0, 0.0, 1.0, 1.0); break;//蓝色
		case 3:onecolor = color4(1.0, 0.0, 1.0, 1.0); break;//品红色
		case 4:onecolor = color4(0.0, 1.0, 1.0, 1.0); break;//青色
		}
	}
	glutSwapBuffers();
	glutPostRedisplay();
}

//----------------------------------------------------------------------------

void
keyboard(unsigned char key, int x, int y)
{ 
	switch (key) {
	case 'x':    Axi = 0; break; //Xaxis;  break;
	case 'y':    Axi = 1; break;//Yaxis;  break;
	case 'z':    Axi = 2; break;//Zaxis;  break;选择对应的x,y,z旋转角度来变化
	case 'f':fd += 0.1; break;//Xdist; break;
	case 's':fd -= 0.1; break;//Ydist; break;
	case 033: // Escape Key
	case 'q': case 'Q':
		exit(EXIT_SUCCESS);
		break;
	}
	if (fd == 0)fd = 0.1;
}
void SpecialKeys(int key, int x, int y)
{ 
	switch (key) {
	case GLUT_KEY_UP:Dis += 0.01;  break;
	case GLUT_KEY_DOWN:Dis -= 0.01;  break;//Ydist; break;
	case GLUT_KEY_LEFT:Disx -= 0.01;   break; 
	case GLUT_KEY_RIGHT:Disx += 0.01;   break;//Xdist; break;
	case 033: // Escape Key
	case 'q': case 'Q':
		exit(EXIT_SUCCESS);
		break;
	}
}

//----------------------------------------------------------------------------


//----------------------------------------------------------------------------

void
idle(void)
{
	Thet[Axi] += 0.01;

	if (Thet[Axi] > 360.0) {
		Thet[Axi] -= 360.0;
	}
	glutSwapBuffers();
	glutPostRedisplay();
}




//----------------------------------------------------------------------------

int
main(int argc, char **argv)
{
	 
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(512, 512);
	glutInitContextVersion(3, 1);
	//这里在舍友的电脑上用3,2可以用,在我的电脑上会出现
	//freeglut(dll地址):unableto create OpenGL3.2 context(flags 0, profile 1)
	//我改成3,1就可以了。不知道会不会是版本问题。这里用的是比较旧的版本freeglut。

	glutInitContextProfile(GLUT_CORE_PROFILE);
	glutCreateWindow("Color Cube");

	glewExperimental = true;
	glewInit(); 
	int nGlutColorMenu1 = glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("black", 1);
	glutAddMenuEntry("blue", 2);
	glutAddMenuEntry("magenta", 3);
	glutAddMenuEntry("cyan", 4);

	int nGlutColorMenu2 = glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("background1", 21);
	glutAddMenuEntry("background2", 22);
	glutAddMenuEntry("background3", 23);
	glutAddMenuEntry("background4", 24);
	glutAddMenuEntry("background5", 25);

	int nGlutColorMenu3 = glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("return", 100);

	int nGlutColorMenu = glutCreateMenu(ProcessMenu);
	glutAddSubMenu("coclor", nGlutColorMenu1);
	glutAddSubMenu("background", nGlutColorMenu2);
	glutAddSubMenu("return", nGlutColorMenu3);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
	init();
	glutDisplayFunc(display);
	glutSpecialFunc(SpecialKeys);
	glutKeyboardFunc(keyboard);
	//glutMouseFunc(mouse);
	glutIdleFunc(idle);
	 

	glutMainLoop();
	return 0;
}
vshader.glsl

#version 150

in vec2 vtexCoord;新增或有更改
in  vec4 vPosition;
in vec3 vNormal;

out vec2 texCoord;新增或有更改
out vec4 color;


uniform vec4 AmbientProduct,DiffuseProduct,SpecularProduct;
uniform vec4 LightPosition;
uniform float Shininess;
uniform vec3 theta;
uniform float athat;
uniform float direct;
uniform float ff;
void main() 
{ 
   texCoord=vtexCoord;新增或有更改
    vec3 angles = radians( theta );
    vec3 c = cos( angles );
    vec3 s = sin( angles );

     mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
		    0.0,  c.x,  s.x, 0.0,
		    0.0, -s.x,  c.x, 0.0,
		    0.0,  0.0,  0.0, 1.0 );

    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
		    0.0, 1.0,  0.0, 0.0,
		    s.y, 0.0,  c.y, 0.0,
		    0.0, 0.0,  0.0, 1.0 );

    // Workaround for bug in ATI driver
    ry[1][0] = 0.0;
    ry[1][1] = 1.0;

    mat4 rz = mat4( c.z, s.z, 0.0, 0.0,
		    -s.z,  c.z, 0.0, 0.0,
		    0.0,  0.0, 1.0, 0.0,
		    0.0,  0.0, 0.0, 1.0 );

    // Workaround for bug in ATI driver
    rz[2][2] = 1.0;
    
    //color = vColor; 
	mat4 t=mat4(1.0,0.0,0.0,0.0,
	0.0,1.0,0.0,0.0,
	0.0,0.0,1.0,0.0,
	athat,direct,0.0,1.0); 
	   
    mat4 sf=mat4(ff,0.0,0,0,
	0.0,ff,0.0,0.0,
	0.0,0.0,ff,0.0,
	0.0,0.0,0.0,1.0); 
	mat4 modeview=t*rx*rz*ry;
	vec3 pos=(modeview*vPosition).xyz;

	vec3 L=normalize(LightPosition.xyz-pos);
	vec3 E=normalize(-pos);
	vec3 H=normalize(L+E);

	vec3 N=normalize(modeview*vec4(vNormal,0.0)).xyz;

	
	vec4 ambient=AmbientProduct;
	                        
	float Kd=max(dot(L,N),0.0);
	vec4 diffuse=Kd*DiffuseProduct;
	   float Ks=pow(max(dot(N,H),0.0),Shininess);
	   vec4 specular=Ks*SpecularProduct;
    if(dot(L,N)<0.0)

	 specular=vec4(0.0,0.0,0.0,1.0);
    gl_Position =modeview*sf*vPosition;
	color=ambient+diffuse+specular;
	color.a=1.0;
} 

fshader.glsl

#version 150
in vec2 texCoord;新增或有更改
in  vec4 color;
out vec4 fColor;

uniform sampler2D texture;新增或有更改
void main() 
{ 

    fColor = color*texture2D(texture,texCoord);新增或有更改
} 

InitShader.cpp 

#include "Angel.h"

namespace Angel {

// Create a NULL-terminated string by reading the provided file
static char*
readShaderSource(const char* shaderFile)
{
    //FILE* fp = fopen(shaderFile, "r");
	//由于vs甚么安全性的原因,不让使用fopen,用下面的fopen_s代替;
	FILE *fp;
	fopen_s(&fp, shaderFile, "r");


    if ( fp == NULL ) { return NULL; }

    fseek(fp, 0L, SEEK_END);
    long size = ftell(fp);

    fseek(fp, 0L, SEEK_SET);
    char* buf = new char[size + 1];
    fread(buf, 1, size, fp);

    buf[size] = '\0';
    fclose(fp);

    return buf;
}


// Create a GLSL program object from vertex and fragment shader files
GLuint
InitShader(const char* vShaderFile, const char* fShaderFile)
{
    struct Shader {
	const char*  filename;
	GLenum       type;
	GLchar*      source;
    }  shaders[2] = {
	{ vShaderFile, GL_VERTEX_SHADER, NULL },
	{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
    };

    GLuint program = glCreateProgram();
    
    for ( int i = 0; i < 2; ++i ) {
	Shader& s = shaders[i];
	s.source = readShaderSource( s.filename );
	if ( shaders[i].source == NULL ) {
	    std::cerr << "Failed to read " << s.filename << std::endl;
	    exit( EXIT_FAILURE );
	}

	GLuint shader = glCreateShader( s.type );
	glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
	glCompileShader( shader );

	GLint  compiled;
	glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
	if ( !compiled ) {
	    std::cerr << s.filename << " failed to compile:" << std::endl;
	    GLint  logSize;
	    glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
	    char* logMsg = new char[logSize];
	    glGetShaderInfoLog( shader, logSize, NULL, logMsg );
	    std::cerr << logMsg << std::endl;
	    delete [] logMsg;

	    exit( EXIT_FAILURE );
	}

	delete [] s.source;

	glAttachShader( program, shader );
    }

    /* link  and error check */
    glLinkProgram(program);

    GLint  linked;
    glGetProgramiv( program, GL_LINK_STATUS, &linked );
    if ( !linked ) {
	std::cerr << "Shader program failed to link" << std::endl;
	GLint  logSize;
	glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
	char* logMsg = new char[logSize];
	glGetProgramInfoLog( program, logSize, NULL, logMsg );
	std::cerr << logMsg << std::endl;
	delete [] logMsg;

	exit( EXIT_FAILURE );
    }

    /* use program object */
    glUseProgram(program);

    return program;
}

}  // Close namespace Angel block

随便一图


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenGL是一种开放源代码的图形库,用于开发二维和三维图形应用程序。其支持光照平移旋转缩放等功能。 光照是在OpenGL实现逼真和真实感的一个重要方面。通过对物体表面的光照进行计算和模拟,可以模拟出光线在真实世界的表现。OpenGL提供了多种光照模型和光源类型,如平行光照、点光源和聚光灯等。通过设置光源的属性,如位置、颜色和强度,可以控制光照的效果。同时,还可以设置材质的属性,如漫反射、镜面反射和环境光反射等,以使物体表面具有不同的反射特性。 平移旋转缩放是控制物体在OpenGL位置、方向和大小的重要操作。通过平移(Translation),可以改变物体的位置。通过旋转(Rotation),可以改变物体的方向。通过缩放(Scaling),可以改变物体的大小。这些操作可以通过设置模型视图矩阵来实现,将物体的顶点坐标进行相应的变换。平移旋转缩放都可以相对于世界坐标系进行,也可以相对于物体自身坐标系进行。 在OpenGL,可以通过矩阵操作来实现平移旋转缩放平移可以通过将物体的位置矩阵与一个平移矩阵相乘来实现。旋转可以通过将物体的方向矩阵与一个旋转矩阵相乘来实现。缩放可以通过将物体的大小矩阵与一个缩放矩阵相乘来实现。通过改变这些矩阵的数值,可以控制物体在空间的位置、方向和大小。 总结来说,OpenGL提供了一系列的函数和接口,可以实现光照平移旋转缩放等操作,使得开发者可以自由控制物体的表现和行为。这些功能在图形应用程序非常重要,可以帮助开发者创建出逼真和动态的图形效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值