Skip to main content
gamedev.net
🔒 Locked

problems with render to texture

Started by SkyRanger 9 replies 1.5k views
Original Post
SkyRanger
SkyRanger
Hi to all. I have project on SF.net http://sky3d.sf.net and now try to make remote cameras in my 3d engine. I have multiple cameras support and now want to make screens for thouse cameras. I mean, when camera inactive, content of it shown inside small texture :) I nearly comple it, but i have strange problem when try to render in texture. Here code:

procedure TGLCameraManager.RenderCams(IsMouseLook:Boolean;
                                   MouseSens:GLDouble;
                                   CurrCamera:Integer);
var
  I:Integer;
  CurrCam : TGLCamera;
  Tmp : Integer;
  PO : PPyObject;
begin
  for I:=0 to FCount-1 do
  begin
  glPushMatrix();
  glLoadIdentity();
    CurrCam:=TGLCamera(FCollection);
    if CurrCam.CameraID <> CurrCamera then
      if CurrCam.CameraTex<>'' then
      begin
        CurrCam.Move(IsMouseLook, MouseSens);
        TextureManager.RenderTexture(CurrCam.CameraTex);
        if CurrCam.CamPyClass <> nil then
        begin
          pyCallObjMethod(CurrCam.CamPyClass,'_OnMove');
        end;
      end
      else
      else
        Tmp:=I;
    glPopMatrix();
 end;

 glLoadIdentity();
 CurrCam:=TGLCamera(FCollection[Tmp]);
  CurrCam.Move(IsMouseLook, MouseSens);
  if CurrCam.CamPyClass <> nil then
    pyCallObjMethod(CurrCam.CamPyClass,'_OnMove');
  CurrCam:=nil;
end;
It first checks and render cameras if need and then make final move for current camera. But when i run it draw CURRENT screen on texture. I mean it must render to texture content of camera_1 and if camera 1 active no content (WELL, It do last thing only correctly). So what i doing wrong? All work fine except this thing :(
MARS_999
MARS_999
You need to post your RTT code... I am not sure but is that code Delphi?
SkyRanger
SkyRanger
Yes. It is Delphi. I use Delphi 6 Personal
Here it is:
procedure TGLCamera.Move(IsMouseLook:Boolean; MouseSens:GLDouble);var  CursorPos     : TPoint;  MaxX, MaxY : Integer;  CurPosT : TGLPoint;  P:PPyObject;begin  MaxX:=GetSystemMetrics(SM_CXSCREEN);  MaxY:=GetSystemMetrics(SM_CYSCREEN);  if FCamPyClass<>nil then  begin    FCameraPos.X:=pyGetDoubleFromObject(FCamPyClass,'_Pos_x','TGLCamera.Move');    FCameraPos.Y:=pyGetDoubleFromObject(FCamPyClass,'_Pos_y','TGLCamera.Move');    FCameraPos.Z:=pyGetDoubleFromObject(FCamPyClass,'_Pos_z','TGLCamera.Move');    FLatitude:=pyGetDoubleFromObject(FCamPyClass,'_Pos_lat','TGLCamera.Move');    FLongitude:=pyGetDoubleFromObject(FCamPyClass,'_Pos_lon','TGLCamera.Move');    CameraID:=pyGetLongFromObject(FCamPyClass,'_Cam_Id','TGLCamera.Move');  end;  GetCursorPos(CursorPos);  if FLatitude>360 then    FLatitude:=FLatitude-360;  if FLatitude<0 then    FLatitude:=360;  if FLongitude>360 then    FLongitude:=FLongitude-360;  if FLongitude<0 then    FLongitude:=360;  if (IsMouseLook) then  Begin    FLatitude:= FLatitude+((FOldCameraPos.Y-CursorPos.y)*MouseSens);    FLongitude:= FLongitude-((FOldCameraPos.X-CursorPos.x)*MouseSens);  End;  pySetDoubleToObject(FCamPyClass,'_Pos_lon',FLongitude,'TGLCamera.Move');  pySetDoubleToObject(FCamPyClass,'_Pos_lat',FLatitude,'TGLCamera.Move');    glLoadIdentity();	glRotatef( FLatitude, 1, 0, 0);	glRotatef( FLongitude, 0, 0, 1);	glTranslatef( FCameraPos.X, FCameraPos.Y, -FCameraPos.Z );  if (IsMouseLook) then  Begin    if (CursorPos.x=MaxX-1) then    Begin      CursorPos.x:=1;      SetCursorPos(CursorPos.x,CursorPos.y);    End;    if (CursorPos.y=MaxY-1) then    Begin      CursorPos.y:=1;      SetCursorPos(CursorPos.x,CursorPos.y);    End;    if (CursorPos.x=0) then    Begin      CursorPos.x:= MaxX-2;      SetCursorPos(CursorPos.x,CursorPos.y);    End;    if (CursorPos.y=0) then    Begin      CursorPos.y:= MaxY-2;      SetCursorPos(CursorPos.x,CursorPos.y);    End;  End;  CurPosT.X:=CursorPos.X;  CurPosT.Y:=CursorPos.Y;  OldCameraPos:=CurPosT;end;


And more:

procedure TGLEngine.Paint(aStepVal:Single);var  I : Integer;begin  StepVal:=aStepVal;  glClear( GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT );  glPolygonMode(GL_FRONT, GL_FILL);  glPolygonMode(GL_BACK, GL_FILL);  if IsLight then    glEnable(GL_Lighting)  else    glDisable(GL_Lighting);  glMatrixMode(GL_MODELVIEW);  DoMove(StepVal); //Выполнение необходимых трансформаций  if Assigned(FPaintProc) then    FPaintProc;  CameraManager.RenderCams(IsMouseLook, MouseSens, FCurrCamera);  glEnable(GL_2D);  WindowsManager.TestWindows;  WindowsManager.DrawAll;  if (IsConsole) then  begin    IsKeyHandle:=False;    Console.DrawConsole;  end;  //Выводим курсор мыши  if (not IsMouseLook) then    GLMouse.DrawMouse2D;  glDisable(GL_2D);  //Отправляем картинку в буфер  SwapBuffers(wglGetCurrentDC());end;
MARS_999
MARS_999
Hmm I don't see any code in there that calls glCopyTexImage2D() or FBO's? So how are you copying the framebuffer content to the texture?
SkyRanger
SkyRanger
Sorry, here it is:

//====================================================================procedure TGLTextureManager.RenderTexture(TextureName:String);var	I:Integer;	CurrTex : TGLTexture;begin	for I:=0 to FCount-1 do	begin		CurrTex:=TGLTexture(FCollection);    if CurrTex.TextureName = TextureName then		  if CurrTex.RenderMode = GL_TEXTURE_RENDER then      begin    	  glBindTexture(GL_TEXTURE_2D, CurrTex.TextureId);        glCopyTexImage2D(GL_TEXTURE_2D, 0, CurrTex.Mode, 0, 0, 1024, 1024,0);      end;  end;  CurrTex:=nil;end;

MARS_999
MARS_999
what screen size are you running? If it's not larger than 1280x1024 then this isn't going to work due to you are trying to copy a 1024x1024 size framebuffer image... If you want that you need to use FBO's, or make the 1024x1024 512x512
SkyRanger
SkyRanger
640х480

it working, but strange way...

Here my code that draw camera screen:

procedure TGLCameraScreen.Draw;var	I : Integer;	P:PPyObject;	S : String;	Colors : TGLColor;	Texture : PChar;begin	FControlRec.Left:=pyGetDoubleFromObject(FPyClass,'_Pos_x','TGLCameraScreen.Draw');FControlRec.Top:=pyGetDoubleFromObject(FPyClass,'_Pos_y','TGLCameraScreen.Draw');FControlRec.Width:=pyGetDoubleFromObject(FPyClass,'_Width','TGLCameraScreen.Draw');FControlRec.Height:=pyGetDoubleFromObject(FPyClass,'_Height','TGLCameraScreen.Draw');Texture:=pyGetStringFromObject(FPyClass,'_Texture','TGLCameraScreen.Draw');	glDisable(GL_DEPTH_TEST);	glEnable(GL_TEXTURE_2D);	glEnable(GL_ALPHA_TEST);	glEnable(GL_BLEND);	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	glAlphaFunc(GL_GREATER, 0);	glPixelStorei(GL_PACK_ALIGNMENT ,1);	TextureManager.Bind(Texture,GL_TEXTURE_2D);	glBegin(GL_QUADS);		glNormal3d(0,0,1);		glTexCoord2f(0,0);		glVertex2f(FControlRec.Left+FParentWRec.Left,FControlRec.Top+FParentWRec.Top);		glTexCoord2f(0,WinHeight/(1024+75));		glVertex2f(FControlRec.Left+FParentWRec.Left,FControlRec.Top+FParentWRec.Top+FControlRec.Height);		glTexCoord2f(WinWidth/(1024+10),WinHeight/(1024+75));		glVertex2f(FControlRec.Left+FParentWRec.Left+FControlRec.Width,FControlRec.Top+FParentWRec.Top+FControlRec.Height);		glTexCoord2f(WinWidth/(1024+10),0);		glVertex2f(FControlRec.Left+FParentWRec.Left+FControlRec.Width,FControlRec.Top+FParentWRec.Top);	glEnd;end;


Sry i have no time clean code from 'tabs'.

FBO surelly next step in any case...

Here screenshot with that i have. Current camera_0, and it rendering in camera screen, top left window, but in camera screen must be renered camera_1, not current screen content!

http://skyr.newmail.ru/screen_cam.JPG
SkyRanger
SkyRanger
So any one have ideas???
I look at FBO and it not help in that case. It need another render content, so it will be 2 passes. One for texture and second for actual screen :(
SkyRanger
SkyRanger
well...

As i realise FBO need to create render content for himself. So i need to draw surface and all objects twice. Once for texture and inside it content. Second on screen.

Or i may be wrong?

But i want to draw it once. And then just rotate/translate it and render in to texture if needed. As i know rotation/translation takes less resources than rerawing...

But i not realy sure :)
deavik
deavik
"Render to texture" essentially implies at least 2 passes without exception (unless you are talking about something else) - 1) render scene to texture, 2) use texture for further processing and finally rendering.

You can take it from the guys who have already posted: FBO (as everyone says) is the fast, easy way to render-to-texture. The only disadvantage it has is that it needs a newer card.

Among other methods, WGL_ARB_pbuffer + WGL_ARB_render_texture is the only one that cuts it. glCopyTexImage2D / glReadPixels are too slow for anything of practical value.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.