上学期帮舍友改了下的半成品,这次继续学习接着改。
记得老师有说过要注意啥啥按列存储的。
没搞明白,然后发现有的按行存储,甚是不解。
《交互式计算机图形学》这本书上注释着按列存储。
嗯,然后我以为电脑应该一样吧。但是左右上下平移发现怎么有是我按的那个方向的线变短,另一个方向的变长,反正就是正方形变成畸形的六面体了。
可能有的按行有的按列,我用的是vs2013社区版。按行存储
所以样例【其他旋转甚么的也是同理转置一下】
x方向平移athat,y方向平移direct。
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);
其他的按列存储
t=mat4(1.0,0.0,0.0,athat,,
0.0,1.0,0.0,direct,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0);
【简单的说就是它们是互为转置矩阵,更通俗易懂就讲就是沿着 \ 交换数值】
话说在vshader顶点着色器中 gl_Position =t*rx*rz*ry*sf*vPosition; 和 gl_Position =rx*rz*ry*sf*t*vPosition;弄出来的是不一样的哦。
搜罗很多资料,和我要的效果都不一样,然后我就改了一下,发现前者才是我要的效果。
我要的效果是按着世界坐标系上下左右平移旋转,而后者好像貌似是绕着对象坐标系上下左右平移旋转【目前个人感觉应该是这样吧】
整个工程 http://download.csdn.net/detail/u014646950/9477261
工程里面和exe在同一目录的.glsl忘记更改了。
//
// 绘制一个旋转的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];
// 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)
};
color4 gr = color4(1.0, 1.0, 1.0, 1.0);
color4 onecolor = color4(1.0, 0.0, 1.0, 1.0);
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 cc;
//----------------------------------------------------------------------------
// 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)
{
points[Index] = vertices[a]; Index++;
points[Index] = vertices[b]; Index++;
points[Index] = vertices[c]; Index++;
points[Index] = vertices[a]; Index++;
points[Index] = vertices[c]; Index++;
points[Index] = vertices[d]; Index++;
}
//----------------------------------------------------------------------------
// generate 12 triangles: 36 vertices
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();
// 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),
NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
// 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));
cc = glGetUniformLocation(program, "cc");
thet = glGetUniformLocation(program, "theta");
atha = glGetUniformLocation(program, "athat");
direct = glGetUniformLocation(program, "direct");
f = glGetUniformLocation(program, "ff");
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);
glUniform3fv(thet, 1, Thet);
glUniform1f(atha, Disx);
glUniform1f(direct, Dis);//传递单个的
glUniform1f(f, fd);
glUniform4fv(cc, 1, onecolor);
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 = vec4(0.0f, 0.0f, 0.0f, 1.0f); break;//黑色
case 2:onecolor = vec4(0.0f, 0.0f, 1.0f, 1.0f); break;//蓝色
case 3:onecolor = vec4(1.0f, 0.0f, 1.0f, 1.0f); break;//品红色
case 4:onecolor = vec4(0.0f, 1.0f, 1.0f, 1.0f); 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;
}
#version 150
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
uniform vec4 cc;
uniform vec3 theta;
uniform float athat;
uniform float direct;
uniform float ff;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );
// Remeber: thse matrices are column-major
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;
color=cc;
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);
gl_Position =t*rx*rz*ry*sf*vPosition;
}
fshader.glsl
#version 150
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
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