Jump to content

  • Log In with Google      Sign In   
  • Create Account

Brother Bob

Member Since 26 Nov 2001
Online Last Active Today, 05:02 AM

#5017111 Getting data from multiple vertex data

Posted by Brother Bob on 03 January 2013 - 08:34 AM

I want 2 VBOs but how? If I bind one buffer and then the next will the first buffer not be unbound? Or is it enough to bind the buffer, set the vertex attrib pointers and then unbind it again before the draw call?

Bind a VBO and set a pointer, then bind another VBO and set another pointer. Yes, the second binding will unbind the first one, but a vertex attribute pointer depends on the VBO binding when the pointer is set, not when the arrays are drawn.




#5015905 Miscellaneous OpenGL questions (mostly dealing with shaders)

Posted by Brother Bob on 30 December 2012 - 06:19 PM

Also, the enable and disable status of an attribute binding is a part of the vertex array object. When you bind the buffers and set the pointers, enable them within the vertex array object also and it will become a part of the binding. No need to enable and disable them in the render function.




#5015903 Miscellaneous OpenGL questions (mostly dealing with shaders)

Posted by Brother Bob on 30 December 2012 - 06:17 PM

There are a lot of old-style and deprecated functions still. But ignoring that, a quick search suggests that the built-in normal attribute is on location 2, not 1.


#5015859 BMP file problem

Posted by Brother Bob on 30 December 2012 - 03:07 PM

You have the error message and you have the code, so see the code where the error message comes from, and then look back in the code to see why the code gets to that point.




#5015716 Problem with ProjMatrix

Posted by Brother Bob on 30 December 2012 - 05:26 AM

You should not expect perspective and orthographic projections to give comparable results in general. They are fundamentally different projections.




#5015578 Miscellaneous OpenGL questions (mostly dealing with shaders)

Posted by Brother Bob on 29 December 2012 - 05:48 PM

The direct translation of that particular piece of code would look something like this:

// Bind the position attribute of the vertex array
glBindBuffer(GL_ARRAY_BUFFER, vbos[0]);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(positionLocation);
// Bind the normal attribute of the vertex array
glBindBuffer(GL_ARRAY_BUFFER, vbos[1]);
glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(normalLocation);
glUseProgram(shaderProgram);
glDrawArrays(GL_TRIANGLES, 0, model.getFaces().size() * 3);
glUseProgram(0);
glDisableVertexAttribArray(vertexLocation);
glDisableVertexAttribArray(normalLocation);
glBindBuffer(GL_ARRAY_BUFFER, 0);

But you also have to setup your shader infrastructure. You need to get the location of the position and the normal attribute so you can attach the correct attribute arrays to the correct attribute in the shader. You can use glGetAttribLocation to get the location of the index of an attribute so you can pass the location to glVertexAttribPointer and glEnableVertexAttribArray.

 

You also need to get a math library for matrices if you want to add the transformations from your first post.




#5015407 Function template problem

Posted by Brother Bob on 29 December 2012 - 06:32 AM

You can use std::enable_if, or the boost equivalent, to select specialization for different groups of types. For example, you can select integers and reals using something like this:

template<typename T> void foo(T v, typename std::enable_if<std::numeric_limits<T>::is_integer>::type * = nullptr)
{
    std::cout << "integer" << std::endl;
}
template<typename T> void foo(T v, typename std::enable_if<!std::numeric_limits<T>::is_integer>::type * = nullptr)
{
    std::cout << "real" << std::endl;
}
int main()
{
    foo(1); // int
    foo((short)2); // short
    foo(3.0); // double
    foo(4.0f); // float
}

int and short calls the integer variant, float and double calls the real variant, and std::enable_if is used to include/exclude certain templates from the name resolution.




#5015400 Adding/Removing from VBO at runtime

Posted by Brother Bob on 29 December 2012 - 05:27 AM

If by "object" you mean just a single quad, then you may prefer a single buffer object. I would definitely not create and recreate the buffer object, but try to manage the memory within it instead.

 

For example, make a buffer object large enough to hold all objects, or at least quite a few of them, and then fill it with as many objects as you need to begin with. After that, just add more objects to the end, or remove objects either by shifting the buffer or by swapping in the last object to the deleted position. if you add more objects than can be stored in the buffer object, then create a new, larger buffer, copy everything to it, and continue using the larger one instead. By memory mapping the buffer object, you get "direct access" to it as if it was a regular pointer and memory buffer and you can manipulate your buffer's memory as you like.

 

You could also use different buffer objects for sprites with different usage patterns. For example, a buffer object for static sprites that doesn't change, a buffer object for sprites that change but are always there, and a buffer object for dynamic sprites that are created and deleted in the fly.




#5015388 Adding/Removing from VBO at runtime

Posted by Brother Bob on 29 December 2012 - 04:40 AM

It seems like you're talking about whole objects, so why not keep the objects in their own buffer objects instead of all of them sharing one big buffer object? Then you don't have to manage one big buffer, but just manage many smaller ones so the other objects aren't affected when you add or remove other objects.




#5015261 How to check if dynamic memory is there before deleting?

Posted by Brother Bob on 28 December 2012 - 07:24 PM

Your solution is not wrong, but you may have misunderstood why it's not useful to check for null before deleting. It is not that your code won't work. the pointer is initially null, and if you allocate something, then the pointer is not null and it will be deleted. Likewise, if you don't allocate anything, then the pointer remains null and it won't delete it.

 

But that's not the issue. The "problem" is that calling delete on a null pointer is perfectly fine, so the if-statement is useless. Not incorrect, just useless. If ptr is null, then delete does nothing.




#5015258 Miscellaneous OpenGL questions (mostly dealing with shaders)

Posted by Brother Bob on 28 December 2012 - 07:07 PM

Ignoring exotic lighting techniques, it's typically enough to do them in the fragment shader when you draw the model. You don't see any effect of the lighting anywhere except for where the model is actually drawn. You need some kind of post-processing technique only if you want, say, halos or glows around very bright spots because they spread outside the model.




#5015248 Miscellaneous OpenGL questions (mostly dealing with shaders)

Posted by Brother Bob on 28 December 2012 - 06:36 PM

Thank you! So if the functions aren't listed at http://www.opengl.org/sdk/docs/man/ then I shouldn't use them if I want to use the modern approach. Learning OpenGL ES 2.0 should be very similar because it doesn't include any of the deprecated stuff as far as I know.

That seems to be the case, yes.

 

One more thing, I'm guessing per-pixel lighting via fragment shading is the modern approach.

Yes, fragment shaders are the way to do per-pixel lighting.

 

How do you apply a shader to the entire screen and not just a model?

That would depend on what kind of full-screen effect you want to do. You could, for example, render the scene to an off-screen texture and then draw the texture onto a full-screen quad. Use the desired fragment shader when drawing the quad.




#5015211 Miscellaneous OpenGL questions (mostly dealing with shaders)

Posted by Brother Bob on 28 December 2012 - 04:43 PM

Given that you say that you want to learn the modern approach, the answer to almost all of your questions are not relevant. In the code you posted, all functions except glBindBuffer, glUseProgram and glDrawArrays are deprecated,s o questions about them are not relevant in the context of your final goal.

  • Materials and coloring has to be done by yourself in the shader, so glColor and glMaterial are all out of the question; you have to implement lighting and all that yourself in the shaders.
  • Transformation has to be done by yourself and be uploaded to the shader programs as uniforms, so glPushMatrix, glRotate and all those functions are out of the question; you have to replace those with some other math library.
  • Vertex arrays has been generalized and the specific functions such as glVertexPointer, glNormalPointer adn glEnableClientState has been replaced with generic attributes such as glVertexAttribArray (one generic function for any kind of vertex attribute, not a specific function for specific vertex attributes) and glEnableVertexAttribArray.

Otherwise, your buffer object and program object binding seems to be fine in relation to where you bind, where you set vertex array pointers, where you draw the arrays and so on.




#5014708 how to avoid macro loops

Posted by Brother Bob on 27 December 2012 - 09:27 AM

Santa01 showed above how to get the log from the shader or program object. Your code has two major problems though:

  1. glGetShaderInfoLog expect you to allocate the buffer so that it can write the log to it. You're not allocating anything and so the function is writing to wherever the pointer happens to point. In this case, it's trashing the stack big time.
  2. infoLog is char *, and so infoLog itself is the string containing the log, not &intoLog. Output as a string is only overloaded for char * (with combinations of cv-qualifiers), but &infoLog is a char **  which just prints the address of the infoLog variable.



#5014501 OpenGL Triangle not being displayed

Posted by Brother Bob on 26 December 2012 - 03:27 PM

You're passing hDc and hRc to EnableOpenGL by value but expect the function to change the values in your main function since you're using those variables later. Pass them by reference instead if you expect the function to change the original variables and not the parameter variables local to the function itself. You're also not creating the device context anywhere; you need to call GetDC to actually get the value for hDc.

 

You're missing many of these errors because you're not checking the return values from the functions. You definitely should start checking for errors from the functions you call; they are there for a reason.






PARTNERS