Autor Beitrag
Ulrich 68
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Fr 03.03.06 21:13 
Hallo, ich bin noch Open GL-Anfänger. Bei meinen ersten Versuchen mit Texturen läuft jedes mal der Speicher voll. Wie kann ich das verhindern? Hab mal den Quellcode angehängt.
MfG
Ulrich


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
Unit Unit1;

interface

uses
  Windows, Forms, OpenGL, Classes, ExtCtrls, Messages, glaux, Dialogs;

type
  TMainForm = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure FormResize(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Inittextures;

  private
    RC    : HGLRC;
    Angle : Integer;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
  end;

var
  MainForm: TMainForm;
  tex: gluint;

implementation

PROCEDURE glGenTextures(n: GLsizei; VAR textures: GLuint); STDCALL; EXTERNAL opengl32;
PROCEDURE glBindTexture(target: GLenum; texture: GLuint);  STDCALL; EXTERNAL opengl32;





{$R *.DFM}

procedure TMainForm.FormCreate(Sender: TObject);
begin // initialize OpenGL and create a context for rendering
  RC:=CreateRenderingContext(Canvas.Handle,[opDoubleBuffered],32,0);

end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin // destroy the rendering context
  DestroyRenderingContext(RC);
end;

procedure TMainForm.FormPaint(Sender: TObject);
begin // draw somthing useful
  ActivateRenderingContext(Canvas.Handle,RC); // make context drawable
  glClearColor(0,0.5,0.5,1); // background color of the context
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // clear background and depth buffer
  glMatrixMode(GL_MODELVIEW); // activate the transformation matrix
  glLoadIdentity;             // set it to initial state
  gluLookAt(0,0,6,0,0,-10,0,1,0); // set up a viewer position and view point
  //glTranslatef(0,0,0);
  glRotatef(0.5*Angle,0,1,0); // do rotation around axis (x:0;y:1;z:0)
  glRotatef(30,1,0,0);      // do another rotation for better view (accumulates to first rot.)
  glScalef(1,sin(Angle*pi/90),1); // simulate bumping
  glEnable(GL_DEPTH_TEST); // enable depth testing


  glenable(gl_texture_2d);
  inittextures;

 glBindTexture(GL_TEXTURE_2D, tex);

 glBegin(GL_TRIANGLE_FAN); // draw a tetrahedron
   //glColor3f(1,0,1);       // color of the upper vertex
   gltexcoord2f(0,0);
   glVertex3f(0,0,0);      // coordinates of the upper vertex (= center of the fan)
   gltexcoord2f(0,1);
   glVertex3f(0,1,0);     // coordinates of the left-front vertex
   gltexcoord2f(1,0.5);
   glVertex3f(1,0,0);      // right-front
 glEnd;
                    // finish triangle fan


  glBegin(GL_TRIANGLE_FAN); // draw a tetrahedron
    //glColor3f(0.2,0,0);       // color of the upper vertex
    gltexcoord2f(0,0);
    glVertex3f(0,0,0);      // coordinates of the upper vertex (= center of the fan)
    gltexcoord2f(0,1);
    glVertex3f(0,1,0);     // coordinates of the left-front vertex
    gltexcoord2f(1,0.5);
    glVertex3f(0,0,1);      // right-front
  glEnd;


  SwapBuffers(Canvas.Handle); // copy back buffer to front
  DeactivateRenderingContext; // release control of context
end;

procedure TMainForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #27 then Application.Terminate;
end;

procedure TMainForm.FormResize(Sender: TObject);
begin // handle form resizing (viewport must be adjusted)
  wglMakeCurrent(Canvas.handle,RC); // another way to make context drawable
  glViewport(0,0,Width,Height); // specify a viewport (has not necessarily to be the entire window)
  glMatrixMode(GL_PROJECTION); // activate projection matrix
  glLoadIdentity;              // set initial state
  gluPerspective(35,Width/Height,1,100); // specify perspective params (see OpenGL.hlp)
  wglMakeCurrent(0,0); // another way to release control of context
  Refresh;             // cause redraw
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
begin // do some animation
  Inc(Angle,1);
  if Angle >= 360 then Angle:=0;
  Repaint;
end;

procedure TMainForm.Inittextures;

var textur: PTAUX_RGBImageRec;

begin
  textur := auxDIBImageLoadA('HIMMEL.bmp');
  glGenTextures(1, tex);
  glBindTexture(GL_TEXTURE_2D, tex);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_linear);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_linear);
  glTexImage2D(GL_TEXTURE_2D, 0, 3, textur^.sizeX, textur^.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, textur^.data);
end;

procedure TMainForm.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin // avoid clearing the background (causes flickering and speed penalty)
  Message.Result:=1;
end;

end.


Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt
deJosHL
Hält's aus hier
Beiträge: 1

WIN XP
D7 Enterprise
BeitragVerfasst: Fr 03.03.06 21:46 
Titel: Re:
Hi,
du solltest Texturen nur einmal beim Programmstart laden, danach kannst du sie immer noch verwenden, ohne sie erneut zu laden.

Joshua
Phobeus
ontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1280

Linux (FC6), WinXP Pro (Box)
D6 Pers, D7 Pro, FPC 2.x
BeitragVerfasst: Sa 04.03.06 11:27 
Das ist zwar wahr, sollte jedoch eigentlich eher zu einer unsaglich schlechten Performance führen und nicht zu Speicherproblemen. Nichts desto trotz, solltest Du dies korrigieren und auch folgendes ins Auge fassen: Der RC wird normalerweise nicht bei jedem Renderdurchgann neu angefordert. Normalerweise wird zu Beginn im Rahmen der Initalisierung ein RC angefordert und dies wieder frei gegeben. Das die Texturen innerhalb eines RCs verwaltet werden und Du beute ständig neu lädst, führt dies vermutlich dazu, dass Du deinen Speicher vollschaufelst. das OnPaint zum Zeichnen zu verwenden ist generell in Ordnung, gerade bei sehr "bewegten" Szenen bietet sich jedoch eher das OnIdyle an, selbst wenn dies die CPU Auslastung hochjagt. Des Weiteren läßt sich nur massiv davor warnen, die GLAUX noch als zeitgemäße Bibliothek anzusehen. Diese ist als Hoffnungslos veraltet anzusehen und es existieren zahlreich neuere und bessere TexturLoader, sowie Bibliotheken.

_________________
"Menschen sterben nicht wenn man sie zu Grabe trägt, sondern wenn sie ihre Träume verlieren..."
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Sa 04.03.06 16:37 
Hi,

user profile iconPhobeus hat folgendes geschrieben:
Das ist zwar wahr, sollte jedoch eigentlich eher zu einer unsaglich schlechten Performance führen und nicht zu Speicherproblemen.


jaein... er gibt ja nirgendwo mal ne textur frei = er erstellt ständig neue texturen ohne ende.. irgendwann ist halt der Grafikkarten speicher voll und dann auch irgendwann der normale ram.. :)

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
Ulrich 68 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 04.03.06 18:50 
Mein Speicherproblem konnte ich jetzt dank eurer Tipps lösen. Vielen Dank dafür. Noch ne kleine Frage, wie kann ich eine Textur wiederholend mehrfach auf eine Fläche auftragen. Vielleicht könntet ihr mir anhand des Programms erklären, wo der Syntax wie geändert werden muß.
PS: Welches Buch habt ihr beim Einstieg verwendet. Ich hab mir das Buch Programmieren mit OpenGl von Ute Claussen zugelegt. Das Buch ist mir aber für den Anfang etwas zu wissenschaftlich.
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Sa 04.03.06 19:28 
Hi,

um eine textur zu wiederholen mußt du einfach die TexturCoordinaten anpassen.
Der wert den du bei glTexCoord2f übergibst geht standardmäßig von 0..1. (U = 0 und V = 0 ist die linke obere ecke der textur, U = 1 und V = 1 ist rechts unten, U = 1 und V = 0 ist rechts oben etc..)
Wenn du jetzt die textur einfach 3x wiederholen möchtest gibst du statt "1" einfach "3" an.. :)

Bedingt dadurch das ich Bücher nicht mag und dementsprechend auch keine habe kann ich dir da keine empfehlung geben.. gelernt habe ich OpenGL hauptsächlich durch DelphiGL.com (Forum und Tutorials).. :)

Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
Ulrich 68 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 05.03.06 09:11 
Danke für eure Antworten. Evtl. hat ja noch jemand ne Buchempfehlung für Einsteiger.
MfG
Ulrich
Ulrich 68 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 05.03.06 09:23 
Kann ich die Textur auch je nach größe der Fläche unterschiedlich oft auftragen, ohne vorher die Anzahl festzulegen? Also die Textur soll nicht gezogen werden sondern wie mehrere Tapeten nebeneinander geklebt werden?
Phobeus
ontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1280

Linux (FC6), WinXP Pro (Box)
D6 Pers, D7 Pro, FPC 2.x
BeitragVerfasst: So 05.03.06 12:00 
Wirkliche Buchempfehlungen kann ich nicht geben. Meist sind diese eher veraltet oder sehr speziell und daher nicht für Einsteiger geeignet. Würde daher lieber auf deutsch- und englischsprachige Online-Lektüre zurückgreifen (die Polen haben auch viel, aber...).

Sofern ich deine Frage richtig verstehe: Nein, dass ist nicht möglich. Beim texturieren mußt Du wissen, wo welcher Bereich und wie oft angezeigt werden soll, da OpenGL keine Glaskugel besitzt um zu erraten, wie Du gerne die Textur darauf sehen möchtest. In der Praxis ist dies jedoch kein Problem, da Du ja auch die Positionen der Eckpunkte übergibst und diese leicht der Texturierung via Variablen abpassen kannst. Entschließt Du Dich dynamisch im Programm, dass ein Quad von 0,0 bis 10,1 gehen soll, so kann man leicht ausrechnen wie das Mapping erfolgen muss, damit alles schön paßt. In diesem Fall würdest Du die U-Koordinate auf 10 setzen. Im Prinzip also genauso wie auch Aya es schon erklärte.

_________________
"Menschen sterben nicht wenn man sie zu Grabe trägt, sondern wenn sie ihre Träume verlieren..."
Ulrich 68 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 05.03.06 13:18 
OK Danke für die Tips, dann werd ich wohl meinen STL2OpenGL Konverter mit etwas mehr intelligenz verpassen.