Results 1 to 8 of 8

Thread: Glitching and wrong textures used after changing the height of the projection matrix.

  1. #1
    Squire
    Join Date
    Sep 2011
    Location
    Poland
    Posts
    16

    Question Glitching and wrong textures used after changing the height of the projection matrix.

    I am working on an camera object which allows the player to zoom in or out by using the mouse wheel.
    It's following the player by updating it's position on every draw call.

    The problem is everytime the player tries to change the height of the camera, objects are beeing drawn with wrong textures.

    Below are two screenshoots showing what is happening at a default height of 450 units, and after beeing changed.
    Name:  before zoom.png
Views: 39
Size:  231.8 KB
    Name:  After zoom.png
Views: 32
Size:  231.9 KB

    Things to note are:
    1.All gui windows stay intact
    2.The same incorrect textures are beeing displayed on every object using the same sprite.
    3.On every application start the same incorrect textures are beeing applied after height change.
    4.basic drawing also suffers from this. Rgb squares drawed with CL_Draw's filling just dissapear.

    Draw call that still bothers CL_Draw looks like this:
    Code:
    World::World()
    {
    	/.../
    	perspMatrix = CL_Mat4f::perspective(90.0f, (1600.0f/900.0f), 0.1f, 2000.0f);
    	modelIdentity = CL_Mat4f::identity();
    	/.../
    }
    void Camera::Camera()
    {
    	/../
    	perspMatrix = world->getPerspMatrix();
            /../
    }
    void Camera::lookAtObject()
    {
    	CL_GraphicContext gc = world->get_gc();
    
    	perspCameraMatrix = *perspMatrix; //perspCameraMatrix is defined in the Camera.h
    	perspCameraMatrix.translate_self(0,0,-height); // Anything different than height = 450.0f makes my life fall apart.
    
    	gc.set_map_mode(cl_user_projection);
    	gc.set_projection(perspCameraMatrix);
    }
    
    void World::draw()
    {
    	gc.set_modelview(modelIdentity);
    	camera->lookAtObject();
    
    	CL_Draw::fill(gc,-200,-200,-100,-100,CL_Colorf::red);
    	CL_Draw::fill(gc,-100,-200,0,-100,CL_Colorf::green);
    	CL_Draw::fill(gc,0,-200,100,-100,CL_Colorf::blue);
    
    	gc.set_map_mode(cl_map_2d_upper_left);
    }
    
    //Gui component responsible for calling world's draw method
    void GameComponent::on_render(CL_GraphicContext &gc, const CL_Rect &clip_rect)
    {
    	if(world) world->draw();
    }
    Right now i am using OPENGL_2, so i've tried going from OPENGL_2 to OPENGL_1. Although it fixed the problem, a different glitch that appeared after doing so is a material for a completely different story.
    Perhaps i should be using GC provided by the GUI call? Right now world has got it's own.
    Also i am working on windows 7 64x, Visual c++ 2008, Clanlib 2.3.4.

    Huge thanks for your time. I am going to appreciate all kinds of help.
    Cheers

    @edit1
    Tried using GUI GC what sadly hasn't helped. Right now i am throwing away portions of code to track the bug.
    Last edited by Griz; 05-28-2012 at 08:56 PM.

  2. #2
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    Try adding gc.flush_batcher() everywhere to see if that helps

    (Especially around settings the projection matrix)

  3. #3
    Squire
    Join Date
    Sep 2011
    Location
    Poland
    Posts
    16

    Default

    Quote Originally Posted by rombust View Post
    Try adding gc.flush_batcher() everywhere to see if that helps

    (Especially around settings the projection matrix)
    Thanks for the reply Rombust. I'll try that right away

  4. #4
    Squire
    Join Date
    Sep 2011
    Location
    Poland
    Posts
    16

    Default

    Flushing in literally every second line of code fixed drawing sprites and images. Whew!
    CL_Draw doesn't like this solution, though. That called for some heavy weaponry.

    for simplicity i am going to write GLC instead of GL context.

    I decided to try out gDEBugger, and while using it I've stumbled upon rather interesting results.

    while using OPENGL_1 application creates GLC1* and GLC2, plus GLC 3,4,5,6 that are shared with GLC 2.
    I have no problems in accessing the textures from the GLC2. Everything seems alright.

    Now, while using OPENGL_2 application creates GLC1* and GLC2.
    I don't have access to the textures anymore.

    *- GLC1 in both cases is deleted just after creation of GLC2.

    two errors appear when GLC2 turns alive.
    Code:
    error 1:
    Render Context 1 was deleted without clearing all its graphic objects, 
    causing a graphic memory leak. 
    Note that if using ShareLists, these objects may have been created in another render context.
    
    error 2:
    Debug String: Detected error: The debugged process asked for an extension function pointer 
    (wglCreateContextAttribsARB) from one render context, but called this function pointer in another render context (context #0)
    I don't see any shared lists while using OPENGL_2. Maybe that's the case?

    Error 1 comes from the following piece of code only if OPENGL_2 is used:
    Code:
    int Application::main(const std::vector<CL_String> &args)
    {
    	
    	CL_SetupVorbis setup_vorbis;
    	CL_SoundOutput output(44100,100);
    
    	CL_SetupCore setupCore;
    	CL_SetupNetwork setupNetwork;
    	
    	initValues();
    	//create Window
    	CL_DisplayWindowDescription desc;
    	desc.set_title("Futurisma 0.08 build 108");
    	desc.set_size(CL_Size(1600, 900), true);
    ->	CL_DisplayWindow window(desc);
    
    	CL_GraphicContext gc = window.get_gc();
    
    	/../
    }
    To be more exact:
    Code:
    Call stack:
    >	SpritesRTS.exe!CL_OpenGLCreationHelper::~CL_OpenGLCreationHelper()  Line 84	C++
     	SpritesRTS.exe!CL_OpenGLWindowProvider_WGL::create(CL_DisplayWindowSite * new_site=0x041c5d8c, const CL_DisplayWindowDescription & desc={...})  Line 337 + 0x11 bytes	C++
     	SpritesRTS.exe!CL_DisplayWindow::CL_DisplayWindow(const CL_DisplayWindowDescription & description={...}, CL_DisplayTarget target={...})  Line 80	C++
     	SpritesRTS.exe!Application::main(const std::vector<CL_String8,std::allocator<CL_String8> > & args=[1]({data_capacity=65 local_string=0x02ebda34 "" }))  Line 52 + 0x22 bytes	C++
     	SpritesRTS.exe!Program::main(const std::vector<CL_String8,std::allocator<CL_String8> > & args=[1]({data_capacity=65 local_string=0x02ebda34 "" }))  Line 59 + 0xc bytes	C++
     	SpritesRTS.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x0024652c, int nCmdShow=1)  Line 90	C++
     	SpritesRTS.exe!__tmainCRTStartup()  Line 263 + 0x2c bytes	C
     	SpritesRTS.exe!WinMainCRTStartup()  Line 182	C
    
    
    CL_OpenGLCreationHelper::~CL_OpenGLCreationHelper()
    {
    ->	wglDeleteContext(query_context);
    	DeleteDC(query_dc);
    	DestroyWindow(query_window);
    }
    I don't really know what else i can do with that now except for using OPENGL_1.

    @PS
    I am just starting to crawl in graphic development. Because of that some information provided in this post might be irrelevant.

  5. #5
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    Ignore that OpenGL error, although it is probably technically an error, it shouldn't be connected with your bug.

    Flushing in literally every second line of code fixed drawing sprites and images. Whew!
    CL_Draw doesn't like this solution, though. That called for some heavy weaponry.
    Since that worked, you just need to slowly remove the flush_batcher calls() until you find the exact offending function call.

  6. #6
    Squire
    Join Date
    Sep 2011
    Location
    Poland
    Posts
    16

    Default

    Flush_batcher needs to be called after every single CL_Sprite draw call. CL_Draw::fill doesn't get fixed no matter where the flushing occurs.

    @edit
    Also noticed that if there are two CL_Sprite draw calls one after another, both use the same texture of the first sprite drawed.
    Then if there are three CL_Sprite draw calls first draws correctly, second uses texture of the first, and third uses texture of the second.
    Last edited by Griz; 05-30-2012 at 09:08 PM.

  7. #7
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    I don't know what can be wrong.

    It is very strange that the ClanLib batcher stops working when changing the projection matrix. ClanLib should automatically use a 3D version of the batcher when using a user defined projection matrix. I guess the switching mechanism is broken (just a guess)

    Normally you never need to touch the projection matrix unless you are working in 3D. (In 3D you wouldn't be using CL_Sprite (since it's a 2D class).

    Instead, consider doing the following, to change the height:

    (Tested using Examples/Game/SpriteRTS)

    Code:
    void World::draw()
    {
    
    	CL_Mat4f matrix = CL_Mat4f::identity();
    	matrix = CL_Mat4f::translate(gc.get_width()/2.0f, gc.get_height()/2.0f, 0.0f) * matrix;		// Offset to center of screen
    	matrix = CL_Mat4f::scale(0.5f, 0.5f, 0.0f) * matrix;										// Scale
    	matrix = CL_Mat4f::translate(-gc.get_width()/2.0f, -gc.get_height()/2.0f, 0.0f) * matrix;	// Restore offset
    	gc.set_modelview(matrix);
    
    }
    This method works with clanSWRender, clanGL and clanGL1

  8. #8
    Squire
    Join Date
    Sep 2011
    Location
    Poland
    Posts
    16

    Default

    Quote Originally Posted by rombust View Post
    It is very strange that the ClanLib batcher stops working when changing the projection matrix. ClanLib should automatically use a 3D version of the batcher when using a user defined projection matrix. I guess the switching mechanism is broken (just a guess)
    Yes. It seems to work perfectly fine with clanGL1 as long as i don't use CL_Window objects in the gui system (That's a story for another topic and i don't really want to raise it here).

    Quote Originally Posted by rombust View Post
    Normally you never need to touch the projection matrix unless you are working in 3D. (In 3D you wouldn't be using CL_Sprite (since it's a 2D class).
    I plan on implementing 3D levels and particle effects with 2D sprites. That's why I Find using projection matrix a quite flexible way of achieving the wanted result.

    Quote Originally Posted by rombust View Post
    Instead, consider doing the following, to change the height:
    /.../
    This method works with clanSWRender, clanGL and clanGL1
    It works really well! I'm enormously grateful for your help Rombust. Thank you for your time.
    Cheers

Similar Threads

  1. ClanLib 2.4 (SVN) - Matrix Multiplication Reversal
    By rombust in forum Official ClanLib SDK Forums
    Replies: 0
    Last Post: 01-24-2012, 01:54 PM
  2. Problem with changing package name on Android
    By Le Viet Bach in forum Proton SDK
    Replies: 2
    Last Post: 01-30-2011, 07:32 AM
  3. Changing Novashell source - Linear Filter
    By garcia in forum Novashell Game Creation System
    Replies: 8
    Last Post: 11-15-2010, 12:00 AM
  4. changing the size of CL_Font_Sprite
    By xrubio in forum Official ClanLib SDK Forums
    Replies: 8
    Last Post: 07-27-2009, 09:49 AM
  5. OpenGL Textures
    By ElephantHunter in forum Official ClanLib SDK Forums
    Replies: 2
    Last Post: 09-09-2008, 03:03 AM

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •