Пример OpenGL Vala GTK3 - PullRequest
       61

Пример OpenGL Vala GTK3

0 голосов
/ 10 октября 2018

Я пытаюсь переписать этот первый пример треугольника в vala, и мне не удается это до сих пор:

public class MyApp : Gtk.Application {

  private MyAppWindow? myAppWindow;
  public string appName;

  public MyApp () {
    Object (
      application_id: "com.github.myusername.myreponame",
      flags: ApplicationFlags.FLAGS_NONE
    );
    appName = "My App";
  }

  protected override void activate () {
    myAppWindow = new MyAppWindow (this);
    add_window (myAppWindow);
    myAppWindow.show_all ();
  }

  public static int main (string[] args) {
    var myApp = new MyApp ();
    return myApp.run (args);
  }
}


public class MyAppWindow : Gtk.ApplicationWindow {

  public MyApp myApp { get; construct set; }

  private Gtk.HeaderBar headerBar;
  private Gtk.GLArea glArea;
  private Gtk.Frame frame;

  // An array of 3 vectors which represents 3 vertices
  private GLES2.GLfloat[] g_vertex_buffer_data = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,  1.0f, 0.0f };

  // This will identify our vertex buffer
  private GLES2.GLuint vertexbuffer;

  private GLES2.GLuint programID;

  public MyAppWindow(MyApp myApp) {
    Object(myApp: myApp);
  }

  construct {
    set_default_size (480, 640);

    headerBar = new Gtk.HeaderBar ();
    headerBar.set_show_close_button (true);
    headerBar.set_title (myApp.appName);

    glArea = new Gtk.GLArea ();
    glArea.margin = 10;

    frame = new Gtk.Frame ("GL Area");
    frame.margin = 10;

    // Generate 1 buffer, put the resulting identifier in vertexbuffer
    GLES2.glGenBuffers(1, &vertexbuffer);

    // The following commands will talk about our 'vertexbuffer' buffer
    GLES2.glBindBuffer(GLES2.GL_ARRAY_BUFFER, vertexbuffer);

    // Give our vertices to OpenGL.
    GLES2.glBufferData(GLES2.GL_ARRAY_BUFFER, 9*4, g_vertex_buffer_data, GLES2.GL_STATIC_DRAW);

    LoadShaders (out programID);

    GLES2.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);

    glArea.render.connect (() => {

      GLES2.glClear (GLES2.GL_COLOR_BUFFER_BIT | GLES2.GL_DEPTH_BUFFER_BIT);

      GLES2.glUseProgram(programID);

      // 1st attribute buffer : vertices
      GLES2.glEnableVertexAttribArray(0);
      GLES2.glBindBuffer(GLES2.GL_ARRAY_BUFFER, vertexbuffer);
      GLES2.glVertexAttribPointer(
        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
        3,                  // size
        GLES2.GL_FLOAT,     // type
        GLES2.GL_FALSE,     // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
      );
      // Draw the triangle !
      GLES2.glDrawArrays(GLES2.GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
      GLES2.glDisableVertexAttribArray(0);

      GLES2.glFlush ();

      return true;
    });

    set_titlebar (headerBar);
    frame.add (glArea);
    add (frame);
  }


  void LoadShaders(out GLES2.GLuint ProgramID) {

    GLES2.GLint Result = GLES2.GL_FALSE;
    int InfoLogLength = 0;

    // create vertex shader
    GLES2.GLuint VertexShaderID = GLES2.glCreateShader(GLES2.GL_VERTEX_SHADER);
    string VertexSource = "#version 330 core
                          layout(location = 0) in vec3 vertexPosition_modelspace;
                          void main(){
                            gl_Position.xyz = vertexPosition_modelspace;
                            gl_Position.w = 1.0;
                          }";
    // compile vertex shader
    GLES2.glShaderSource(VertexShaderID, 1, out VertexSource, null);
    GLES2.glCompileShader(VertexShaderID);
    // check vertex shader
    GLES2.glGetShaderiv(VertexShaderID, GLES2.GL_COMPILE_STATUS, &Result);
    GLES2.glGetShaderiv(VertexShaderID, GLES2.GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ) {
      GLES2.GLchar[InfoLogLength+1] VertexShaderErrorMessage;
      GLES2.glGetShaderInfoLog(VertexShaderID, InfoLogLength, null, &VertexShaderErrorMessage[0]);
    }

    // create fragment shader
    GLES2.GLuint FragmentShaderID = GLES2.glCreateShader(GLES2.GL_FRAGMENT_SHADER);
    string FragmentSource = "#version 330 core
                            out vec3 color;
                            void main(){
                              color = vec3(1,0,0);
                            }";
    // compile fragment shader
    GLES2.glShaderSource(FragmentShaderID, 1, out FragmentSource, null);
    GLES2.glCompileShader(FragmentShaderID);
    // check fragment shader
    GLES2.glGetShaderiv(FragmentShaderID, GLES2.GL_COMPILE_STATUS, &Result);
    GLES2.glGetShaderiv(FragmentShaderID, GLES2.GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ){
        GLES2.GLchar[InfoLogLength+1] FragmentShaderErrorMessage;
        GLES2.glGetShaderInfoLog(FragmentShaderID, InfoLogLength, null, &FragmentShaderErrorMessage[0]);
    }


    ProgramID = GLES2.glCreateProgram();
    GLES2.glAttachShader(ProgramID, VertexShaderID);
    GLES2.glAttachShader(ProgramID, FragmentShaderID);
    GLES2.glLinkProgram(ProgramID);
    // Check the program
    GLES2.glGetProgramiv(ProgramID, GLES2.GL_LINK_STATUS, &Result);
    GLES2.glGetProgramiv(ProgramID, GLES2.GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ){
      GLES2.GLchar[InfoLogLength+1] ProgramErrorMessage;
      GLES2.glGetProgramInfoLog(ProgramID, InfoLogLength, null, &ProgramErrorMessage[0]);
    }

    GLES2.glDetachShader(ProgramID, VertexShaderID);
    GLES2.glDetachShader(ProgramID, FragmentShaderID);

    GLES2.glDeleteShader(VertexShaderID);
    GLES2.glDeleteShader(FragmentShaderID);

  }

}

Я компилирую это с valac --pkg gtk+-3.0 --vapidir=. --pkg gles2 valagl.vala -o valagl --Xcc=-lGLESv2.У меня есть gles2.vapi в той же папке.

  1. В glShaderSource есть 2 [-Wincompatible-pointer-types] предупреждений для исходной строки шейдера во время компиляции.Это может быть, где проблема, но я не знаю, как ее исправить.

expected ‘const GLchar * const* {aka const char * const*}’ but argument is of type ‘gchar ** {aka char **}

В примере есть шаг glfwSwapBuffers().Я не уверен, что нужно делать там.Я использую GLES2.glFlush (), но я не понимаю, как он соединяется с GLArea, который я только что создал.

Также valadoc продолжает примерно on_realize сигнал, где шейдерынужно инициализировать, но я не могу найти сигнал on_realize вообще


Как нарисовать простой треугольник в окне GTK3 с помощью GLES2?


Программа запускается и показывает черный GLArea.Единственное, что работает, это цвет этой области, я могу изменить цвет, изменив GLES2.glClearColor (0.0f, 0.0f, 0.0f, 0.0f)

Black GLArea

...