• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
harshman_chris

Passing a float as a pointer.

11 posts in this topic

So I am trying to pass the below value to a float*, it returns a float

 

enviroment->getDirectionalLight()->getAmbientIntensity()

 

Here is what I am trying to pass it into.

void addUniform(std::string _id, float* _value);

getShader()->addUniform("directionalLight.base.ambientIntensity",&enviroment->getDirectionalLight()->getAmbientIntensity());

 

Unfortunately, it gives me this error

 

error C2102: '&' requires l-value

I dont understand this error, or a way around it?

 
0

Share this post


Link to post
Share on other sites

Another question is why does the function take a pointer? If it were returning a value, it could easily just return a float value, unless it is expected to read and write this value over time; in the latter case, passing the return value of that function is immediately a bad idea. This strikes me as a function that takes an array of float values, so even if you assigned the temporary to a variable, then sent its address, that'd be trouble.

0

Share this post


Link to post
Share on other sites

My basic idea is that I need to store the memory address to several float's and int's, so that I can access the values at a later point from a different class without having to hardcode the calls.

0

Share this post


Link to post
Share on other sites

My basic idea is that I need to store the memory address to several float's and int's, so that I can access the values at a later point from a different class without having to hardcode the calls.

So don't use pointers, but use values (I see no reason there why you need the memory address):

struct MyStruct
{
    int x;
 
    void assign(int value)
    {
        x = value; // Saving it for later!
    }
 
    void useValue()
    {
        std::cout << "x is " << x << std::endl; // Now use it later!
    }
};
 
MyStruct s;
s.assign(someFunctionThatComputesStuff());
// ... some time later ...
s.useValue(); // does *NOT* re-call someFunctionThatComputesStuff()

 

You can also make a std::vector of floats or ints if you need (but keeping track of what value represents what might get confusing if each value is supposed to be used differently).

0

Share this post


Link to post
Share on other sites

(I see no reason there why you need the memory address)


He likely is trying to say that the value that is returned is expected change while he's holding the pointer to it, and he wants to always have the updated value without having to get it again each time.

Then this will be a problem; technically, the temporary value might be in memory, or it might not be in memory at all. Even if it is, it's address will likely be different each time it is called. You'll have to find a way around it.

I would suggest getting a pointer to the data that the function returns (might not be a good idea, because it has an interface in place to get it, so handling it yourself might defy assumptions that the code makes), or holding on to the data in some sort of cache like Cornstalks mentioned, and having some sort of system to know when it is time to update it.
 
0

Share this post


Link to post
Share on other sites

The problem with watching for an update is that now a large section of my code needs to be hard coded to refresh values.

 

Where as if I can store pointers to the piece of data I will will not have to hard code that side of things.

0

Share this post


Link to post
Share on other sites

The problem with watching for an update is that now a large section of my code needs to be hard coded to refresh values.
 
Where as if I can store pointers to the piece of data I will will not have to hard code that side of things.

No, you just have an even-worse slew of new problems to handle, such as life-times of the pointers.
Even if you went with your pointer system you would still have to “hard-code” the telling to the shader that the pointer is no longer valid.

I don’t believe you are using the word “hard-code” correctly either.
What does that mean and how does it relate to a system such as this?
When some things change, sometimes other systems or objects need to be notified and updated. This isn’t hard-coding. It’s just…coding.

Besides that, you are trying to escape a simple update-when-changed system for a pointer-based system which means your intention is to set the pointer once and leave it.
That means you have no intention of using the same shader between multiple objects as that would require re-updating the pointer for each object (which would make the pointer system pointless since that many re-updates would mean that the shader would always have the most up-to-date value in it anyway).
The point is you can’t share your shaders and this is a major loss in both resources and performance.

Basically, your overall design needs to be re-evaluated, and your real underlying issue isn’t as simple as floats and pointers.  To solve this issue you must look beyond the beyond, young Kimosabe.  You must acknowledge that “grey” does not have an “a” in it, and you can’t ignore the chocolate cake any longer.  The time has come…

 

A good start would be to explain what you mean by “hard-coded” and what exactly is so wrong with your current system that you feel the need to make an even-worse system.

 

 

L. Spiro

0

Share this post


Link to post
Share on other sites

You must acknowledge that “grey” does not have an “a” in it


In my country's variant of English, its preferred spelling is "gray", with "grey" as an accepted alternative. smile.png

Also, I agree with figuring out exactly what you need and establishing why you need it, rather than making several drawn out patches to a system that likely wasn't what you had in mind when you started.

Edited by Ectara
0

Share this post


Link to post
Share on other sites

There are different value types in C++ types. To take the address of something with &, it needs to be an l-value. Temporary variables, like what enviroment->getDirectionalLight()->getAmbientIntensity() returns, are r-values, which means you can't take their address.



Think of it like this: Where does the float returned by enviroment->getDirectionalLight()->getAmbientIntensity() live? Where is its home? Answer: it doesn't have one. It's "homeless." It's just a temporary float that's being returned by a function, and so it never gets a "home" assigned to it. If something doesn't have a home, how can you take its address? You can't. The address points to "home," and thus if you could take its address it would have a home in the first place!



Why is this important? Well, look at that function. It's taking a pointer to a float. That means the function has the power and ability to change that float. But that float is temporarily existing. You can't change a temporary like that. If you could do that, then why not be able to do int* x = &2; *x = 3; (uh oh... did we just change 2 to now be 3? that's (one reason) why something like this isn't legal).







Note that this is a pretty high level explanation. You could get super technical and say that the temporary float does (or even better: might) have a home, but I don't really want to get into those details too much. If you want to view it like this, just think of it as a super temporary home that has some special rules you can't mess with. Kind of like a guest-home. The float is just a guest at the home, it doesn't "own" the home. You can't go in and start changing things in a home you don't own. Not legally, at least.

 

Well that is kind of true. All temporary file does have a home, because i just tried that

int* foo(const int& x)
{
  int* t = (int*)&x;
  *t=22;
  return t;
}
void main()
{
  int* ref = foo(12);

  cout<<ref<<endl;     //This is stil pointing to the temporary variable address.
}

 

And i was a able to modify 12 to 22. Also when i try printing the address of 12 it does print out an Address. The interesting thing is that the return value when i print it the address is still valid. The thing that was very interesting though is that if you look at the Assembly you will notice that the value that is assign to foo is still valid in the assembly code.
 

Edited by BornToCode
0

Share this post


Link to post
Share on other sites

Well that is kind of true. All temporary file does have a home, because i just tried that

int* foo(const int& x)
{
  int* t = (int*)&x;
  *t=22;
  return t;
}
void main()
{
  int* ref = foo(12);
  cout<<ref<<endl;     //This is stil pointing to the temporary variable address.
}

That's undefined behavior right there. I don't think you can rely on undefined behavior to come to any kind of meaningful conclusions about what the standard guarantees.

 

And i was a able to modify 12 to 22. Also when i try printing the address of 12 it does print out an Address. The interesting thing is that the return value when i print it the address is still valid. The thing that was very interesting though is that if you look at the Assembly you will notice that the value that is assign to foo is still valid in the assembly code.

Without trying to get super technical in this thread, temporaries may or may not have addresses associated with them, as they can potentially be completely optimized away or live entirely in a register instead of in memory. But yes, as you have noticed, you can pass a temporary or literal by const reference, which implies it's got some address or memory location associated with it (this is most easily proven by simply taking and printing the address of the const reference). A situation like this would fall under the "the temporary is just a guest in a temporary home" situation I described at the end. It's also important to note that when you print out that address, it is not still valid (that is, the temporary no longer exists in any way, shape, or form (as far as the standard guarantees), so that address you're printing out is just the temporary's old address, not a currently valid address (because the temporary doesn't even exist... how can you address it?))

Edited by Cornstalks
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0