Arrays zuweisen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Arrays zuweisen

Beitrag von Mathias »

Ich gucke mal in die Glaskugel.

Ich denke du hast so etwas, oder ähnliches in deinem Code.

Code: Alles auswählen

glBufferData(GL_ARRAY_BUFFER, sizeof(aCube), @aCube, GL_STATIC_DRAW);


Wen es so ist, versuch mal :

Code: Alles auswählen

glBufferData(GL_ARRAY_BUFFER, SizeOf(GLfloat) * Length(TVertexArr), Pointer(aCube), GL_STATIC_DRAW);


Der Name TVertexArr ist schlecht gewählt, ich würde es durch TFace oder TArea ersetzen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Arrays zuweisen

Beitrag von Hartkern »

Danke...habs probiert, jedoch werden von sagenhaften 3 Vertexe im dynamischen Array nur 2 verwendet obwohl alle 3 im Array sich befinden...jedoch egal was ich probiert hab, eine Koordinate (die letzte) bekommt immer!!!! ihren Punkt bei 0,0,0..

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Arrays zuweisen

Beitrag von Mathias »

Poste doch mal deinen gesamten Code als Anhang, dann sieht man einiges mehr. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Arrays zuweisen

Beitrag von Hartkern »

tataaaa!!

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, OpenGLContext, Forms, Controls, Graphics,
  Dialogs, ExtCtrls, dglOpenGL, ComCtrls, StdCtrls;
 
type
  TVertex3f = array[0..2] of GLfloat;
 
type
 
  TFace = array[0..2] of TVertex3f;
 
type
  TVB = record
    VAO,
    VBO: GLuint;
  end;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
    aCube : array of TFace;  //dynamische Länge
    VBaCube : TVB;
    MatrixID : glInt;
  public
    { public declarations }
    ProgramID: GLuint;
    OpenGLControl1 : TOpenGLControl;
    procedure InitScene;
    procedure RenderScene;
    Procedure Test;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
  function Initshader(VertexDatei, FragmentDatei: string): GLuint;
  var
    StringList: TStringList;
    Str: ansistring;
 
    ProgramObject: GLhandle;
    VertexShaderObject: GLhandle;
    FragmentShaderObject: GLhandle;
 
    ErrorStatus :ByteBool;
    InfoLogLength: integer;
 
  begin
    StringList := TStringList.Create;
    ProgramObject := glCreateProgram();
 
    // Vertex - Shader
 
    VertexShaderObject := glCreateShader(GL_VERTEX_SHADER);
    StringList.LoadFromFile(VertexDatei);
    Str := StringList.Text;
    glShaderSource(VertexShaderObject, 1, @Str, nil);
    glCompileShader(VertexShaderObject);
    glAttachShader(ProgramObject, VertexShaderObject);
 
    // Check  Shader
 
    glGetShaderiv(VertexShaderObject, GL_COMPILE_STATUS, @ErrorStatus);
    if ErrorStatus = GL_FALSE then begin
      glGetShaderiv(VertexShaderObject, GL_INFO_LOG_LENGTH, @InfoLogLength);
      SetLength(Str, InfoLogLength);
      glGetShaderInfoLog(VertexShaderObject, InfoLogLength, @InfoLogLength, @Str[1]);
      Application.MessageBox(PChar(Str), 'OpenGL Vertex Fehler', 48);
      Halt;
    end;
 
    glDeleteShader(VertexShaderObject);
 
    // Fragment - Shader
 
    FragmentShaderObject := glCreateShader(GL_FRAGMENT_SHADER);
    StringList.LoadFromFile(FragmentDatei);
    Str := StringList.Text;
    glShaderSource(FragmentShaderObject, 1, @Str, nil);
    glCompileShader(FragmentShaderObject);
    glAttachShader(ProgramObject, FragmentShaderObject);
 
    // Check  Shader
 
    glGetShaderiv(FragmentShaderObject, GL_COMPILE_STATUS, @ErrorStatus);
    if ErrorStatus = GL_FALSE then begin
      glGetShaderiv(FragmentShaderObject, GL_INFO_LOG_LENGTH, @InfoLogLength);
      SetLength(Str, InfoLogLength);
      glGetShaderInfoLog(FragmentShaderObject, InfoLogLength, @InfoLogLength, @Str[1]);
      Application.MessageBox(PChar(Str), 'OpenGL Fragment Fehler', 48);
      Halt;
    end;
 
    glDeleteShader(FragmentShaderObject);
 
    glLinkProgram(ProgramObject);
 
    // Check  Link
    glGetProgramiv(ProgramObject, GL_LINK_STATUS, @ErrorStatus);
    if ErrorStatus = GL_FALSE then begin
      glGetProgramiv(ProgramObject, GL_INFO_LOG_LENGTH, @InfoLogLength);
      SetLength(Str, InfoLogLength);
      glGetProgramInfoLog(ProgramObject, InfoLogLength, @InfoLogLength, @Str[1]);
      Application.MessageBox(PChar(Str), 'OpenGL ShaderLink Fehler', 48);
      Halt;
    end;
 
    Result := ProgramObject;
    FreeAndNil(StringList);
  end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  InitOpenGL;
     Form1.Height:=600;
     Form1.Width:=800;
   OpenGLControl1 := TOpenGLControl.Create(Self);
   with OpenGLControl1 do begin
     OpenGLMajorVersion := 3;     // OpenGL 3.3 erzwingen
     OpenGLMinorVersion := 3;
     Parent := Self;
     Align := alClient;
     MakeCurrent;
     AutoResizeViewport := True// Ersetzt glViewport
   end;
  ReadExtensions;
  ReadImplementationProperties;
 
  InitScene;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  glDeleteVertexArrays(1, @VBaCube.VAO);
  glDeleteBuffers(1, @VBaCube.VBO);
  glDeleteShader(ProgramID);
  OpenGLControl1.Free;
end;
 
procedure TForm1.FormPaint(Sender: TObject);
begin
 
  RenderScene;
end;
 
procedure TForm1.FormResize(Sender: TObject);
begin
   glClearColor(1.0, 0.5, 1.0, 1.0);
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  RenderScene;
end;
 
procedure TForm1.InitScene;
begin
  ProgramID := InitShader('VertexShader.txt', 'FragmentShader.txt');
  glUseProgram(programID);
// Dreieck
  glGenBuffers(1, @VBaCube.VBO);
  glGenVertexArrays(1, @VBaCube.VAO);
  glBindVertexArray(VBaCube.VAO);
  glBindBuffer(GL_ARRAY_BUFFER, VBaCube.VBO);
 
end;
 
procedure TForm1.RenderScene;
begin
  glClear(GL_COLOR_BUFFER_BIT);
  // Zeichen Dreieck
  test;
 
  OpenGLControl1.SwapBuffers;
end;
 
 
procedure TForm1.Test;
begin
  // Zeichen Dreieck
  setlength(aCube,2);      //Vertexarray
  aCube[0,0,0] :=0.5;      //1. V+ertex    jupp
  aCube[0,0,1] :=0.5;
  aCube[0,0,2] :=0.5;
 
  aCube[0,2,0] :=-0.5;      //2. Vertex    jupp
  aCube[0,2,1] :=0.5;
  aCube[0,2,2] := 0.5;
 
  aCube[0,1,0] :=0.5;      //3. Vertex
  aCube[0,1,1] :=-0.5;
  aCube[0,1,2] :=0.5;
  //2. Dreieck
  aCube[1,0,0] :=-1.0;      //1. V+ertex    jupp
  aCube[1,0,1] :=-1.0;
  aCube[1,0,2] :=1.0;
 
  aCube[1,2,0] :=1.0;      //2. Vertex    jupp
  aCube[1,2,1] :=1.0;
  aCube[1,2,2] :=1.0;
 
  aCube[1,1,0] :=1.5;      //3. Vertex
  aCube[1,1,1] :=-1.5;
  aCube[1,1,2] :=1.0;
 
  // upload daten ans VBO
  glBufferData(GL_ARRAY_BUFFER, (sizeof(aCube))* (Length(TFace)) , pointer(aCube), GL_STATIC_DRAW); //hier gibts problem
 
  glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, nil);
  glEnableVertexAttribArray(0);
  glBindVertexArray(VBaCube.VAO);
  glDrawArrays(GL_TRIANGLES,0,Length(aCube) *3  );
 
end;
end.   

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Arrays zuweisen

Beitrag von Mathias »

Ich denke du hast nicht begriffen, um was es bei OpenGL 3.3 geht.
Die Koordinaten, welche du in die Procedure Test lädst kommen in Initscene.

In RenderScene wird nur noch die VAO gebunden und anschliessen mit glDrawArray gezeichnet.

Mit anderen Worten, der Sinn an der ganzen Sache ist, das man die Vertex-Daten in den Speicher der Grafikkarte lädt.
Und der Karte anschliessend der Befehl gibt, alles zu zeichnen.


Im Anhang nochmals der komplette Code, so wie es sein soll.

Die Daten-Zuweisung zu aCube kommt ganz am Anfang in InitScene.

Bei glBufferData muss noch das @ durch Pointer ersetzt werden, so wie im folgender Zeile.

Code: Alles auswählen

glBufferData(GL_ARRAY_BUFFER, (Lenght(aCube))* (SizeOf(TFace)) , pointer(aCube), GL_STATIC_DRAW);

Du hast noch Length und SizeOf vertauscht, habe ich aber korrigiert.
Dateianhänge
Tutorial 01-3 - Quad and Triangle - Color - Shader.zip
(127.9 KiB) 59-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Arrays zuweisen

Beitrag von Hartkern »

Verstanden hab ich es schon, jedoch wenn ich das Mesh im VBO während der Laufzeit verändere, muss ich es ja neu füllen können?

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Arrays zuweisen

Beitrag von Mathias »

jedoch wenn ich das Mesh im VBO während der Laufzeit verändere, muss ich es ja neu füllen können?

Guck dir mal ein Games an, da werden alle Mesh generiert und in den VRAM geladen.
Dann werden die Mesh nur noch mit Matrixen bewegt.


Wen ein neuer Level kommt, wird alles angehalten, dann alles wider frei gegeben und anschliessend alles neu mit InitScene geladen.
In einem OBJ-Loader funktioniert das selbe in Grün.

Ich denke kaum, das du animierte Charaktere programmieren willst, so wie in einem aktuellen Ego-Shooter.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten