Jump to content

  • Log In with Google      Sign In   
  • Create Account

We need your help!

We need 7 developers from Canada and 18 more from Australia to help us complete a research survey.

Support our site by taking a quick sponsored survey and win a chance at a $50 Amazon gift card. Click here to get started!

Brother Bob

Member Since 26 Nov 2001
Offline Last Active Today, 05:50 AM

#5025881 Delete VBOs at run time?

Posted by Brother Bob on 26 January 2013 - 05:24 PM

Deleting buffers at run time makes the next draw call ends with an access violation.

This one makes me seriously wonder what you're doing.


Are you creating and deleting the buffer objects for every frame? That is a very big no-no. What you need to do is create them once and delete them when you're done with them, at the end of the game, or at the end of the level, or whenever you don't need the objects anymore. But don't create and recreate them on a per-frame basis.


I can also interpret your question as a serious ownership-problem; you are deleting objects that shouldn't be deleted in the first place because you are still using them. In that case, you should read up on resource ownership and what it means with something owning a resource and controlling when it's being deleted. In no case should a resource be deleted that you either need or have a replacement for (such as a dummy resource that you can use instead of the actual resource isn't available).

#5025153 One way list into glVertexPointer

Posted by Brother Bob on 24 January 2013 - 11:47 AM

OpenGL can only use attributes stored linearly in memory and cannot read non-linear data structures.

#5024071 Tile sheet spriting math ?

Posted by Brother Bob on 21 January 2013 - 05:11 PM

Subtract one from the values you read from the map and then work with zero-based indexing. The math turns out so much cleaner with zero-based indexing.

#5023893 Reading binary file to vbo in OpenGL

Posted by Brother Bob on 21 January 2013 - 08:17 AM

The significant performance issue is going to be the physical disk IO and not which logical method you use. Just don't make some stupid performance test where you don't take the physical disk IO into account and just keeps reading from any of the multiple levels of cache along the way to come to an irrelevant conclusion.

#5023837 Whats wrong with this code?

Posted by Brother Bob on 21 January 2013 - 04:59 AM

Please specify the environment you're using and in what context it is used. This looks like a very limited piece of code. But just looking at the code, I see no reason why the callbacks would matter. The program flow seems to be like this:

  1. Get some button handles
  2. Define an uninitialized variable num
  3. Set button callbaks.
  4. Print the value of num.

There are no callbacks happening before printing in step 4, and thus no chance of printing anything but the uninitialized value from step 2.

#5023455 Compiler error on Counting how many lines there is?

Posted by Brother Bob on 20 January 2013 - 04:52 AM

strtok modifies the string you pass, but you're passing a string literal which cannot be modified. You have to allocate memory for the string, either dynamically or statically.

char string[] = "This is a simple game lets enjoy this\nIt breaks a new era in to games\nwhahahaha zoom in";
int lines = count_lines(string);

#5023177 Text error in C

Posted by Brother Bob on 19 January 2013 - 08:46 AM

You have to allocate memory for the pointer to point to. Look up malloc() and free() on how to allocate memory dynamically.


For example:

int length = strlen(text);
char *buf = malloc(length-pos+2); // +1 for null character, +1 for the inserved character, and -pos since we don't have to allocate the part of the string before pos.
sprintf(buf, "%c%s", c, text+pos);
strcpy(text+pos, buf);

#5022681 Enforcing inherited classes without pure virtual functions?

Posted by Brother Bob on 17 January 2013 - 04:45 PM

It means that you cannot put both the definition and the pure specifier on the declaration, not that a pure function cannot be defined. Solution:
struct C {
    virtual void f() = 0;

void C::f() {
edit: And yeah, that was new to me, actually. I thought you could do both, but MSVC doesn't complain about it even with language extensions disabled. Looks like G++ is doing the right thing though.

#5022603 Enforcing inherited classes without pure virtual functions?

Posted by Brother Bob on 17 January 2013 - 12:55 PM

Another way would be to mark the destructor of StaticMesh pure virtual, but also provide an implementation.



Yet another option would be to mark StaticMesh::Render as pure virtual (again leaving the implementation of it intact). This forces inheritors to override Render but still allows them to call the base implementation, although some people will find this confusing.


That's pretty odd! Is that valid C++? huh.png

Sure. There's nothing with pure virtual functions that stops you from providing an implementation and calling it.


In fact, a pure virtual destructor is required to have an implementation and to have it called. Not required by the language syntax, but a derived class' destructor will call its base class' destructor. If you don't provide an implementation for the destructor, you'll get an undefined external symbol linker error.

#5022507 Indexed vs Non-indexed primitives

Posted by Brother Bob on 17 January 2013 - 07:39 AM

I am trying to choose the right way for me. I am rewriting some parts of my engine and now i stand before this question.

I will use these indexed/nonindexed primitives only for imported models ( characters or objects ), not for terrains, particles.

The right way would depends on your particular usage and scenario. Advantages and disadvantages also change accordingly, as I mention in following quotes...


Let's say the advantages and disadvantages.


Advantages of indexed primitives:

  • Primitive can take less memory

They take less memory if you have enough shared vertices; otherwise the index buffer will be larger than the amount by which you can reduce the vertex buffer(s).

  • They are rendered faster ( because of first point ? )

Not necessarily. It probably will if you have enough shared vertices with a cache-friedly layout. Otherwise, you may be in for a performance hit.

Disadvantages of indexed primitives:

  • More complex models needs normals/bitangents/tangents/uvs/colours per vertex

You need exactly one attribute per vertex no matter what, so this is neither an advantage nor a disadvantage but a fundamental requirement for vertex arrays of any kind.

  • We have to bind two buffers, vertex and index

Not very big of a deal, but yeah, one more buffer to handle.

  • cache miss, if indexes not ordered propertly

That is correct, but not an inherent disadvantage of the index buffer itself, but rather a problem with an incorrect usage of them. You could say, though, that it adds extra complexity to ensure that it doesn't happen.

and nonindexed are opposite of these.

Not really. It doesn't have the added complexity of ensuring cache-friendly indexing, but the points in general are not the opposite. For example, the points with less memory and faster rendering is about using the correct type (non-indexed vs indexed) for a particular model, and not something that is true in general.


Is indexed primitives really faster to render for medium complex objects ( even, 50% of vertices needs different normals/tangents/.... so they are reperating actually ). Perhaps it's easy to answer, i would like to hear opinions from more experienced users.

If vertices needs different normals and such, they need to be duplicated no matter what. You cannot have same vertex with different attributes even with non-indexed buffers.


In general, advantages and disadvantages depends. It adds some complexity to ensure a cache-friendly indexing and it can result in faster rendering in comparison to non-indexed buffers. But it can also be worse. You need to profile and see if the there is actually an observable difference, and if it is worth the extra complexity.

#5022487 C++ sprintf float Decimal Degrees to Degrees Minutes Seconds

Posted by Brother Bob on 17 January 2013 - 05:37 AM

Round the value to an integer to get the integer part of the angle. Then subtract that from the real angle to get the decimal part, and multiply by 60 to convert to minutes.

float degrees = floor(lon);
float minutes = (lon - degrees) * 60;
sprintf(bufflon,"Longitude: %.0f degrees, %f minutes\n", degrees, minutes);

#5022187 Texture filtering modes and performance boosts

Posted by Brother Bob on 16 January 2013 - 08:44 AM

Mipmapping selects the mipmap level where the size of the texels matches the size of the pixels the best. This is good for the cache where rasterinzing adjacent pixels also means sampling adjacent texels. If, instead, the much larger base-level texture is selected (which is effectively what happens when you have a non-mipmapping filter), then the texels are much smaller than the pixels on the screen and sampling the texture for adjacent pixels means sampling very distant texels; this is very bad for the cache.


Mipmapping, especially full linear filtering on all dimensions, is computationally more expensive. But that is only a problem if you are computationally saturated. In your case, you are probably saturated by the memory transfer and so reducing that and increasing the computational complexity is an overall win.

#5021915 Unexpected program flow (templates / conversion operator).

Posted by Brother Bob on 15 January 2013 - 02:16 PM

You probably want the copy constructor and the assignment operator to take the parameter by const reference instead of by reference. For example, the return statement is Obj::get() takes an unexepected route because it cannot copy by the copy constructur; it would pass a temporary value to a function taking a non-const reference which is not legal.


The same problem applies to the assignment operator; the return value from Obj::get() is a temporary and cannot be passed to the assignment operator taking a non-const reference. But your assignment operator is behaving in an unexpected way anyway; it modifies the right-hand-side (sets ref.m_ref to zero) which is not the expected behavior of a copy-assignment. What you have implemented is the move-assignment operator disguised as the copy-assignment operator.

#5021592 Calculating matrices and then sending them or sending them and letting the GP...

Posted by Brother Bob on 14 January 2013 - 04:49 PM

The question is not whether it is faster to calculate the final MVP matrix on the CPU or the GPU, but whether it is faster to calculate it matrix once per model on the CPU or once per vertex on the GPU. But maybe the compiler could, theoretically, precompute the product just before the program is executed, but who knows.

You also have to consider where the bottle-neck is. Assume, for a moment, that is is actually faster to do the calculation in the shader on the GPU. If the GPU is saturated already, then offloading the multiplication to the CPU is a net-win, even if the individual operation is performed slower.

As always, benchmark to see where the problem is and how to rectify it.

#5021556 OpenGL shaders in Windows

Posted by Brother Bob on 14 January 2013 - 02:15 PM

Of course you can still use SDL. The two libraries mentioned above do not compete with SDL and can perfectly well be used together.