PDA

View Full Version : opengl render on tpanel



serkank
24-04-2014, 09:40 PM
Hi, i am trying to make a video processing and video effect program
i need get render on a tpanel , i searched lot of page and tutorial about opengl.


1) there is a Topenglcontrol component imgu & testopenglcontext1 in lazarus. i tryed understand how they work. i thought i understand them but if i try to add texture a simple plane its not work...


i found some tutorial in Nehe about texture render. if i use glut window its work but if i add it with topenglcontrol its not work.
i dont know what is different each other.. i was copy all procedure Draw , init , loadtexture .. but its didnt worked...


2 i saw another sample with sdl .. its use sdl_putenv() ;
SDL_putenv( 'SDL_VIDEODRIVER=windib' );
EnvVal := 'SDL_WINDOWID=' + inttostr(Integer(Panel1.Handle));


but there is something worng.. my render not on panel1 its out on anyempty are without any gui..




there is not enought simple tutorial on internet... i dont know where i do wrong..

AthenaOfDelphi
24-04-2014, 10:30 PM
Hi serkank,

Could you post more of your code please? Personally I don't use Lazarus so I'm not in a position to help, but your post would benefit greatly from more of the source code you have tried.

serkank
25-04-2014, 04:01 AM
i maked sample code from jediopengl sdl -> testwin tutorial
its create render area outof form .. not in panel1

unit project1unit1;


{$MODE Delphi}


interface


{$IFDEF VER140}
{$DEFINE CLX}
{$ELSE}
{$DEFINE VCL}
{$ENDIF}


uses
Classes,
{$IFDEF VCL}
LCLIntf, LCLType, LMessages,
Messages,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
ComCtrls,
Buttons,
ExtDlgs,
Spin,
{$ENDIF}
{$IFDEF CLX}
QT,
QGraphics,
QControls,
QForms,
QDialogs,
QStdCtrls,
QExtCtrls,
QComCtrls,
QButtons,
Types,
{$ENDIF}
SysUtils,
sdl,OpenGLContext,GL,GLU,glext,logger,
fastevents in 'fastevents.pas';




type


{ TForm1 }


TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);


procedure OpenGLControl1Paint(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;








const
// screen width, height, and bit depth
SCREEN_WIDTH = 640;
SCREEN_HEIGHT = 480;
SCREEN_BPP = 16;


var
Form1: TForm1;
// This is our SDL surface
surface : PSDL_Surface;


xrot : GLfloat; // X Rotation ( NEW )
yrot : GLfloat; // Y Rotation ( NEW )
zrot : GLfloat ; // Z Rotation ( NEW )


texture : GLuint; // Storage For One Texture ( NEW )


//Status indicator
Status : Boolean = false;




implementation




{$IFDEF Win32}
{$R *.lfm}
{$ENDIF}


{$IFDEF Linux}
{$R *.xfm}
{$ENDIF}


{ TForm1 }












// The main drawing function.
procedure DrawGLScene;
begin
// Clear The Screen And The Depth Buffer
glClear( GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT );


// Move Into The Screen 5 Units
glLoadIdentity;
glTranslatef( 0.0, 0.0, -5.0 );


glRotatef( xrot, 1.0, 0.0, 0.0 ); // Rotate On The X Axis
glRotatef( yrot, 0.0, 1.0, 0.0 ); // Rotate On The Y Axis
glRotatef( zrot, 0.0, 0.0, 1.0 ); // Rotate On The Z Axis


// Select Our Texture
glBindTexture( GL_TEXTURE_2D, texture );


// NOTE:
// * The x coordinates of the glTexCoord2f function need to inverted
// * for SDL because of the way SDL_LoadBmp loads the data. So where
// * in the tutorial it has glTexCoord2f( 1.0, 0.0 ); it should
// * now read glTexCoord2f( 0.0, 0.0 );
glBindTexture( GL_TEXTURE_2D, texture );
glBegin( GL_QUADS );
// Front Face
// Bottom Left Of The Texture and Quad
glTexCoord2f( 0.0, 1.0 );
glVertex3f( -1.0, -1.0, 1.0 );
// Bottom Right Of The Texture and Quad
glTexCoord2f( 1.0, 1.0 );
glVertex3f( 1.0, -1.0, 1.0 );
// Top Right Of The Texture and Quad
glTexCoord2f( 1.0, 0.0 );
glVertex3f( 1.0, 1.0, 1.0 );
// Top Left Of The Texture and Quad
glTexCoord2f( 0.0, 0.0 );
glVertex3f( -1.0, 1.0, 1.0 );


// Back Face
// Bottom Right Of The Texture and Quad
glTexCoord2f( 0.0, 0.0 );
glVertex3f( -1.0, -1.0, -1.0 );
// Top Right Of The Texture and Quad
glTexCoord2f( 0.0, 1.0 );
glVertex3f( -1.0, 1.0, -1.0 );
// Top Left Of The Texture and Quad
glTexCoord2f( 1.0, 1.0 );
glVertex3f( 1.0, 1.0, -1.0 );
// Bottom Left Of The Texture and Quad
glTexCoord2f( 1.0, 0.0 );
glVertex3f( 1.0, -1.0, -1.0 );


// Top Face
// Top Left Of The Texture and Quad
glTexCoord2f( 1.0, 1.0 );
glVertex3f( -1.0, 1.0, -1.0 );
// Bottom Left Of The Texture and Quad
glTexCoord2f( 1.0, 0.0 );
glVertex3f( -1.0, 1.0, 1.0 );
// Bottom Right Of The Texture and Quad
glTexCoord2f( 0.0, 0.0 );
glVertex3f( 1.0, 1.0, 1.0 );
// Top Right Of The Texture and Quad
glTexCoord2f( 0.0, 1.0 );
glVertex3f( 1.0, 1.0, -1.0 );


// Bottom Face
// Top Right Of The Texture and Quad
glTexCoord2f( 0.0, 1.0 );
glVertex3f( -1.0, -1.0, -1.0 );
// Top Left Of The Texture and Quad
glTexCoord2f( 1.0, 1.0 );
glVertex3f( 1.0, -1.0, -1.0 );
// Bottom Left Of The Texture and Quad
glTexCoord2f( 1.0, 0.0 );
glVertex3f( 1.0, -1.0, 1.0 );
// Bottom Right Of The Texture and Quad
glTexCoord2f( 0.0, 0.0 );
glVertex3f( -1.0, -1.0, 1.0 );


// Right face
// Bottom Right Of The Texture and Quad
glTexCoord2f( 0.0, 0.0 );
glVertex3f( 1.0, -1.0, -1.0 );
// Top Right Of The Texture and Quad
glTexCoord2f( 0.0, 1.0 );
glVertex3f( 1.0, 1.0, -1.0 );
// Top Left Of The Texture and Quad
glTexCoord2f( 1.0, 1.0 );
glVertex3f( 1.0, 1.0, 1.0 );
// Bottom Left Of The Texture and Quad
glTexCoord2f( 1.0, 0.0 );
glVertex3f( 1.0, -1.0, 1.0 );


// Left Face
// Bottom Left Of The Texture and Quad
glTexCoord2f( 1.0, 0.0 );
glVertex3f( -1.0, -1.0, -1.0 );
// Bottom Right Of The Texture and Quad
glTexCoord2f( 0.0, 0.0 );
glVertex3f( -1.0, -1.0, 1.0 );
// Top Right Of The Texture and Quad
glTexCoord2f( 0.0, 1.0 );
glVertex3f( -1.0, 1.0, 1.0 );
// Top Left Of The Texture and Quad
glTexCoord2f( 1.0, 1.0 );
glVertex3f( -1.0, 1.0, -1.0 );
glEnd;


// swap buffers to display, since we're double buffered.
SDL_GL_SwapBuffers;


xrot := xrot + 0.3; // X Axis Rotation
yrot := yrot + 0.2; // Y Axis Rotation
zrot := zrot + 0.4; // Z Axis Rotation


end;


procedure TerminateApplication;
begin
SDL_QUIT;
Halt(0);
end;
// function to reset our viewport after a window resize
function ResizeWindow( width : integer; height : integer ) : Boolean;
begin
// Protect against a divide by zero
if ( height = 0 ) then
height := 1;


// Setup our viewport.
glViewport( 0, 0, width, height );


// change to the projection matrix and set our viewing volume.
glMatrixMode( GL_PROJECTION );
glLoadIdentity;


// Set our perspective
gluPerspective( 45.0, width / height, 0.1, 100.0 );


// Make sure we're changing the model view and not the projection
glMatrixMode( GL_MODELVIEW );


// Reset The View
glLoadIdentity;


result := true;
end;


// function to handle key press events
procedure HandleKeyPress( keysym : PSDL_keysym );
begin
case keysym^.sym of
SDLK_ESCAPE :
// ESC key was pressed
TerminateApplication;


SDLK_RETURN :
begin
if (keysym^.Modifier and KMOD_ALT <> 0) then
begin
{* Alt+Enter key was pressed
* this toggles fullscreen mode
*}
SDL_WM_ToggleFullScreen( surface );
end;
end;
end;
end;
// Load Bitmaps And Convert To Textures
function LoadGLTextures : Boolean;
var
// Create storage space for the texture
TextureImage: PSDL_Surface;
begin
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
TextureImage := SDL_LoadBMP('ashwood.bmp');
if ( TextureImage <> nil ) then
begin
// Set the status to true
Status := true;


// Create Texture
glGenTextures( 1, @texture );
// Typical Texture Generation Using Data From The Bitmap
glBindTexture( GL_TEXTURE_2D, texture );


// Generate The Texture
glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage^.w,
TextureImage^.h, 0, GL_BGR,
GL_UNSIGNED_BYTE, TextureImage^.pixels );


// Linear Filtering
// scale linearly when image bigger than texture
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
// scale linearly when image smaller than texture
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
end
else
begin
Log.LogError( Format( 'Could not Load Image : %s', [SDL_GetError] ),
'LoadGLTextures' );
TerminateApplication;
end;


// Free up any memory we may have used
if ( TextureImage <> nil ) then
SDL_FreeSurface( TextureImage );


result := Status;
end;




function InitGL : Boolean;
begin
// Load in the texture
if ( not LoadGLTextures ) then
begin
result := false;
exit;
end;


// Enable Texture Mapping ( NEW )
glEnable( GL_TEXTURE_2D );


// Enable smooth shading
glShadeModel( GL_SMOOTH );


// Set the background black
glClearColor( 0.0, 0.0, 0.0, 0.0 );


// Depth buffer setup
glClearDepth( 1.0 );


// Enables Depth Testing
glEnable( GL_DEPTH_TEST );


// The Type Of Depth Test To Do
glDepthFunc( GL_LEQUAL );


// Really Nice Perspective Calculations
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );


result := true;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
Done : Boolean;
event : TSDL_Event;
videoflags : Uint32;
videoInfo : PSDL_VideoInfo;
EnvVal:string;
hwnd:integer;
black: Uint32;
pixels: PUint8;
i:integer;
label
tekrar;
begin
hwnd:=0;


tekrar:
hwnd:=panel1.Handle;
if hwnd = 0 then goto tekrar;




{$IFDEF VCL}
SDL_putenv( 'SDL_VIDEODRIVER=windib' );
EnvVal := 'SDL_WINDOWID=' + inttostr(Integer(Panel1.Handle));
{$ENDIF}


{$IFDEF CLX}
// EnvVal := 'SDL_WINDOWID=' + inttostr(QWidget_WinId(Panel1.Handle));
{$ENDIF}




// Initialize SDL
if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) then
begin
Log.LogError( Format( 'Could not initialize SDL : %s', [SDL_GetError] ),
'Main' );
TerminateApplication;
end;


// Fetch the video info
videoInfo := SDL_GetVideoInfo;


if ( videoInfo = nil ) then
begin
Log.LogError( Format( 'Video query failed : %s', [SDL_GetError] ),
'Main' );
TerminateApplication;
end;


// the flags to pass to SDL_SetVideoMode
videoFlags := SDL_OPENGL; // Enable OpenGL in SDL
videoFlags := videoFlags or SDL_DOUBLEBUF; // Enable double buffering
videoFlags := videoFlags or SDL_HWPALETTE; // Store the palette in hardware
videoflags := videoflags or SDL_NOFRAME;


// This checks to see if surfaces can be stored in memory
if ( videoInfo^.hw_available <> 0 ) then
videoFlags := videoFlags or SDL_HWSURFACE
else
videoFlags := videoFlags or SDL_SWSURFACE;


// This checks if hardware blits can be done * /
if ( videoInfo^.blit_hw <> 0 ) then
videoFlags := videoFlags or SDL_HWACCEL;


// Set the OpenGL Attributes
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );


// Set the title bar in environments that support it
SDL_WM_SetCaption( 'Jeff Molofee''s OpenGL Code Tutorial 6 using JEDI-SDL', nil );


videoflags := videoFlags or SDL_RESIZABLE; // Enable window resizing
//SDL_SetVideoMode(seWidth.Value, seHeight.Value, seBPP.Value,
// video_flags);
surface := SDL_SetVideoMode( panel1.Width, panel1.Height, SCREEN_BPP, videoflags );
if ( surface = nil ) then
begin
Log.LogError( Format( 'Unable to create OpenGL screen : %s', [SDL_GetError]
),
'Main' );
TerminateApplication;
end;


// Loop, drawing and checking events
InitGL;
ReSizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT );


Done := False;
while ( not Done ) do
begin
// This could go in a separate function
while ( SDL_PollEvent( @event ) = 1 ) do
begin
case event.type_ of
SDL_QUITEV :
begin
Done := true;
end;


SDL_KEYDOWN :
begin
// handle key presses
HandleKeyPress( @event.key.keysym );
end;


SDL_VIDEORESIZE :
begin
surface := SDL_SetVideoMode( event.resize.w, event.resize.h, SCREEN_BPP, videoflags );
if ( surface = nil ) then
begin
Log.LogError( Format( 'Could not get a surface after resize : %s', [SDL_GetError] ),
'Main' );
TerminateApplication;
end;


InitGL;
ResizeWindow( event.resize.w, event.resize.h );
end;
end;
end;
// draw the scene
DrawGLScene;
end;
TerminateApplication;








end;






procedure TForm1.OpenGLControl1Paint(Sender: TObject);
begin
// DrawGLScene;
// openglcontrol1.SwapBuffers;
end;






end.

serkank
25-04-2014, 04:01 AM
This is openglcontrol code
i only add imaginggltexture from another code this code work with glut window but not work with openglcontrol
i tryed to texture Red side of cube but cube only colored there isnt texture


{
************************************************** ***************************
* *
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
* for details about the copyright. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
************************************************** ***************************


Author: Mattias Gaertner


}
unit MainUnit;


{$mode objfpc}{$H+}


interface


uses
Classes, SysUtils, LCLProc, LResources, Forms, Controls, Graphics, Dialogs,
OpenGLContext, GL, GLU,imagingopengl;


type


{ TForm1 }


TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure OpenGLControl1Paint(Sender: TObject);
procedure OpenGLControl1Resize(Sender: TObject);
procedure OnAppIdle(Sender: TObject; var Done: Boolean);
private
public
cube_rotationx: GLFloat;
cube_rotationy: GLFloat;
cube_rotationz: GLFloat;
OpenGLControl1: TOpenGLControl;
end;


var
Form1: TForm1;
tex:gluint;
implementation


{$R *.lfm}


{ TForm1 }


procedure TForm1.FormCreate(Sender: TObject);
begin
OpenGLControl1:=TOpenGLControl.Create(Self);


tex:=LoadGLTextureFromFile('c:\ashwood.jpg');
with OpenGLControl1 do begin
Name:='OpenGLControl1';
Align:=alClient;
Parent:=Self;
OnPaint:=@OpenGLControl1Paint;
OnResize:=@OpenGLControl1Resize;
AutoResizeViewport:=true;
end;

Application.AddOnIdleHandler(@OnAppIdle);
end;


procedure TForm1.OpenGLControl1Paint(Sender: TObject);
var
Speed: Double;
begin
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, double(width) / height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


glTranslatef(0.0, 0.0,-6.0);
glRotatef(cube_rotationx, cube_rotationy, cube_rotationz, 0.0);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glColor3f(0.0,1.0,0.0); // Set The Color To Green
glVertex3f( 1.0, 1.0,-1.0); // Top Right Of The Quad (Top)
glVertex3f(-1.0, 1.0,-1.0); // Top Left Of The Quad (Top)
glVertex3f(-1.0, 1.0, 1.0); // Bottom Left Of The Quad (Top)
glVertex3f( 1.0, 1.0, 1.0); // Bottom Right Of The Quad (Top)
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.5,0.0); // Set The Color To Orange
glVertex3f( 1.0,-1.0, 1.0); // Top Right Of The Quad (Bottom)
glVertex3f(-1.0,-1.0, 1.0); // Top Left Of The Quad (Bottom)
glVertex3f(-1.0,-1.0,-1.0); // Bottom Left Of The Quad (Bottom)
glVertex3f( 1.0,-1.0,-1.0); // Bottom Right Of The Quad (Bottom)
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,0.0); // Set The Color To Red
glTexCoord2f(1, 0); glVertex3f( 1.0, 1.0, 1.0); // Top Right Of The Quad (Front)
glTexCoord2f(0, 0); glVertex3f(-1.0, 1.0, 1.0); // Top Left Of The Quad (Front)
glTexCoord2f(0, 1); glVertex3f(-1.0,-1.0, 1.0); // Bottom Left Of The Quad (Front)
glTexCoord2f(1, 1); glVertex3f( 1.0,-1.0, 1.0); // Bottom Right Of The Quad (Front)
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,1.0,0.0); // Set The Color To Yellow
glVertex3f( 1.0,-1.0,-1.0); // Bottom Left Of The Quad (Back)
glVertex3f(-1.0,-1.0,-1.0); // Bottom Right Of The Quad (Back)
glVertex3f(-1.0, 1.0,-1.0); // Top Right Of The Quad (Back)
glVertex3f( 1.0, 1.0,-1.0); // Top Left Of The Quad (Back)
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.0,1.0); // Set The Color To Blue
glVertex3f(-1.0, 1.0, 1.0); // Top Right Of The Quad (Left)
glVertex3f(-1.0, 1.0,-1.0); // Top Left Of The Quad (Left)
glVertex3f(-1.0,-1.0,-1.0); // Bottom Left Of The Quad (Left)
glVertex3f(-1.0,-1.0, 1.0); // Bottom Right Of The Quad (Left)
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,1.0); // Set The Color To Violet
glVertex3f( 1.0, 1.0,-1.0); // Top Right Of The Quad (Right)
glVertex3f( 1.0, 1.0, 1.0); // Top Left Of The Quad (Right)
glVertex3f( 1.0,-1.0, 1.0); // Bottom Left Of The Quad (Right)
glVertex3f( 1.0,-1.0,-1.0); // Bottom Right Of The Quad (Right)
glEnd();
glDisable(GL_TEXTURE_2D);
Speed := double(OpenGLControl1.FrameDiffTimeInMSecs)/10;


cube_rotationx += 5.15 * Speed;
cube_rotationy += 5.15 * Speed;
cube_rotationz += 20.0 * Speed;


OpenGLControl1.SwapBuffers;
end;


procedure TForm1.OpenGLControl1Resize(Sender: TObject);
begin
if OpenGLControl1.Height <= 0 then exit;
// the viewport is automatically resized by the TOpenGLControl
// you can disable it (OpenGLControl1.AutoResizeViewport:=false)
// and do something yourself here
end;


procedure TForm1.OnAppIdle(Sender: TObject; var Done: Boolean);
begin
Done:=false;
//DebugLn(['TForm1.OnAppIdle ']);
OpenGLControl1.Invalidate;
end;


end.

AthenaOfDelphi
25-04-2014, 10:43 AM
Could someone who knows Lazarus possible help serkank?

It's way out of my comfort zone so I'm not able to assist with this question.

Thanks

SilverWarior
25-04-2014, 05:36 PM
tekrar:
hwnd:=panel1.Handle;
if hwnd = 0 then goto tekrar;

WOW! Last time I have seen GOTO commands in pascal based program was when I was checking an old TurboPascal code. :)
BTW That is a potential infinite loop. A realy BAD thing.
I think you can throw that code out as it serves no purpose. What it will do is cause your application to hang if hwnd would equal 0.

I also see you are using JEDI OpenGL components. If I'm not mistaken they relly on SDL1 and are no longer maintained. I'm not sure about that.
Maybe you should think of using latest SDL library which bases on SDL2.
You might wanna check this site: http://www.freepascal-meets-sdl.net/

serkank
25-04-2014, 06:22 PM
yes i know. i only try to test, its work on debugger i can stop it on debugger. This code only for test. i use goto label because its short code ...
first time i downloaded SDL2 library but SDL + SDL2 havent much tutorial and example, if i try sdl 1.2 code width sdl2 lot of sdl function change width sdl2...

any body know how can i get opengl render on tpanel ?

serkank
27-04-2014, 07:16 AM
i found problem.

if texture load before openglcontrol.makecurent or openglcontrol.onpaint function , openglcontrol cant show texture.
thank you for your interest and answer..