2012-11-06 166 views
1

通过删除ComputePositonOffsets()和AdjustVertexData()方法,我可以显示一个三角形,但我添加了一些按钮功能来旋转它以查看屏幕中是否有其他位置,并且我无法弄清为什么它会产生黑屏。C++ OpenGL not rendering

#include <algorithm> 
#include <string> 
#include <vector> 
#include <stdio.h> 
#include <glload/gl_3_2_comp.h> 
#include <GL/freeglut.h> 

#define ARRAY_COUNT(array) (sizeof(array)/(sizeof(array[0]) * (sizeof(array) != sizeof(void*) || sizeof(array[0]) <= sizeof(void*)))) 
double rotate_y = 0; 
double rotate_x = 0; 

GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile) { 
    GLuint shader = glCreateShader(eShaderType); 
    const char *strFileData = strShaderFile.c_str(); 
    glShaderSource(shader, 1, &strFileData, NULL); 

    glCompileShader(shader); 

    GLint status; 
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 
    if (status == GL_FALSE) { 
     GLint infoLogLength; 
     glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); 

     GLchar *strInfoLog = new GLchar[infoLogLength + 1]; 
     glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog); 

     const char *strShaderType = NULL; 
     switch (eShaderType) { 
     case GL_VERTEX_SHADER: 
      strShaderType = "vertex"; 
      break; 
     case GL_GEOMETRY_SHADER: 
      strShaderType = "geometry"; 
      break; 
     case GL_FRAGMENT_SHADER: 
      strShaderType = "fragment"; 
      break; 
     } 

     fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType,strInfoLog); 
     delete[] strInfoLog; 
    } 

    return shader; 
} 

GLuint CreateProgram(const std::vector<GLuint> &shaderList) { 
    GLuint program = glCreateProgram(); 

    for (size_t iLoop = 0; iLoop < shaderList.size(); iLoop++) 
     glAttachShader(program, shaderList[iLoop]); 

    glLinkProgram(program); 

    GLint status; 
    glGetProgramiv(program, GL_LINK_STATUS, &status); 
    if (status == GL_FALSE) { 
     GLint infoLogLength; 
     glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); 

     GLchar *strInfoLog = new GLchar[infoLogLength + 1]; 
     glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog); 
     fprintf(stderr, "Linker failure: %s\n", strInfoLog); 
     delete[] strInfoLog; 
    } 

    for (size_t iLoop = 0; iLoop < shaderList.size(); iLoop++) 
     glDetachShader(program, shaderList[iLoop]); 

    return program; 
} 

GLuint theProgram; 

const std::string strVertexShader("#version 330\n" 
     "layout(location = 0) in vec4 position;\n" 
     "void main()\n" 
     "{\n" 
     " gl_Position = position;\n" 
     "}\n"); 

const std::string strFragmentShader("#version 330\n" 
     "out vec4 outputColor;\n" 
     "void main()\n" 
     "{\n" 
     " outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n" 
     "}\n"); 

void InitializeProgram() { 
    std::vector<GLuint> shaderList; 

    shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader)); 
    shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader)); 

    theProgram = CreateProgram(shaderList); 

    std::for_each(shaderList.begin(), shaderList.end(), glDeleteShader); 
} 

const float vertexPositions2[] = { 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 
     0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 
     0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 
     -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 
     -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 
     -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5 }; 

GLuint positionBufferObject; 
GLuint vao; 

void InitializeVertexBuffer() { 
    glGenBuffers(1, &positionBufferObject); 

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions2), vertexPositions2, 
      GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 

//Called after the window and OpenGL are initialized. Called exactly once, before the main loop. 
void init() { 
    InitializeProgram(); 
    InitializeVertexBuffer(); 

    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 
} 

void ComputePositionOffsets(float &fXOffset, float &fYOffset) { 
    const float fLoopDuration = 5.0f; 
    const float fScale = 3.14159f * 2.0f/fLoopDuration; 

    float fElapsedTime = glutGet(GLUT_ELAPSED_TIME)/1000.0f; 

    float fCurrTimeThroughLoop = fmodf(fElapsedTime, fLoopDuration); 

    fXOffset = cosf(fCurrTimeThroughLoop * fScale) * 0.5f; 
    fYOffset = sinf(fCurrTimeThroughLoop * fScale) * 0.5f; 
} 

void AdjustVertexData(float fXOffset, float fYOffset) { 

    std::vector<float> fNewData(ARRAY_COUNT(vertexPositions2)); 
    memcpy(&fNewData[0], vertexPositions2, sizeof(vertexPositions2)); 

    for (int iVertex = 0; iVertex < ARRAY_COUNT(vertexPositions2); iVertex += 
      4) { 
     fNewData[iVertex] += fXOffset; 
     fNewData[iVertex + 1] += fYOffset; 
    } 

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertexPositions2), &fNewData[0]); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

} 

//Called to update the display. 
//You should call glutSwapBuffers after all of your rendering to display what you rendered. 
//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function. 
void display() { 
    glUseProgram(theProgram); 
    float fXOffset = 0.0f, fYOffset = 0.0f; 
    ComputePositionOffsets(fXOffset, fYOffset); 
    AdjustVertexData(fXOffset, fYOffset); 
    //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glLoadIdentity(); 

    glRotatef(rotate_x, 1.0, 0.0, 0.0); 
    glRotatef(rotate_y, 0.0, 1.0, 0.0); 

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

    GLubyte indices[] = { 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 8, 9, 10, 10, 11, 
      8, 12, 13, 14, 14, 15, 12, 16, 17, 18, 18, 19, 16, 20, 21, 22, 22, 
      23, 20 }; // back 

    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices); 

    glDisableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    glFlush(); 
    glUseProgram(0); 
    glutSwapBuffers(); 
} 

//Called whenever the window is resized. The new window size is given, in pixels. 
//This is an opportunity to call glViewport or glScissor to keep up with the change in size. 
void reshape(int w, int h) { 
    glViewport(0, 0, (GLsizei) w, (GLsizei) h); 
} 

//Called whenever a key on the keyboard was pressed. 
//The key is given by the ''key'' parameter, which is in ASCII. 
//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to 
//exit the program. 
void keyboard(unsigned char key, int x, int y) { 
    switch (key) { 
    case 27: 
     glutLeaveMainLoop(); 
     return; 
    } 

    // Right arrow - increase rotation by 5 degree 
    if (key == GLUT_KEY_RIGHT) rotate_y += 5; 
    // Left arrow - decrease rotation by 5 degree 
    else if (key == GLUT_KEY_LEFT) rotate_y -= 5; 
    else if (key == GLUT_KEY_UP) rotate_x += 5; 
    else if (key == GLUT_KEY_DOWN) rotate_x -= 5; 

    // Request display update 
    glutPostRedisplay(); 
} 

unsigned int defaults(unsigned int displayMode, int &width, int &height) { 
    return displayMode; 
} 
+0

如果您希望格式正确,您应该用四个空格替换您的选项卡。 – dupersuper

+0

请仅发布您遇到问题的代码,并将它们组织在单独的代码块中,以便我们可以更轻松地缩小问题的范围 –

+0

如果您使用GL3,为什么要使用固定功能矩阵堆栈?这并不像你在某个时候拉开模型视图矩阵并将其固定在统一体上。甚至可以使用(已弃用的)GLSL内置插件!你只是......希望顶点着色器能以某种方式接收它。 – genpfault

回答

2
const float vertexPositions2[] = {0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5}; 

我猜是3D矢量组成一个立方体的列表,有24个(6个面* 4角)指数使用较低的倒在你的代码和所有值都看0.5或-0.5。但是,你告诉OpenGL,这是向量与4个componenents,而不是3列表:

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

这是相当不寻常的是第二个参数设置为4。如果你将它设置为3,OpenGL的将在填w组件为1给你。试试看。如果你这样做,我认为你会看到一个方块。

最重要的是,我没有在任何地方看到透视投影矩阵。如果你没有,你会得到一个二维投影,而不是一个3D。事情不会以你想要的方式出现。在实施旋转和四处移动之前,您会希望得到它。

下面的这些行对您的程序没有影响,它们不属于现代图形程序。他们改变了固定功能矩阵堆栈中的矩阵,您不会在你的着色器中使用矩阵(我认为不能,因为你使用的是GLSL 330)。你必须自己定义矩阵作为统一变量。

glLoadIdentity(); 

glRotatef(rotate_x, 1.0, 0.0, 0.0); 
glRotatef(rotate_y, 0.0, 1.0, 0.0);