以下是README所说的示例:“使用旋转灯在一个多边形上凹凸贴图”。让我补充一点:多边形是一个正方形,其上的凹凸贴图应该在原始多边形正方形内产生一个凸起的正方形。 main()中第二个'for'循环中的i和j(像素迭代)的值表示该内部正方形图案。
问题:当我运行它时,显示窗口出现但是它是空白。 也许您可以尝试自己运行它:如果它有效,让我们在设置中找到差异;如果它,请不要帮助找到代码的错误。代码在这里:http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/。单击“代码”,然后单击“第07条/”。这是例子7.3。另外,下面是参考代码。注意:我在fshader73.glsl中添加了“#version 150”以在运行时删除版本错误。
example3.cpp :
/* sets up flat mesh */
/* sets up elapsed time parameter for use by shaders */
#include "Angel.h"
#define N 256
GLfloat normals[N][N][3];
GLuint program;
GLuint texMapLocation;
GLfloat tangent[3] = {1.0, 0.0, 0.0};
typedef Angel::vec4 point4;
typedef Angel::vec4 color4;
point4 points[6];
vec2 tex_coord[6];
mat4 ctm, projection;
vec4 normal = point4(0.0, 1.0, 0.0, 0.0);
color4 light_diffuse = color4(1.0, 1.0, 1.0, 1.0);
color4 material_diffuse = color4(0.7, 0.7, 0.7, 1.0);
point4 light_position = point4(0.0, 10.0, 0.0, 1.0);
vec4 eye = vec4(2.0, 2.0, 2.0, 1.0);
vec4 at = vec4(0.5, 0.0, 0.5, 1.0);
vec4 up = vec4(0.0, 1.0, 0.0, 1.0);
GLuint loc, loc2;
GLuint buffers[2];
GLuint normal_loc;
GLuint diffuse_product_loc;
GLuint light_position_loc;
GLuint ctm_loc, projection_loc;
GLuint tangent_loc;
/* standard OpenGL initialization */
vec4 product(vec4 a, vec4 b)
{
return vec4(a[0]*b[0], a[1]*b[1], a[2]*b[2], a[3]*b[3]);
}
static void init()
{
const float meshColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, meshColor);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glBindTexture(GL_TEXTURE_2D, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, N, N, 0, GL_RGB, GL_FLOAT, normals);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, 0, points);
loc2 = glGetAttribLocation(program, "texcoord");
glEnableVertexAttribArray(loc2);
glVertexAttribPointer(loc2, 2, GL_FLOAT, GL_FALSE, 0, tex_coord);
glGenBuffers(2, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
tangent_loc = glGetUniformLocation(program, "objTangent");
glUniform3fv(tangent_loc, 3, tangent);
normal_loc = glGetUniformLocation(program, "Normal");
glUniform4fv(normal_loc, 4, normal);
vec4 diffuse_product = product(light_diffuse, material_diffuse);
diffuse_product_loc = glGetUniformLocation(program, "DiffuseProduct");
glUniform4fv(diffuse_product_loc, 4, diffuse_product);
light_position_loc = glGetUniformLocation(program, "LightPosition");
glUniform4fv(light_position_loc, 4, light_position);
ctm_loc = glGetUniformLocation(program, "ModelView");
ctm = LookAt(eye, at , up);
glUniformMatrix4fv(ctm_loc, 16, GL_TRUE, ctm);
mat4 nm;
GLfloat det;
det = ctm[0][0]*ctm[1][1]*ctm[2][2]+ctm[0][1]*ctm[1][2]*ctm[2][1]
-ctm[2][0]*ctm[1][1]*ctm[0][2]-ctm[1][0]*ctm[0][1]*ctm[2][2]-ctm[0][0]*ctm[1][2]*ctm[2][1];
nm[0][0] = (ctm[1][1]*ctm[2][2]-ctm[1][2]*ctm[2][1])/det;
nm[0][1] = -(ctm[0][1]*ctm[2][2]-ctm[0][2]*ctm[2][1])/det;
nm[0][2] = (ctm[0][1]*ctm[2][0]-ctm[2][1]*ctm[2][2])/det;
nm[1][0] = -(ctm[0][1]*ctm[2][2]-ctm[0][2]*ctm[2][1])/det;
nm[1][1] = (ctm[0][0]*ctm[2][2]-ctm[0][2]*ctm[2][0])/det;
nm[1][2] = -(ctm[0][0]*ctm[2][1]-ctm[2][0]*ctm[0][1])/det;
nm[2][0] = (ctm[0][1]*ctm[1][2]-ctm[1][1]*ctm[0][2])/det;
nm[2][1] = -(ctm[0][0]*ctm[1][2]-ctm[0][2]*ctm[1][0])/det;
nm[2][2] = (ctm[0][0]*ctm[1][1]-ctm[1][0]*ctm[0][1])/det;
GLuint nm_loc;
nm_loc = glGetUniformLocation(program, "NormalMatrix");
glUniformMatrix4fv(nm_loc, 16, GL_TRUE, nm);
projection_loc = glGetUniformLocation(program, "Projection");
projection = Ortho(-0.75,0.75,-0.75,0.75,-5.5,5.5);
glUniformMatrix4fv(projection_loc, 16, GL_TRUE, projection);
texMapLocation = glGetUniformLocation(program, "texMap");
}
/* set up uniform parameter */
void mesh()
{
point4 vertices[4] = {point4(0.0, 0.0, 0.0, 1.0), point4(1.0, 0.0, 0.0, 1.0),
point4(1.0, 0.0, 1.0, 1.0), point4(0.0, 0.0, 1.0, 1.0)};
points[0] = vertices[0];
tex_coord[0] = vec2(0.0, 0.0);
points[1] = vertices[1];
tex_coord[1] = vec2(1.0, 0.0);
points[2] = vertices[2];
tex_coord[2] = vec2(1.0, 1.0);
points[3] = vertices[2];
tex_coord[3] = vec2(1.0, 1.0);
points[4] = vertices[3];
tex_coord[4] = vec2(0.0, 1.0);
points[5] = vertices[0];
tex_coord[5] = vec2(0.0, 0.0);
}
static void draw()
{
glUniform1i(texMapLocation, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mesh();
glDrawArrays(GL_TRIANGLES, 0, 6);
glutSwapBuffers();
}
static void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glutPostRedisplay();
}
static void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
case 'Q':
case 'q':
exit(EXIT_SUCCESS);
}
}
void idle()
{
int t;
t = glutGet(GLUT_ELAPSED_TIME);
light_position[0] = 5.5*sin(0.001*t);
light_position[2] = 5.5*cos(0.001*t);
glUniform4fv(light_position_loc, 4, light_position);
glutPostRedisplay();
}
int main(int argc, char** argv)
{
int i,j, k;
float d;
float data[N+1][N+1];
for(i=0;i<N+1;i++) for(j=0;j<N+1;j++) data[i][j]=0.0;
for(i=N/4; i< 3*N/4; i++) for(j=N/4;j<3*N/4;j++) data[i][j] = 1.0;
for(i=0;i<N;i++) for(j=0;j<N;j++)
{
normals[i][j][0] = data[i][j]-data[i+1][j];
normals[i][j][2] = data[i][j]-data[i][j+1];
normals[i][j][1]= 1.0;
}
for(i=0;i<N;i++) for(j=0;j<N;j++)
{
d = 0.0;
for(k=0;k<3;k++) d+=normals[i][j][k]*normals[i][j][k];
d=sqrt(d);
for(k=0;k<3;k++) normals[i][j][k]= 0.5*normals[i][j][k]/d+0.5;
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(1024, 1024);
glutInitContextVersion( 3, 2 );
glutInitContextProfile( GLUT_CORE_PROFILE );
glutCreateWindow("Simple GLSL example");
glutDisplayFunc(draw);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
glewInit();
program = InitShader("vshader73.glsl", "fshader73.glsl");
init();
glutMainLoop();
return 0;
}
vshader73.glsl :
/* bump map vertex shader */
#version 150
out vec3 L; /* light vector in texture-space coordinates */
out vec3 V; /* view vector in texture-space coordinates */
in vec2 texcoord;
in vec4 vPosition;
uniform vec4 Normal;
uniform vec4 LightPosition;
uniform mat4 ModelView;
uniform mat4 Projection;
uniform mat4 NormalMatrix;
uniform vec3 objTangent; /* tangent vector in object coordinates */
out vec2 st;
void main()
{
mat3 NM3;
NM3[0][0] = NormalMatrix[0][0];
NM3[0][1] = NormalMatrix[0][1];
NM3[0][2] = NormalMatrix[0][2];
NM3[1][0] = NormalMatrix[1][0];
NM3[1][1] = NormalMatrix[1][1];
NM3[1][2] = NormalMatrix[1][2];
NM3[2][0] = NormalMatrix[2][0];
NM3[2][1] = NormalMatrix[2][1];
NM3[2][2] = NormalMatrix[2][2];
gl_Position = Projection*ModelView*vPosition;
st = texcoord;
vec3 eyePosition = vec3(ModelView*vPosition);
vec3 eyeLightPos = LightPosition.xyz;
/* normal, tangent and binormal in eye coordinates */
vec3 N = normalize(NM3*Normal.xyz);
vec3 T = normalize(NM3*objTangent);
vec3 B = cross(N, T);
/* light vector in texture space */
L.x = dot(T, eyeLightPos-eyePosition);
L.y = dot(B, eyeLightPos-eyePosition);
L.z = dot(N, eyeLightPos-eyePosition);
L = normalize(L);
/* view vector in texture space */
V.x = dot(T, -eyePosition);
V.y = dot(B, -eyePosition);
V.z = dot(N, -eyePosition);
V = normalize(V);
}
fshader73.glsl :
#version 150
in vec3 L;
in vec3 V;
uniform sampler2D texMap;
in vec2 st;
uniform vec4 DiffuseProduct;
out vec4 fColor;
void main()
{
vec4 N = texture2D(texMap, st);
vec3 NN = normalize(2.0*N.xyz-1.0);
vec3 LL = normalize(L);
float Kd = max(dot(NN.xyz, LL), 0.0);
fColor = Kd*DiffuseProduct;
}
修改:
根据Brett的评论,我用以下内容替换了glBindTexture(GL_TEXTURE_2D, 0)
- 仍然是一个空白的白色窗口:
GLuint texture;
glGenTextures( 1, &texture );
glBindTexture(GL_TEXTURE_2D, texture);
...
glActiveTexture(GL_TEXTURE0);
答案 0 :(得分:1)
我的评论超出了角色的限制,所以希望这值得回答。
我唯一能看到的问题可能是你的glUniformMatrix4fv
电话。根据{{3}},第二个参数将其描述为要更改的矩阵数。 3.2核心参考页面未在其网站上链接,因此我无法查找该特定上下文。因此对于glUniformMatrix4fv(projection_loc, 16, GL_TRUE, projection);
,它打算在一个名为“Projection”的数组中找到16个矩阵,但是你只定义了uniform mat4 Projection;
。这可能是也可能不是你问题的一部分,而且我甚至可能不正确,特别是如果这是其他人编译/使用的已知教程。
此外,glEnable(GL_TEXTURE_2D)不需要(OpenGl 4 language reference),其OpenGL上下文版本为3.2核心,在此设置:
glutInitContextVersion( 3, 2 );
glutInitContextProfile( GLUT_CORE_PROFILE );
如果编译器没有给您任何错误,请尝试在您认为可能有问题的行之后添加glGetError()
。返回值映射到OpenGL头文件中的枚举值(or even usable, i think?将列出它们),我认为文档也会列出它们。
除此之外,您可能只想检查“normals”三维数组是否按照您期望的方式在内存中进行布局,因为我从未尝试过手动构建数组以用作纹理自己(虽然图像基本上都是字节数据的字符串,所以在这种情况下我不知道它是怎么回事。)
希望这有助于您,或者至少指出您正确的方向。祝你好运。
编辑#1 :我意识到我对着色器检查的评论不是很完整,因为我没有提到一些API调用。这是一个例子:
char * dataBuffer;
struct _stat fileStat;
long fLen;
FILE * vSh;
FILE * fSh;
int desc;
GLint status;
GLint logLength;
GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
//errort = glGetError();
GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
GLuint program = glCreateProgram();
/*__________________________________________________*/
vSh = fopen("vShader.vSh", "r");
desc = _fileno(vSh);
_fstat(desc, &fileStat);
fLen = fileStat.st_size;
dataBuffer = (char *) calloc((fLen + 1), sizeof(char));
if (dataBuffer == NULL)
{
MessageBox(NULL, "Malloc failure: VS", "Create Program", MB_OK | MB_ICONINFORMATION);
return 1;
}
if(feof(vSh) == 0)
{
MessageBox(NULL, "Did not reach EoF for VS", "Create Program", MB_OK | MB_ICONINFORMATION);
return 2;
}
fclose(vSh);
glShaderSource(vShader, 1, &dataBuffer, NULL);
glCompileShader(vShader);
//Error checking
glGetShaderiv(vShader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &logLength);
char resultV[logLength+1];
glGetShaderInfoLog(vShader, logLength, NULL, resultV);
MessageBox(NULL, resultV, "Vertex Compile Error", MB_OK);
}
free(dataBuffer);
我获取着色器的方式并不是真正重要的部分,所以希望这并不会让你感到困惑。当谈到检查着色器是否存在错误时,标记为//Error checking
的部分就是我的意思。
答案 1 :(得分:0)
Alex我的朋友你很亲密!基本上,只有glUniform...
个glUniformMatrix...
来1
进行调用,需要{{1}}作为第二个参数。