Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!

Brother Bob

Member Since 26 Nov 2001
Offline Last Active Today, 06:18 AM

#5218604 Array of structure to VAO how to?

Posted by Brother Bob on 23 March 2015 - 03:02 PM

You have to sort that out with the index; pos_index, for example, is the index of your shader attribute you want to feed the pos data into.You can ask for the attribute location with glGetAttribLocation or explicitly specify its location using the layout specifier.

layout(location = 2) in vec3 position;

That defines your position attribute as a 3-component vector at location 2, which is the index you then pass to glVertexAttribPointer.

#5218579 Array of structure to VAO how to?

Posted by Brother Bob on 23 March 2015 - 02:02 PM

For each of the attributes, call glVertexAttribPointer with the appropriate set of parameters for attribute index, size, type and normalization. The key in using array-of-structure types with vertex arrays is in the stride and offset parameters.


The stride is the distance between two instances of an attributes. In your case, you pack all your vertex structure data between each attribute, so the stride is simply sizeof(V_INDEX). The pointer parameter is a pointer to the attribute within your vertex structure, or equivalently the offset of the attribute in the structure, so the pointer is simply offsetof(V_INDEX, pos) for example. You probably have to cast the integer result from offsetof to a void pointer type.

glVertexAttribPointer(pos_index, 3, GL_DOUBLE, FALSE, sizeof(V_INDEX), (void *)offsetof(V_INDEX, pos));
glVertexAttribPointer(uv_index, 2, GL_FLOAT, FALSE, sizeof(V_INDEX), (void *)offsetof(V_INDEX, uv));

#5218434 String replacing

Posted by Brother Bob on 23 March 2015 - 05:37 AM

Sigh... Do you have a solution without regex? The upgrade to C++11 turned out to be troublesome (some libs I use won't compile with C++11).

Jan2go gave another solution above. Use the find and replace repeatedly until the whole string has been searched and replaced.

#5218054 String replacing

Posted by Brother Bob on 21 March 2015 - 08:57 AM

A regular expression can do the job for you; it's in the <regex> header.

auto string = std::string("string\\nwith\\nembedded\\nnew-lines");
auto pattern = std::regex("\\\\n");
auto result = std::regex_replace(string, pattern, "\n");

std::cout << string << std::endl;
std::cout << result << std::endl;

The sub-string you want to search for is "\n", but the slash has to be escaped in the regular expression since the slash is a special character, so the actual regular expression pattern becomes "\\n". The two slashes has to be escaped again in the source code since they are special characters to the C++ compiler as well. Hence, the four back-slashes.

#5217312 C++ do while error

Posted by Brother Bob on 18 March 2015 - 04:32 AM

You can't start the do-whole loop outside the function.

#5216884 simple regex issue

Posted by Brother Bob on 16 March 2015 - 12:02 PM

The documentation seems to suggest that matches() returns true only if the entire string matches the regular expression. Your current expression can only match the entire string if it consists of a single digit.

#5215473 Picking a random value from array with priority

Posted by Brother Bob on 09 March 2015 - 01:30 PM

Your second option is possible if it is sufficient to only approximate the distribution of the individual elements. This is equivalent to generating random numbers with a different distribution, you example is biased towards the start of the array so a Laplacian distribution could make sense.


Another option that allows for fully arbitrary and individual weights is to keep a separate vector of weights corresponding to each element. Sum all the weights and generate a random number from 0 to to the sum. Loop through the array to find the point where the cumulative sum of all previous weights becomes greater than then generated random number.


An optimization on that variant is to keep an array of cumulative weights instead of the weights themselves. The last element is the sum of all elements, and you can now use a binary search algorithm to find the random number more efficiently.

#5213953 null a vector of pointers in a parameter?

Posted by Brother Bob on 02 March 2015 - 10:37 AM

A reference must refer to a valid object, but your null-pointer is not a valid vector object. If you want to pass an optional parameter, you can pass a pointer to the vector instead of a reference so you can pass a null-pointer to indicate the absence of a vector.

#5213633 Equation for Zooming

Posted by Brother Bob on 01 March 2015 - 04:02 AM

You want an exponential interpolation. An easy way to achieve that is to linearly interpolate in logarithmic domain.

  1. Calculate the logarithm of your two end points: logMinZoom = log(minZoom) and logMaxZoom = log(maxZoom).
  2. Linearly interpolate between logMinZoom and logMaxZoom in the desired number of steps: logZoom = logMinZoom + (logMaxZoom-logMinZoom)*step/(maxSteps-1).
  3. Transform logarithmic zoom to linear zoom: zoom = exp(logZoom).

This ensures that zoom increases or decreases with a uniform scale instead of with a uniform offset.

#5213538 General questions about matrix multiplications

Posted by Brother Bob on 28 February 2015 - 01:46 PM

Your first two points are correct, but the remaining ones doesn't make any sense. Row/column majorness of a matrix has nothing to do with matrix maths, what you can do with it and what the result of operations are. The majorness affects one and only one thing: how the two-dimensional grid of numbers representing the matrix is mapped to a one-dimensional linear memory storage. You have to store the matrix in some way in one-dimensional memory, and the majorness dictates where the individual matrix elements are stores in memory.

#5212300 glDrawElements (SEGAULT)

Posted by Brother Bob on 22 February 2015 - 12:32 PM

The vector object itself is just a small class that stores a few pointers, such as a pointer to the actual data you put into it, and some internal book-keeping information for things such as how much memory has been allocated, how much is actually used, and so on. You want the pointer to the data stored by the vector, not a pointer to the vector object itself. A pointer to the vector object just points to its internal private data.

#5212266 glDrawElements (SEGAULT)

Posted by Brother Bob on 22 February 2015 - 08:47 AM

You're passing pointers to the vectors to glBufferData, not the pointer to the data the vector contains. Also, pass the vectors by reference instead and skip the size parameter; the vector know its own size.

GLuint InitializeVBOs(std::vector<Vertex> &vertices)
    GLuint VBOid;
    glGenBuffers(1, &VBOid);
    glBindBuffer(GL_ARRAY_BUFFER, VBOid);
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
    return VBOid;

#5211970 Cannot initialize constant base member value

Posted by Brother Bob on 20 February 2015 - 01:33 PM

You need to initialize the base class members from the base class, you cannot do it from the derived classes.

class Block : public Entity
Block() : Entity(eIDError) {}
Block(EntityIDs id) : Entity(id) {}

#5211960 Cannot initialize constant base member value

Posted by Brother Bob on 20 February 2015 - 01:04 PM

Constant members can only be initialized in the constructor's initializer list, but there's no constructor in your base class to initialize it. Add a constructor that takes an ID so that the base class can initialize its member and call that base constructor from the derived classes.

class base
base(__int32 ID) : ID(ID) {}
const __int32 ID;

#5211873 Easiest way to pass a 2D array?

Posted by Brother Bob on 20 February 2015 - 06:18 AM

Pay closer attention to where the ampersand goes: clicky.


In any case, I suggest some dynamic array anyway. A two-dimensional array, or any-dimensional for the matter, can always be flattened into a one-dimensional storage so there's no need for vectors of vectors of vector of... how many dimensions you decide to have.

std::vector<int> storage(size_x * size_y);
int value = storage[y*size_x + x];

Wrap that up in a small class containing the storage and the dimensions, and provide some convenience function to access the storage based on two indices.