Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 18 Aug 2005
Offline Last Active Mar 30 2016 05:19 PM

#5277892 Translate 2D mouse position to place an object in 3D space

Posted by on 24 February 2016 - 09:38 AM

Read: http://mathworld.wolfram.com/Tangent.html -- look for the big triangle. Remember SOHCAHTOA.


tan(theta), where theta = pi/8, gives you the rise over run. When the camera is 1 unit away from the origin, the run is 1. The rise goes on to give you half of the image plane width.

That helps because I didn't know what the tangent was for.


I've analyzed the code and simplified it. Below is the final modified version. Let's look at it line by line.


First useless line.

const float pi = 4.0f*atanf(1.0f);

All this does is give us the value of PI. math.h has a #define you can use so this is unnecessary. As you'll see in the finial code, many things were unnecessary.


Next line.

const float aspect = (float)(m_renderbufferWidth) / (float)(m_renderbufferHeight);

This give us the aspect ratio of the screen. Not sure why this is needed for the x coordinate and not the y. I think it's magic.


Next Two lines.

const float fx = 2.0f * ((float)(x) / (float)(m_renderbufferWidth - 1)) - 1.0f;
const float fy = 2.0f * ((float)(y) / (float)(m_renderbufferHeight - 1)) - 1.0f;

This converts screen coordinates from a top/left orientation to a center screen coordinates but there's a little more to this then that.

1) Subtracting the width and height by one. The reason you do this is because resolution sizes are usually all even numbers. For example, a resolution of 1280x720 there is no center pixel or a pixel at 0. The other reason this could be is that you need a value of base 0, as if this was an array and w/h represents the total number of elements.

2) x/y divied by w/h. This gives you a normalize value of the point on your screen. In other words, a value from 0 to 1.

3) 2.0f *; not entirely sure what this is doing and why it is needed.

4) The last - 1.0f flips the sign.


Second useless line

const float y_fov = pi/4; // pi/4 radians = 45 degrees

This takes PI and divides it by 4 to give us 45 degrees in radians. This is unnecessary.


Modified line.

const float tangent = tan(y_fov / 2.0f);

This divides the 45 degrees by 2 to give use 22.5 degrees in radians. This can be simplified by plopping a number in tan.


I know what the rest is doing, I just don't understand why it works.

*    desc:  Convert 2d screen coordinates to 3D perspective space
void Convert2Dto3D( float & destX, float & destY, float x, float y, float width, float height )
    const float aspect = width / height;

    // Convert upper left 0,0 to center screen 0,0 coordinates
    const float fx = (2.0f * (x / (width - 1))) - 1.0f;
    const float fy = (2.0f * (y / (height - 1))) - 1.0f;

    // (pi/4 radians = 45 degrees / 2) or ((pi/4) / 2))
    const float tangent = tan( 0.392699082 );

    // Project x,y to a z plane of 1
    destX = aspect * tangent* fx;
    destY = -tangent * fy;

}   // Convert2Dto3D

#5277203 Translate 2D mouse position to place an object in 3D space

Posted by on 20 February 2016 - 05:41 PM

done! You have your up vote.


I wish I could look at this code and know what it's doing. If anyone can explain it, please do.

#5276975 Translate 2D mouse position to place an object in 3D space

Posted by on 19 February 2016 - 10:48 AM

Thank you guys for your help!


Taby, thank you for posting the code. It works GREAT!


All I had to do was multiply the final X and Y values by a positive z order.


I couldn't be more happy! There's no way I would have been able to write that code. Taby, you are Awesome!

#5276942 Translate 2D mouse position to place an object in 3D space

Posted by on 19 February 2016 - 08:28 AM

I want to be able to click on the screen and place a box at that spot in perspective 3D space. I would need to give the box the offsets in world view. The camera is at 0,0,0. In addition to the screen coordinates where 0,0 is the center of the screen, I also know the z order of where I want to box to go. Say -150


I've been struggling with this problem for a day now and google searches are not helping. Thought I could solve it with simple tri which is all I'm good at.


Can anyone solve this?


#5258147 Stencil buffer not working on Android NDK implementation

Posted by on 20 October 2015 - 11:23 AM

I'm only setting it in the init now. My stencil needs at the moment are very simple but I can't see needing to do more at this time.


The way to think of this is the glStencilMask() is like glClearColor, you're telling OpenGL what value to use when clearing the stencil buffer, just like the color or depth buffer. This all happens when glClear is used. Example: glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT )


See my adjusted code below.

*    desc:  Init the game
void CBaseGame::Init()
    // Init the clear color
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    // Init the stencil clear mask based on the bit size of the mask
    // Stencil buffer can only be 1 or 8 bits per pixel
    if( CSettings::Instance().GetStencilBufferBitSize() == 1 )
    else if( CSettings::Instance().GetStencilBufferBitSize() == 8 )

    // Cull the back face

    // Enable alpha blending

    // Make the zero texture the active texture

    // Show the window
    CDevice::Instance().ShowWindow( true );

    if( CSettings::Instance().GetClearTargetBuffer() )
        m_clearBufferMask |= GL_COLOR_BUFFER_BIT;

    if( CSettings::Instance().GetEnableDepthBuffer() )
        m_clearBufferMask |= GL_DEPTH_BUFFER_BIT;
    if( CSettings::Instance().GetClearStencilBuffer() )
        m_clearBufferMask |= GL_STENCIL_BUFFER_BIT;
    // Display a black screen
    glClear( GL_COLOR_BUFFER_BIT );
    SDL_GL_SwapWindow( m_pWindow );

}   // Init

#5257709 Trying to debug Android NDK C/C++ files in Eclipse

Posted by on 17 October 2015 - 02:28 PM

Never mind. Thought this was the reason I wasn't able to debug the code. My simple test app does the same thing. Chances are I'm getting past my break point before the debugger has a chance to lock on perhaps.

#5257702 Trying to debug Android NDK C/C++ files in Eclipse

Posted by on 17 October 2015 - 01:23 PM

Just to state for the record, I have gotten native debugging working with a simple project. This problem is from trying to get my game engine to run on Android.


I'm almost there but I don't know what this problem is. Here's the error message.


warning: Could not load shared library symbols for 64 libraries, e.g. /system/bin/linker.


Here are the libraries it said it's couldn't load...

Syms Read   Shared Object Library
No          /system/bin/linker
No          libstdc++.so
No          libm.so
No          liblog.so
No          libcutils.so
No          libz.so
No          libtime_genoff.so
No          libutils.so
No          libbinder.so
No          libexpat.so
No          libcrypto.so
No          libicuuc.so
No          libicui18n.so
No          libsqlite.so
No          libssl.so
No          libnativehelper.so
No          libnetutils.so
No          libEGL.so
No          libwpa_client.so
No          libidd.so
No          libprotobuf-c.so
No          libhardware_legacy.so
No          libpixelflinger.so
No          libhardware.so
No          libui.so
No          libgui.so
No          libsurfaceflinger_client.so
No          libcamera_client.so
No          libemoji.so
No          libdrmframework.so
No          libskia.so
No          libGLESv1_CM.so
No          libskiagl.so
No          libdvm.so
No          libGLESv2.so
No          libETC1.so
No          libsonivox.so
No          libmedia.so
No          libnfc_ndef.so
No          libbluedroid.so
No          libdbus.so
No          libandroid_runtime.so
No          libvorbisidec.so
No          libstagefright_amrnb_common.so
No          libstagefright_enc_common.so
No          libstagefright_avc_common.so
No          libstagefright_foundation.so
No          libstagefright_color_conversion.so
No          libpostfilteredsource_impl.so
No          libsolsmetadataretriever.so
No          libstagefright.so
No          libmedia_jni.so
No          libexif.so
No          libsoundpool.so
No          libacc.so
No          libRS.so
No          librs_jni.so
No          libwtle.so
No          libtextrendering.so
No          libstlport.so
No          libwebcore.so
No          libandroid.so
No          liboverlay.so
No          gralloc.msm8660.so

I'm very confused by what it says it's missing.


In my Android.mk file, I do have these listed.

LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid


I'm assuming there's some libraries I haven't defined somewhere that is somhow needed?


#5200935 Animated load screens with OpenGL, a simple solution

Posted by on 31 December 2014 - 12:09 AM

I came up with a simple solution for animated loading screens since I really don't like the few options that are available for trying to multi-thread parts of OpenGL. My simple solution allows you to load everything from the main thread and run your animation from newly spawned thread. This only works if your using SDL.

The simple solution is...

Use SDL's bitmap software rendering tools to load and render your "loading" animation from a thread. Since this is a completely separate rendering system, there's no OpenGL conflicts. Also, your engine probably has some dependencies that need to be loaded just to get part of your system up and running before even a simple image can be displayed as well as start up the render loop. That's no longer an issue.

I just start the thread that plays the "loading" animation and then load everything. This is happening outside of the game loop, independent of the engine, from within one function.

Here's my code to animate from a thread to show how easy it is to do. I'm just fading the logo in and out while loading sound, textures, etc with my engine.

I thought this was such a cool solution so I thought I'd share. Works great for me. biggrin.png

int CStartUpState::Animate()
    // Get window surface
    SDL_Surface * pScreenSurface = SDL_GetWindowSurface( CDevice::Instance().GetWindow() );
    if( pScreenSurface == NULL )
        NGenFunc::PostDebugMsg( "Surface Creation error! - " + std::string(SDL_GetError()) );

    // Create a bitmap surface
    SDL_Surface * pLogoSurface = SDL_LoadBMP( "data/textures/startup/logo.bmp" );
    if( pLogoSurface == NULL )
        NGenFunc::PostDebugMsg( "Logo Surface Creation error! - " + std::string(SDL_GetError()) );

    // Calculate the rect position and scaled size
    SDL_Rect rect;
    rect.w = pLogoSurface->w * CSettings::Instance().GetScreenRatio().GetH();
    rect.h = pLogoSurface->h * CSettings::Instance().GetScreenRatio().GetH();
    rect.x = (pScreenSurface->w - rect.w) / 2;
    rect.y = (pScreenSurface->h - rect.h) / 2;

    SDL_Delay( 200 );

    FadeTo( 500, 0, 255, pLogoSurface, pScreenSurface, rect );

    SDL_Delay( 2000 );

    FadeTo( 500, 255, 0, pLogoSurface, pScreenSurface, rect );

    SDL_Delay( 200 );

    SDL_FreeSurface( pLogoSurface );
    SDL_FreeSurface( pScreenSurface );

    return thread::THREAD_EXIT_CODE;

}  // Animate

void CStartUpState::FadeTo(
    float time, float current, float final, SDL_Surface * pSource, SDL_Surface * pTarget, SDL_Rect & rect )
    float inc = (final - current) / time;

    while( time > 0 )
        // First thing we need to do is get our elapsed time

        time -= CHighResTimer::Instance().GetElapsedTime();

        current += inc * CHighResTimer::Instance().GetElapsedTime();

        SDL_SetSurfaceColorMod( pSource, current, current, current );

        if( time < 0 )
            SDL_SetSurfaceColorMod( pSource, final, final, final );

        SDL_BlitScaled( pSource, NULL, pTarget, &rect );
        SDL_UpdateWindowSurface( CDevice::Instance().GetWindow() );

        SDL_Delay( 5 );

}   // FadeTo

This is where it all happens. The first line of code starts the thread for animating loading screen. The following lines of code is loading everything I need for the engine at this time. The last line waits for the thread to finish. All within one function, completely independent of the OpenGL/SDL game engine.

void CStartUpState::Load()
    // Start the animated loading thread
    loadThread.Start( this, &CStartUpState::Animate, "startupStateThread" );

    // Load in any fonts
    CFontMgr::Instance().LoadFromXML( "data/textures/fonts/font.lst" );

    // Shaders must always be loaded first because they are accessed from object data
    CShaderMgr::Instance().LoadFromXML( "data/shaders/shader.cfg" );

    // Load all of the meshes and materials in these groups
    CObjectDataMgr2D::Instance().LoadListTable( "data/objects/2d/objectDataList/dataListTable.lst" );
    CObjectDataMgr2D::Instance().LoadGroup( "(title_screen)" );

    // Load sound resources for the menu
    CSoundMgr::Instance().LoadListTable( "data/sound/soundListTable.lst" );

    // Creates the script manager and loads the list table
    CScriptManager::Instance().LoadListTable( "data/objects/2d/scripts/scriptListTable.lst" );

    // Register the script items
    RegisterStdString( CScriptManager::Instance().GetEnginePtr() );
    NScriptGlobals::Register( CScriptManager::Instance().GetEnginePtr() );
    NScriptColor::Register( CScriptManager::Instance().GetEnginePtr() );
    CSpriteScriptComponent2d::Register( CScriptManager::Instance().GetEnginePtr() );

    // Load group specific script items

    // Create the menu system
    CMenuManager::Instance().LoadFromXML( "data/objects/2d/menu/tree.list" );

    // Init the currently plugged in game controllers

    // Load the action manager
    CActionManager::Instance().LoadActionFromXML( "data/settings/controllerMapping.cfg" );

    // Wait for the thread to finish

}   // Load

#5083699 XAudio2 - Pretty poor huh?

Posted by on 06 August 2013 - 05:19 PM

I use XAct. I find it very easy to use and has many powerful features. I'll post some code if anyone is interested.

#5028094 Basic Win32 window with C++

Posted by on 02 February 2013 - 08:10 AM

Since your writing a Windows API app in c++, it's all you at that point. If you want easy interface construction, try C#.


A simpler way to add controls to a window api c++ app is to use an *.rc file to setup a dialog window as your parent window. Now you can use the MSVS gui to design your window with the needed controls.


This example might help you.


#4943714 Package files - Do we really need them for our game?

Posted by on 27 May 2012 - 08:23 AM

For me, the only reason to use a package file is to keep people from messing around or using the resources from the game. So the question is..., is this a legitimate concern?

#4898980 fleshing out your game idea

Posted by on 02 January 2012 - 11:22 AM

I find compartmentalizing concepts makes it easier to expand on them and edit them.

Can you share a simple example of what you are talking about? The idea sounds interesting but I'm not sure I'm completely understand.