2013-07-21 2 views
0

Наконец-то мне удалось получить код для компиляции в QtCreator на Ubuntu. Однако, когда я запускаю его, он работает так быстро, и окно немедленно закрывается. Есть некоторые предупреждения, но никаких ошибок при компиляции.Как приостановить эту программу 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

Даже если он работает быстро, окно будет отображаться до тех пор, пока вы не закроете его, не закроя его, или не нажмете клавишу 0x33. попробуйте запустить в отладчике –

ответ

1

Этот пр. ogram записывается таким образом, что он будет завершаться на свой счет только в случае сбоя. Когда это произойдет, оно выведет сообщение об ошибке. Я предлагаю вам запустить его с терминала, чтобы вы могли видеть результат (т. Е. Не просто дважды щелкните полученный двоичный файл).

+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 в секунду.

Таким образом, вам необходимо заменить звонок на glFlush на glutSwapBuffers. Это приведет к тому, что display() получит вызов не более 60 раз в секунду, если все остальное, если оно настроено правильно.

ВНИМАНИЕ: glutSwapBuffers будут делать то, что я описал, только если ваше приложение GL является двойным буфером. Когда приложение инициализирует GL, он всегда должен запрашивать двойную буферизацию, если у нее нет веской причины. Приложение не запрашивает двойную буферизацию. Вам необходимо заменить вызов на glutInitDisplayMode(GLUT_RGBA) в main() с помощью `glutIinit

Смежные вопросы