簡體   English   中英

GtkGLArea清除背景但不繪制

[英]GtkGLArea clears background but does not draw

我一直在編寫一個簡單的GTK +應用程序,並且剛剛開始進行圖形化開發。 我知道這可能不是一個很好的起點,直接跳入3D渲染,但是我之前做過很少的事情,並且使用Glade並閱讀了大量文檔取得了巨大成功,我認為這並不難整合兩者-我猜錯了。 當前的問題是glDrawArrays似乎無法正常工作。 我看着這個問題 ,不幸的是,它沒有幫助我。 我再次遵循了OpenGL上的一些教程 ,也沒有遵循GtkGLArea上的這個教程

誰能指出我在這個方向上的正確方向? 我不確定從這里去哪里。

相關代碼如下:

#include "RenderingManager.hpp"

RenderingManager::RenderingManager()  {
  ///GTK+ Setup///
  std::cout << "starting render constructor" << std::endl;
  glArea = GTK_GL_AREA(gtk_gl_area_new());
  std::cout << "got new glarea" << std::endl;
  g_signal_connect(GTK_WIDGET(glArea), "render", G_CALLBACK(signal_render), this);
  g_signal_connect(GTK_WIDGET(glArea), "realize", G_CALLBACK(signal_realize), this);
  g_signal_connect(GTK_WIDGET(glArea), "unrealize", G_CALLBACK(signal_unrealize), this);
  gtk_widget_show(GTK_WIDGET(glArea));
  ///Get Shaders///
  // vshader.open("vertex.shader");
  // fshader.open("fragment.shader");

  std::cout << "finished render constructor" << std::endl;
}

void RenderingManager::onRender() {
    // Dark blue background
    glClearColor(0.1f, 0.0f, 0.1f, 0.0f);
    draw_triangle();
    glFlush();
}
void RenderingManager::initBuffers () {
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

  glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

}

void RenderingManager::loadShaders()  {
  // Read the Vertex Shader code from the file
    std::ifstream VertexShaderStream("vertex.shader", std::ios::in);
    if(VertexShaderStream.is_open()){
        std::string Line = "";
        while(getline(VertexShaderStream, Line))
            vshader += "\n" + Line;
        VertexShaderStream.close();
    }

    // Read the Fragment Shader code from the file
    std::ifstream FragmentShaderStream("fragment.shader", std::ios::in);
    if(FragmentShaderStream.is_open()){
        std::string Line = "";
        while(getline(FragmentShaderStream, Line))
            fshader += "\n" + Line;
        FragmentShaderStream.close();
    }

  GLuint vsh, fsh;
  vsh = glCreateShader(GL_VERTEX_SHADER);
  fsh = glCreateShader(GL_FRAGMENT_SHADER);
  vshp = vshader.data();
  fshp = fshader.data();
  // vshp = vshader.get().c_str();
  // fshp = fshader.get().c_str();
  // vshader.get(vshp);
  // fshader.get(fshp);
  printf("%s\n%s\n", vshp, fshp);
  glShaderSource(vsh, 1, &vshp, NULL);
  glShaderSource(fsh, 1, &fshp, NULL);

  glCompileShader(vsh);
  glCompileShader(fsh);

  shaderProgramID = glCreateProgram();
  glAttachShader(shaderProgramID, vsh);
  glAttachShader(shaderProgramID, fsh);
  glLinkProgram(shaderProgramID);

  GLint Result = GL_FALSE;
  int InfoLogLength;
  // Check Vertex Shader
    glGetShaderiv(vsh, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(vsh, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ){
        char* VertexShaderErrorMessage = new char[InfoLogLength+1];
        glGetShaderInfoLog(vsh, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
        printf("%s\n", &VertexShaderErrorMessage[0]);
    }
  // Check Fragment Shader
    glGetShaderiv(fsh, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(fsh, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ){
        char* FragmentShaderErrorMessage = new char[InfoLogLength+1];
        glGetShaderInfoLog(fsh, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
        printf("%s\n", &FragmentShaderErrorMessage[0]);
    }
}
void RenderingManager::onActivate() {

  // We need to make the context current if we want to
  // call GL API
  gtk_gl_area_make_current (glArea);

  glewExperimental = GL_TRUE;
  glewInit();

  loadShaders();
  initBuffers();

}
void RenderingManager::signal_render(GtkGLArea *a, gpointer *user_data) {
  reinterpret_cast<RenderingManager*>(user_data)->onRender();

}
void RenderingManager::signal_realize(GtkGLArea *a, gpointer *user_data)  {
  reinterpret_cast<RenderingManager*>(user_data)->onActivate();

}
void RenderingManager::signal_unrealize(GtkGLArea *a, gpointer *user_data)  {
    //Don't do this
    //reinterpret_cast<RenderingManager*>(user_data)->~RenderingManager();
}
void RenderingManager::draw_triangle()  {
  // Clear the screen
        glClear( GL_COLOR_BUFFER_BIT );

        // Use our shader
        glUseProgram(shaderProgramID);

        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glVertexAttribPointer(
            0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            0,                  // stride
            (void*)0            // array buffer offset
        );

        // Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

        glDisableVertexAttribArray(0);

}
GtkGLArea *RenderingManager::expose()  {
  //yikes
  return glArea;
}

RenderingManager::~RenderingManager() {
  glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);
    glDeleteProgram(shaderProgramID);
  std::cout << "GL Resources deleted." << std::endl;
}

由於X11的異步特性(Gtk +使用它),無法在實現窗口之前(與X11建立連接)創建gl上下文。

在signal_realize()中創建gl-context,並在繪制之前使其為當前狀態,這應該通過處理信號expose_event (gtk + 2)或draw (gtk + 3)來完成

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM