2013-07-21 114 views
0

我終於設法讓代碼在Ubuntu上的QtCreator中編譯。但是,當我運行它時,它運行得非常快,窗口立即關閉。有一些警告,但我編譯時沒有錯誤。如何暫停這個opengl程序?

請教我如何查看程序是否實際崩潰或運行速度非常快。

下面是代碼:

這是主要的功能

// Two-Dimensional Sierpinski Gasket 
// Generated using randomly selected vertices and bisection 

#include "Angel.h" 

const int NumPoints = 5000; 

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

void 
init(void) 
{ 
    vec2 points[NumPoints]; 

    // Specifiy the vertices for a triangle 
    vec2 vertices[3] = { 
     vec2(-1.0, -1.0), vec2(0.0, 1.0), vec2(1.0, -1.0) 
    }; 

    // Select an arbitrary initial point inside of the triangle 
    points[0] = vec2(0.25, 0.50); 

    // compute and store N-1 new points 
    for (int i = 1; i < NumPoints; ++i) { 
     int j = rand() % 3; // pick a vertex at random 

     // Compute the point halfway between the selected vertex 
     // and the previous point 
     points[i] = (points[i - 1] + vertices[j])/2.0; 
    } 

    // Create a vertex array object 
    GLuint vao[1]; 
    glGenVertexArraysAPPLE(1, vao); 
    glBindVertexArrayAPPLE(vao[0]); 


    // Create and initialize a buffer object 
    GLuint buffer; 
    glGenBuffers(1, &buffer); 
    glBindBuffer(GL_ARRAY_BUFFER, buffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); 

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

    // Initialize the vertex position attribute from the vertex shader 
    GLuint loc = glGetAttribLocation(program, "vPosition"); 
    glEnableVertexAttribArray(loc); 
    glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, 
          BUFFER_OFFSET(0)); 

    glClearColor(1.0, 1.0, 1.0, 1.0); // white background 
} 

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

void 
display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT);  // clear the window 
    glDrawArrays(GL_POINTS, 0, NumPoints); // draw the points 
    glFlush(); 
} 

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

void 
keyboard(unsigned char key, int x, int y) 
{ 
    switch (key) { 
    case 033: 
     exit(EXIT_SUCCESS); 
     break; 
    } 
} 

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

int 
main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA); 
    glutInitWindowSize(512, 512); 

    glutCreateWindow("Sierpinski Gasket"); 

    init(); 

    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 

    glutMainLoop(); 
    return 0; 
} 

這是Angel.h文件:

////////////////////////////////////////////////////////////////////////////// 
// 
// --- Angel.h --- 
// 
// The main header file for all examples from Angel 6th Edition 
// 
////////////////////////////////////////////////////////////////////////////// 

#ifndef __ANGEL_H__ 
#define __ANGEL_H__ 

//---------------------------------------------------------------------------- 
// 
// --- Include system headers --- 
// 

#include <cmath> 
#include <iostream> 

// Define M_PI in the case it's not defined in the math header file 
#ifndef M_PI 
# define M_PI 3.14159265358979323846 
#endif 

//---------------------------------------------------------------------------- 
// 
// --- Include OpenGL header files and helpers --- 
// 
// The location of these files vary by operating system. We've included 
//  copies of open-soruce project headers in the "GL" directory local 
//  this this "include" directory. 
// 

#ifdef __APPLE__ // include Mac OS X verions of headers 
# include <OpenGL/OpenGL.h> 
# include <GLUT/glut.h> 
#else // non-Mac OS X operating systems 
# include <GL/glew.h> 
# include <GL/freeglut.h> 
# include <GL/freeglut_ext.h> 
#endif // __APPLE__ 

// Define a helpful macro for handling offsets into buffer objects 
#define BUFFER_OFFSET(offset) ((GLvoid*) (offset)) 

//---------------------------------------------------------------------------- 
// 
// --- Include our class libraries and constants --- 
// 

namespace Angel { 

// Helper function to load vertex and fragment shader files 
GLuint InitShader(const char* vertexShaderFile, 
      const char* fragmentShaderFile); 

// Defined constant for when numbers are too small to be used in the 
// denominator of a division operation. This is only used if the 
// DEBUG macro is defined. 
const GLfloat DivideByZeroTolerance = GLfloat(1.0e-07); 

// Degrees-to-radians constant 
const GLfloat DegreesToRadians = M_PI/180.0; 

} // namespace Angel 

#include "vec.h" 
#include "mat.h" 
//#include "CheckError.h" 

// #define Print(x) do { std::cerr << #x " = " << (x) << std::endl; } while(0) 

// Globally use our namespace in our example programs. 
using namespace Angel; 

#endif // __ANGEL_H__ 

這裏是Initshader.h包括:

#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"); 

    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 
+1

替換呼叫glutInitDisplayMode(GLUT_RGBA)main()即使運行速度很快,也會顯示一個窗口,直到您通過關閉或按下鍵0x33退出。嘗試在調試器中運行 –

回答

1

此pr圖形是以某種方式寫成的,即只有在出現故障的情況下才會自行終止。它會在發生這種情況時打印出錯信息。我建議你從終端運行它,這樣你就可以看到輸出(即不要雙擊生成的二進制文件)。

+0

謝謝,會這樣做datenwolf – georgelappies

0

我懷疑程序因爲運行速度太快,因爲顯示功能忽略了限制GL渲染。

void 
display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT);  // clear the window 
    glDrawArrays(GL_POINTS, 0, NumPoints); // draw the points 
    glFlush(); 
} 

一個OpenGL程序必須調整自己,否則它將盡快通過渲染操作。節流的典型方法是調用GLX/EGL/glutSwapBuffers,其執行以下操作:

  1. 隱刷新GL管道(即glFlush)。
  2. 向窗口管理器發送消息以顯示您所呈現的內容。
  3. 如果窗口管理器檢測到應用程序有太多未完成的swapBuffer請求,那麼應用程序將,直到未完成的請求得到滿足。通常情況下,窗口管理器可以在屏幕的每個垂直回掃中滿足不超過一次swapBuffer請求,通常爲每秒60次。

因此,您需要用glutSwapBuffers替換對glFlush的呼叫。這將導致display()每秒被調用次數不超過60次,如果其他配置正確的話,則不會超過60次。

小心:只有當您的GL應用程序是雙緩衝時,glutSwapBuffers纔會執行我所描述的操作。當應用程序初始化GL時,應始終請求進行雙緩衝,除非它有充分的理由。您的應用程序不請求進行雙緩衝。您需要使用`glutIinit