我一直无法使用带有一些输入进行平移和旋转的着色器绘制一个简单的顶点指定(盒状)茶壶模型。我一遍又一遍地检查了我的gl代码和矩阵(-z上的对象位置,原点上的相机等),并且不明白为什么我仍然只是得到一个空白屏幕。为了保持代码简短,我只是为我的模型的基本多维数据集添加代码(一旦我至少得到它我会没事的)。
namespace TeapotViewer{
class TeapotViewer{
private:
void intitialize();
void draw();
void reshape(int h, int w);
void keyHandle(unsigned char key, int x, int y);
void initCamera();
void reset();
void changeAxis();
void rotateOnAxis(float rot);
int createCube(int i);
public:
};
}
#include "TeapotViewer.h"
using namespace glm;
const int S_WIDTH = 800;
const int S_HEIGHT = 600;
const float FOV = 100;
const float P_NEAR = 0.2;
const float P_FAR = 20.0;
const float SPOUT_WIDTH = 0.025;
const float HANDLE_WIDTH = 0.15;
const float ZERO = 0.0;
const int numberOfVertices = 104;
const int noCubeSide = 10;
const int noCubeFace = 4;
const int noLine = 2;
mat4 modelxViewMatrix, projMatrix, viewMatrix, rotationMatrix, translationMatrix;
vec3 rotationAxis;
vec3 teapotPosition = vec3(0.0, 0.0,-3.0);
const vec3 cameraPosition = vec3(0.0, 0.0, 0.0);
const vec3 cameraDirection = vec3(0.0, 0.0, -1.0);
const vec3 cameraUp = vec3(0.0, 1.0, 0.0);
vec4 vertices[numberOfVertices];
GLuint refVertexArray;
GLuint refVertexBuffer;
GLuint refUniformModelxView;
GLuint refUniformProjection;
const vec4 body[] = {
vec4(-1.0,-1.0, 1.0, 1.0), vec4(-1.0, 1.0, 1.0, 1.0),
vec4( 1.0,-1.0, 1.0, 1.0), vec4( 1.0, 1.0, 1.0, 1.0),
vec4( 1.0,-1.0,-1.0, 1.0), vec4( 1.0, 1.0,-1.0, 1.0),
vec4(-1.0,-1.0,-1.0, 1.0), vec4(-1.0, 1.0,-1.0, 1.0)
};
const vec3 xAxis = vec3(1.0, 0.0, 0.0);
const vec3 yAxis = vec3(0.0, 1.0, 0.0);
const vec3 zAxis = vec3(0.0, 0.0, 1.0);
// draw callback
void draw(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
translationMatrix = translate(mat4(), teapotPosition);
modelxViewMatrix = viewMatrix*translationMatrix*rotationMatrix;
glUniformMatrix4fv(refUniformModelxView, 1, &modelxViewMatrix[0][0]);
glUniformMatrix4fv(refUniformProjection, 1, &projMatrix[0][0]);
void drawTeapot();
glutSwapBuffers();
}
void drawTeapot(){
int bufferIndex = 0;
// draw cube
glDrawArrays(GL_TRIANGLE_STRIP, bufferIndex, noCubeSide);
bufferIndex += noCubeSide;
glDrawArrays(GL_TRIANGLE_STRIP, bufferIndex, noCubeFace);
bufferIndex += noCubeFace;
glDrawArrays(GL_TRIANGLE_STRIP, bufferIndex, noCubeFace);
bufferIndex += noCubeFace;
// draw the axis of rotation
if (rotationAxis == xAxis){
glDrawArrays(GL_LINES, bufferIndex, noLine);
bufferIndex += noLine;
}
if (rotationAxis == yAxis){
bufferIndex += noLine;
glDrawArrays(GL_LINES, bufferIndex, noLine);
bufferIndex += noLine;
}
if (rotationAxis == zAxis){
bufferIndex += noLine*2;
glDrawArrays(GL_LINES, bufferIndex, noLine);
bufferIndex += noLine;
}
}
// reset back to the start
void reset(){
teapotPosition = vec3(0.0, 0.0,-3.0);
rotationMatrix = mat4();
}
void changeAxis(){
if(rotationAxis == xAxis)
rotationAxis = yAxis;
else
if(rotationAxis == yAxis)
rotationAxis = zAxis;
else
rotationAxis = xAxis;
}
void rotateOnAxis(float rot){
rotationMatrix = rotate(rotationMatrix, rot, rotationAxis);
}
// handle keypress
void keyHandle(unsigned char key, int x, int y){
switch(key){
case 033:
exit(EXIT_SUCCESS);
break;
case '0':
reset();
break;
case 'a':
teapotPosition = teapotPosition + vec3(-0.1, 0.0, 0.0);
break;
case 'd':
teapotPosition = teapotPosition + vec3(0.1, 0.0, 0.0);
break;
case 'w':
teapotPosition = teapotPosition + vec3(0.0, 0.1, 0.0);
break;
case 's':
teapotPosition = teapotPosition + vec3(0.0, -0.1, 0.0);
break;
case 'q':
teapotPosition = teapotPosition + vec3(0.0, 0.0, -0.1);
break;
case 'e':
teapotPosition = teapotPosition + vec3(0.0, 0.0, 0.1);
break;
case 'j':
changeAxis();
break;
case 'k':
rotateOnAxis(-5.0);
break;
case 'l':
rotateOnAxis(5.0);
break;
}
glutPostRedisplay();
}
void reshape(int h, int w){
glViewport(0, 0, h, w);
}
void initCamera(){
viewMatrix = lookAt(cameraDirection, cameraPosition, cameraUp);
projMatrix = perspective(FOV, (float)S_WIDTH/(float)S_HEIGHT, P_NEAR, P_FAR);
reset();
}
int createCube(int i){
// sides of the cube
vertices[i++] = body[0];
vertices[i++] = body[1];
vertices[i++] = body[2];
vertices[i++] = body[3];
vertices[i++] = body[4];
vertices[i++] = body[5];
vertices[i++] = body[6];
vertices[i++] = body[7];
vertices[i++] = body[0];
vertices[i++] = body[1];
// top
vertices[i++] = body[0];
vertices[i++] = body[2];
vertices[i++] = body[4];
vertices[i++] = body[6];
//bottom
vertices[i++] = body[1];
vertices[i++] = body[3];
vertices[i++] = body[5];
vertices[i++] = body[7];
std::cout << i << '\n';
return i;
}
int createAxes(int i){
// X axis
vertices[i++] = vec4( 2.0, 0.0, 0.0, 1.0);
vertices[i++] = vec4(-2.0, 0.0, 0.0, 1.0);
// Y axis
vertices[i++] = vec4( 0.0, 2.0, 0.0, 1.0);
vertices[i++] = vec4( 0.0,-2.0, 0.0, 1.0);
// Z axis
vertices[i++] = vec4( 0.0, 0.0, 2.0, 1.0);
vertices[i++] = vec4( 0.0, 0.0,-2.0, 1.0);
std::cout << i << '\n';
return i;
}
// Initialize
void initialize(){
// generate vertex data
int i = 0;
i = createCube(i);
i = createAxes(i);
if(i != numberOfVertices){
std::cout << "Error creating vertex data: check vertex count\n";
std::exit(0);
}
// set
initCamera();
// load shader and activate shader
GLuint refVertexShader = Angel::InitShader("Vertex_Shader.glsl", "Fragment_Shader.glsl");
glUseProgram(refVertexShader);
// create and activate a new vertex array object (vao)
glGenVertexArrays(1, &refVertexArray);
glBindVertexArray(refVertexArray);
// create and activate a new buffer array object in the vao
glGenBuffers(1, &refVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, refVertexBuffer);
// load vertex data into the buffer array
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// load postion pipeline variable
GLuint refVec4Position = glGetAttribLocation(refVertexShader, "Position");
glEnableVertexAttribArray(refVec4Position);
glVertexAttribPointer(refVec4Position, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
// get pointers for uniform variables in shader program
refUniformModelxView = glGetUniformLocation(refVertexShader, "ModelxView");
refUniformProjection = glGetUniformLocation(refVertexShader, "Projection");
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearColor(0.0, 0.0, 0.0, 1.0);
}
int main(int argc, char* argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(S_WIDTH, S_HEIGHT );
glutCreateWindow("TeapotViewer");
glewInit();
initialize();
glutDisplayFunc(draw);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyHandle);
glutMainLoop();
return 0;
}
顶点着色器
#version 150
uniform mat4 ModelxView;
uniform mat4 Projection;
in vec4 Position;
void main()
{
gl_Position = Projection*ModelxView*Position;
}
片段着色器
#version 150
out vec4 fColor;
void main()
{
fColor = vec4(1.0, 1.0, 0.0, 1.0);
}
答案 0 :(得分:0)
不确定这一点,因为我不确定Angel ::幕后发生了什么,但是从片段着色器输出fColor
是否正确?我认为在glsl 150中它需要特殊变量gl_FragColor
,除非Angel做了一些特定的事情来缓解这种情况。
我看了一会儿,但我没有看到任何会导致问题的东西。不幸的是,我认为如果你真的陷入困境,你可能不得不开始编写一个更简单的例子(没有函数,只是通过渲染三角形直接初始化)。
还要确保每个draw()循环至少调用一次glGetError,以确保它没有遗漏任何内容。 Angel会在链接/编译失败时抛出异常吗?
答案 1 :(得分:0)
viewMatrix = lookAt(cameraDirection, cameraPosition, cameraUp);
这与gluLookAt相同吗?在该函数中,原型是(position, lookAtPoint, cameraUp)
,这是你所拥有的。