Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Global Variables Not Truly Global?

2

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [blue]Mike,

    I think, your problem is in a fact that you do not call the functions which USE the variables in a continuous loop. Only continuous loop will provide a sense of a feedback.

    As I see it - you want to press a key and right away (from human point of view) to see the result of that key acting as a modifier for the camera(s) location and angle, etc.

    Do you call these functions in a loop or not? Because if you call them once, then your keys will not be noticed by the function unless you actually call it.

    Usually, to interactively control hardware in Win32 you need to use a timer. For example, you can set up a timer to be called every 100 milliseconds. In response to timer - you call your functions, which are using these variables. This way, max. interval between a key press and reaction on it will be 100 ms or less.
    [/blue]
  • Mike7409Mike7409 Member Posts: 15
    : If I remember correctly the following code will compile correctly, but it will be impossible to access the global variable from within the function:
    : [code]
    : // the global variable
    : int some_var;
    :
    : int some_func( void )
    : {
    : // the following line will not change the global some_var at all
    : // it will just create a local variable of name some_var and
    : // assign it a value of 5
    : int some_var = 5;
    :
    : // also this will only modify the local variable and not the
    : // global one
    : some_var++;
    :
    : } // end some_func
    : [/code]
    : I can't test that right now though. If you sent me the code I could look over it better [email protected]
    :


    Hi, Frank:

    Thanks for your second reply. If you are correct, this would certainly explain why I'm experiencing the difficulties that I am. I will do some more research and see if I can determine why this is so. I'll let you know what I find out.

    Thanks again,

    Mike
  • Mike7409Mike7409 Member Posts: 15
    : [blue]Mike,
    :
    : I think, your problem is in a fact that you do not call the functions which USE the variables in a continuous loop. Only continuous loop will provide a sense of a feedback.
    :
    : As I see it - you want to press a key and right away (from human point of view) to see the result of that key acting as a modifier for the camera(s) location and angle, etc.
    :
    : Do you call these functions in a loop or not? Because if you call them once, then your keys will not be noticed by the function unless you actually call it.
    :
    : Usually, to interactively control hardware in Win32 you need to use a timer. For example, you can set up a timer to be called every 100 milliseconds. In response to timer - you call your functions, which are using these variables. This way, max. interval between a key press and reaction on it will be 100 ms or less.
    : [/blue]
    :


    Hello again:

    Thanks for your second reply.

    I believe that you might be correct about both the loop and the timer. I'm still trying to determine the flow of this particular program. Does the program:

    Scenario A:

    1) Enter at Winmain() function
    2) Cycle through InitApp, calling the other initializing functions
    3) cycle repeatedly through the drawing functions over and over again?

    - or -

    Scenario B:

    Cycle through everything once?

    I had assumed that a C++ Win32 program enters at the Winmain function and then, after carrying out all initialization functions (until initialization flag = TRUE) and then cycles through the WinProc or WindowProc loop over and over again until termination. It is possible, however, that my assumption could be in error.

    I'll have to do some more testing and try to determine that further. I used to program pretty extensively in BASIC and am relatively new to C. I'm still in the process of learning just how C works from a flow control and variable accessing standpoint.

    Your thoughts about the timer are interesting, also. Could it be that the timer is neccessary in order to slow things down just a bit so that the system will have a chance to read the keys? It's certainly worth some thought. One interesting thing, though, is that the system does read the escape key when I press it and does shut down the application. The case VK_ESCAPE is within the switch(wparam) case WM_KEYDOWN within the WindowProc() function. The program does have one call to the Direct3DRM::Tick function to tick the scene, but if that runs only once that would certainly explain why the camera only moves once when I deliberately set the keyselect variable within the SetPositions() function.

    I'll look into both the loop and timer and let you know what I find out.

    Thanks again,

    Mike
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [blue]Mike,

    So, my guess was correct... :-)

    The WndProc is a message receiver from Windows (and from other sources as your own code or other applications). Windows will call your WndProc function only when needed. But if you use a timer - Windows will send you a message WM_TIMER with an interval you specify.

    The drawing in Windows is not cyclical and all the time, but only when needed: window resized, window minimized and restored, maximized and restored, or other window was closing yours and been moved out uncovering your window... etc.
    [/blue]
  • BitByBit_ThorBitByBit_Thor Member Posts: 2,444
    I don't know if this counts for when using Direct3D to draw...
    Probably not, but:

    I was messing around with printing text on a window and I noticed it didn't draw until I 'triggered' the repaint code.
    So I thought I would be smart and send a WM_PAINT with PostMessage.
    However, then still the program wouldn't draw until I resized.

    I found out this is because Windows doesn't really draw it. It just 'remembers' what the code run by WM_PAINT did and then when it is need of a refresh it draws.
    What I needed to do is mark the client area of my window as 'invalidated'. I had to tell Windows it was in need of an actual repaint (I did this with InvalidateRect API). And THEN I posted the WM_PAINT message.

    But like I said, I don't know if it's the same when using Direct3D (I would expect it to redraw automatically).

    Best Regards,
    Richard

    The way I see it... Well, it's all pretty blurry

  • Mike7409Mike7409 Member Posts: 15
    : I don't know if this counts for when using Direct3D to draw...
    : Probably not, but:
    :
    : I was messing around with printing text on a window and I noticed it didn't draw until I 'triggered' the repaint code.
    : So I thought I would be smart and send a WM_PAINT with PostMessage.
    : However, then still the program wouldn't draw until I resized.
    :
    : I found out this is because Windows doesn't really draw it. It just 'remembers' what the code run by WM_PAINT did and then when it is need of a refresh it draws.
    : What I needed to do is mark the client area of my window as 'invalidated'. I had to tell Windows it was in need of an actual repaint (I did this with InvalidateRect API). And THEN I posted the WM_PAINT message.
    :
    : But like I said, I don't know if it's the same when using Direct3D (I would expect it to redraw automatically).
    :
    : Best Regards,
    : Richard
    :
    : The way I see it... Well, it's all pretty blurry
    :
    :

    Hello Richard:

    I appreciate the reminder about "Invalidate". That may have some bearing on why one approach to my work is drawing so slowly. I appear to be making some progress but the challenge is figuring out a way to get the work done without having the computer slow to a crawl. In the last 24 hours, I've made some good progress with one approach but when a 450-mhz Penthium II computer gets to the point where it takes more than a second on each frame to update an image only involving eight vertices, that's pretty bad. Clearly, I'm going to need to rethink my approach to the problem. I'll look into using Invalidate and see if that helps in some kind of way.

    Thank you for taking the time to post your reply.

    Mike
  • Mike7409Mike7409 Member Posts: 15
    : [blue]Mike,
    :
    : So, my guess was correct... :-)
    :
    : The WndProc is a message receiver from Windows (and from other sources as your own code or other applications). Windows will call your WndProc function only when needed. But if you use a timer - Windows will send you a message WM_TIMER with an interval you specify.
    :
    : The drawing in Windows is not cyclical and all the time, but only when needed: window resized, window minimized and restored, maximized and restored, or other window was closing yours and been moved out uncovering your window... etc.
    : [/blue]
    :

    Yes, indeed you guessed part of the problem. In the last 24 hours or so, I have made significant progress. I went through with the debugger and stepped through the code and found out that one appearent factor behind the fact that the camera moved only once when I "forced" it to was the fact that the program cycles through the drawing instructions only once as part of its initialization and then moves the already-set-up image with the "Direct3DRM::Move command in the RenderLoop() function after that.

    By ultimately placing commands to access nearly all of the drawing functions in the RenderLoop() function, I was able to set things up in such a way that the program still initializes the image as part of its initialization but also calls the same drawing functions each time through the RenderLoop().

    I first began just by placing a KeyMode global variable in a structure whcih also stores some of the pointers for the scene, camera, and so forth. I was then able to incorporate if statements into the RenderLoop() that measured the KeyMode value as set in the WindowProc Loop. Finally, I was able to reference the global camera pointer directly in the SetPosition and SetOrientation commands and thus move the camera to either side and toward or away from the image just fine. Needless to say, I was very happy about that.

    However, when I went to rotate the camera -- to "look" to one side or the other or to "look" up or down, the image dissappeared as soon as soon as the camera was no longer pointed directly at it. This is when I decided to incorporate the commands in the RenderLoop() to call on the drawing commands on each cycle through it. Through experimentation with the "AddRotation", I was able to rotate the camera. However, the end result was totally unexpected. Rather than the camera rotating on a Y axis as planned, the camera rotated on a Z axis and the image spun like a whirling dervish! Finally, once I incorporated sufficient code into the loop and global structure to allow the object's frame to be part of the loop and referenced the rotation to that frame, it worked great -- except for one thing. The rotation would start out fast but would slow by half each time the object appeared and dissappeared on the screen as the camera rotates. Eventually, it got to the point where the computer -- a 450-mhz Penthium II -- takes more than a second on each frame to update an image which cureently involves only eight vertices. So, now I need to figure out a different way to tackle the problem.

    Also, when I tried to call the SetPositions function from the RenderLoop() function, something in it still does not allow the information in the global variables to be accessed by it. That's why part of my solution to get this far was to include the code from within the SetPositions() function in the RenderLoop() to access the global KeyMode and pointer variables for the frames with it.

    The bottom line is that, thanks to you and the other people who have taken the time to post replies, I am making progress and am no longer hitting the proverbial brick wall I was before and I cannot thank you personnally enough nor can I thank all of the others enough for that.

    Sincerely,

    Mike
  • Mike7409Mike7409 Member Posts: 15
    : One thing that I think that you should look over your code very carefully for is multiple definitions of the same variable. I noticed that in the code you posted you have campos_x and campos_X. C/C++ is case sensitive.
    :
    : Also are you sure that the code that is supposed to move the camera around is correct and works?
    :
    Hello again, Frank:

    I'm sending you this update (which in all honesty includes some comments I sent in a messgae to another individual -- I did this to saVe me some time in typing) I wanted to let you know that, thanks in part to your suggestion that I look over the code more carefully, things are looking a little better as disussed below:


    "In the last 24 hours or so, I have made significant progress. I went through with the debugger and stepped through the code and found out that one appearent factor behind the fact that the camera moved only once when I "forced" it to was the fact that the program cycles through the drawing instructions only once as part of its initialization and then moves the already-set-up image with the "Direct3DRM::Move command in the RenderLoop() function after that. By placing commands to access nearly all of the drawing functions in the RenderLoop() function, I was able to set things up in such a way that the program still initializes the image as part of its initialization but also calls the same drawing functions each time through the RenderLoop(). By placing a KeyMode global variable in a structure whcih also stores some of the pointers for the scene, camera, and so forth, I was able to incorporate if statements that measured the KeyMode value as set in the WindowProc Loop and thus move the camera to either side and toward or away from the image just fine. Needless to say, I was very happy about that.

    "However, when I went to rotate the camera -- to "look" to one side or the other or to "look" up or down, the image dissappeared as soon as soon as the camera was no longer pointed directly at it. This is when I decided to incorporate the commands in the RenderLoop() to call on the drawing commands on each cycle through it. Through experimentation with the "AddRotation", I was able to rotate the camera. However, the end result was totally unexpected. Rather than the camera rotating on a Y axis as planned, the camera rotated on a Z axis and the image spun like a whirling dervish! Finally, once I incorporated sufficient code into the loop and global structure to allow the object's frame to be part of the loop and referenced the rotation to that frame, it worked great -- except for one thing. The rotation would start out fast but would slow by half each time the object appeared and dissappeared on the screen as the camera rotates. Eventually, it got to the point where the computer -- a 450-mhz Penthium II -- takes more than a second on each frame to update an image which cureently involves only eight vertices. So, now I need to figure out a different way to tackle the problem.

    "Also, when I tried to call the SetPositions function from the RenderLoop() function, something in it still does not allow the information in the global variables to be accessed by it. That's why part of my solution to get this far was to include the code from within the SetPositions() function in the RenderLoop() to access the global KeyMode and pointer variables for the frames with it.

    "The bottom line is that, thanks to you and the other people who have taken the time to post replies, I am making progress and am no longer hitting the proverbial brick wall I was before and I cannot thank all of you enough for that."

    And, as just mentioned, the thanks go to you also, Frank. Thank you very, very much.

    Sincerely,

    Mike
  • Mike7409Mike7409 Member Posts: 15

    Hello again, Lundin:

    I've made some recent progress and, being that you kindly took the time to post a reply to my message, I thought you might be interested in the progress I've made. I'm including some comments I made to another individual so as to save me some typing time. Thanks in part to your suggestion about using the debugger, I've made the progress discussed below:

    "In the last 24 hours or so, I have made significant progress. I went through with the debugger and stepped through the code and found out that one appearent factor behind the fact that the camera moved only once when I "forced" it to was the fact that the program cycles through the drawing instructions only once as part of its initialization and then moves the already-set-up image with the "Direct3DRM::Move command in the RenderLoop() function after that. By placing commands to access nearly all of the drawing functions in the RenderLoop() function, I was able to set things up in such a way that the program still initializes the image as part of its initialization but also calls the same drawing functions each time through the RenderLoop(). By placing a KeyMode global variable in a structure whcih also stores some of the pointers for the scene, camera, and so forth, I was able to incorporate if statements that measured the KeyMode value as set in the WindowProc Loop and thus move the camera to either side and toward or away from the image just fine. Needless to say, I was very happy about that.

    "However, when I went to rotate the camera -- to "look" to one side or the other or to "look" up or down, the image dissappeared as soon as soon as the camera was no longer pointed directly at it. This is when I decided to incorporate the commands in the RenderLoop() to call on the drawing commands on each cycle through it. Through experimentation with the "AddRotation", I was able to rotate the camera. However, the end result was totally unexpected. Rather than the camera rotating on a Y axis as planned, the camera rotated on a Z axis and the image spun like a whirling dervish! Finally, once I incorporated sufficient code into the loop and global structure to allow the object's frame to be part of the loop and referenced the rotation to that frame, it worked great -- except for one thing. The rotation would start out fast but would slow by half each time the object appeared and dissappeared on the screen as the camera rotates. Eventually, it got to the point where the computer -- a 450-mhz Penthium II -- takes more than a second on each frame to update an image which cureently involves only eight vertices. So, now I need to figure out a different way to tackle the problem.

    "Also, when I tried to call the SetPositions function from the RenderLoop() function, something in it still does not allow the information in the global variables to be accessed by it. That's why part of my solution to get this far was to include the code from within the SetPositions() function in the RenderLoop() to access the global KeyMode and pointer variables for the frames with it.

    "The bottom line is that, thanks to you and the other people who have taken the time to post replies, I am making progress and am no longer hitting the proverbial brick wall I was before and I cannot thank all of you enough for that."

    And, as just mentioned, the thanks go to you also, Lundin. Thank you very, very much.

    Sincerely,

    Mike
  • LundinLundin Member Posts: 3,711
    [b][red]This message was edited by Lundin at 2007-3-25 23:26:43[/red][/b][hr]
    Sorry for my late reply, busy weekend.

    I guess there is nothing to add except that I don't think "Invalidate" should be needed in DirectX. I don't know anything about DirectX but I have used OpenGL in the past which should be similar, and I don't remember using any invalidate functions.

    Regarding optimizing: if you know about multithreading, perhaps you could split the program in 3 threads. One main processing thread, one graphic updates thread and one keyboard thread (instead of the inaccurate WM_TIMER which accuracy depends on the speed of other parts of the code).


2
Sign In or Register to comment.