Why can't more people be like you? I have been trying to get this message across to one of my coworkers for 9 months. He has trouble seeing that means to an end are just that. We are constantly getting in fights because he has this set of behavior in his mind that we should be sticking to, but has no concept of actions->results.Get out of the habit of thinking of patterns as something you can have opinions on. Patterns are a description of existing practices, not a prescription or a technique. Understanding the way programs are structured is important, but trying to use 'design patterns' like building blocks, especially where you start talking about one somehow being 'better' than another, is just a recipe for bad code.
And, incidentally, static methods are an implementation of the 'singleton design pattern.' They are not what's usually called a singleton in C++, but they are singletons in the broader pattern sense.
Isn't a singleton more of an anti-pattern?
Why can't more people be like you? I have been trying to get this message across to one of my coworkers for 9 months.
I know this is the C++ thread, but are any of you by chance decently familiar with OpenGL?
Sure!
Right now I have two different vertex buffer objects, one ui elements and one for non ui elements, but it seems like even though I'm packing more than one set of vertices into the buffers at a time I only have one quad for each vertex buffer.
// Args: Mode, data type, stride, offset pointer
// 8*sizeof(GL_FLOAT) for stride because structure is FACE1:nor:f,f,f;tri:f,f,f;tex:f,f;FACE2...
glVertexPointer(GL_TRIANGLES, GL_FLOAT, 8*sizeof(GLfloat), &[gameData polydata][3]);
// Args: Mode, offset, data length
glDrawArrays(GL_TRIANGLES,[reference offset], [[reference faces]count]*3);
I'd have to look at the code, I think.stuff
I'd have to look at the code, I think.
It seems to me that you're using glVertexAttribPointer() wrong. The second argument should be the number of elements for the data type you're describing. So, for example, if you're describing Position, the second argument should be 2. Not sizeof(vertexStruct).
You should wrap this section with glGetError() to see what's up. My guess is it'll respond with GL_INVALID_VALUE because size isn't 1, 2, 3 or 4.
(Just add a call to glGetError() and write its return value into a field, then look up the error code)
Also, for debugging purposes, it would be wise to concentrate on one thing at a time. Just try to paint triangles right first.
I think you're mis-remembering that glVertexAttribPointer code. Aside from what wolfmat mentioned, your 3rd argument is entirely wrong - none of your attribute scalars is of type unsigned int (they're all floats). So checking the actual code is a good idea ; )Derp, I meant glDrawElements.
I think I'm doing something like:
glVertexAttribPointer(getPositionAttrib(), sizeof(vertexStruct), GL_UNSIGNED, false, sizeof(vertexStruct), 0);
glVertexAttribPointer(getDiffuseAttrib(), sizeof(vertexStruct), GL_UNSIGNED, false, sizeof(vertexStruct), sizeof(float) *2);
glVertexAttribPointer(getDiffuseAttrib(), sizeof(vertexStruct), GL_UNSIGNED, false, sizeof(vertexStruct), sizeof(float) *5);
glVertexAttribPointer(getTexCoordsAttrib(), sizeofVertexStruct), , GL_UNSIGNED, false, sizeof(vertexStruct), sizeof(float) *8);
//glUniformStuff goes here
glDrawElements(GL_TRIANGLESTRIP, i forget what I have for the rest...)
my vertexStructure is:
struct{
float[2] Position,
float[3] Diffuse,
float[3] Tint,
float[2] Texture,
}
This is all inexact as I don't have the code in front of me.
I can properly draw quads that are textured correctly I just can't get see to get more than 1 per vbo.
I'll post more of the code when I get to work tomorrow.
Quick question about something I'm not quite fully understanding, sorry if it's a dumb question but if someone could please explain.
When dealing with a dynamically allocated array of structures it says since you have an address, you can't use the . operator so you access members in two ways
ps->price or (*ps).price
But if you're dealing with an array of structures, and using a for loop to get values into members these two don't work:
ps->price or (*ps + i).price
Instead it seems to work if you just use the regular old . as in
ps.price
Could someone please explain to me why it works this way? It just doesn't seem to make sense to me why the rules would change because it seems to only apply when I'm using an index.
typedef Gaf* psPtr; //declare pointer to structure
psPtr psList = new Gaf[10]; //dynamically allocate array of structure instances
psList[0] ->price = whatever;
KorrZ, all of those could potentially be valid C++, depending on what you're trying to do and what context they're in. It would help if you showed how you declared the array you were talking about. Particularly, I think, in making clearer examples.
struct bob
{
std::string name;
double amount;
};
bob * ps = new bob[size];
for (int i = 0; i < size; i++)
{
std::cout << "Enter name: ";
getline(std::cin, ps[i].name);
std::cout << "Enter amount: ";
std::cin >> ps[i].amount;
}
bob * ps = new bob;
std::cin >> ps->amount;
The thing with an immediate mode library is that it'll silently fail a lot of the time. Often enough, this results in partial drawing and the like. The draw call succeeded after all up until this-and-that error occured. That's why you should always check if everything's free of errors with glGetError() at least everytime you add or alter OGL statements.
Edit: Don't forget to remove the glGetError() calls as soon as you don't need them, they kill performance.
void Effect::BindSimpleVertexAttributes()
{
attributes[ATTRIB_POSITION] = glGetAttribLocation(ShaderProgramObj, "Position");
attributes[ATTRIB_DIFFUSE] = glGetAttribLocation(ShaderProgramObj, "DiffuseSource");
attributes[ATTRIB_TINT] = glGetAttribLocation(ShaderProgramObj, "TintSource");
//attributes[ATTRIB_BRIGHTNESS] = glGetAttribLocation(ShaderProgramObj, "BrightnessSource");
glEnableVertexAttribArray(GetAttributeLocation(ATTRIB_POSITION));
glEnableVertexAttribArray(GetAttributeLocation(ATTRIB_DIFFUSE));
glEnableVertexAttribArray(GetAttributeLocation(ATTRIB_TINT));
//glEnableVertexAttribArray(GetAttributeLocation(ATTRIB_BRIGHTNESS));
uniforms[UNIFORM_VIEWPROJECTION_MATRIX] = glGetUniformLocation(ShaderProgramObj, "ViewProjection");
attributes[ATTRIB_TEXCOORD0] = glGetAttribLocation(ShaderProgramObj, "TexCoordIn");
glEnableVertexAttribArray(GetAttributeLocation(ATTRIB_TEXCOORD0));
uniforms[UNIFORM_TEXTURE_SAMPLER] = glGetUniformLocation(ShaderProgramObj, "Texture");
}
GLuint m_simpleVertexBuffer;
glGenBuffers(1, &m_simpleVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_simpleVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_simpleVertices), &m_simpleVertices, GL_STATIC_DRAW);
(where m_simpleVertices right now is just an array of vertex structures with position coordinates, texture coordinates and floats)
(This is what a vertex struct element looks like:)
typedef struct {
float Position[3];
float Diffuse[4];
float Tint[4];
float Texture[2];
} SimpleVertex;
void GLESDevice::SetSimpleVertexAttribs()
{
const GLKMatrix4 *viewProjection = m_CurrentEffect->GetMatrix("ViewProjection");
glUniformMatrix4fv(m_CurrentEffect->GetUniformLocation(UNIFORM_VIEWPROJECTION_MATRIX), 1, 0, viewProjection->m);
glViewport(0, 0, Height, Width);
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_POSITION), 3, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), 0);
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_DIFFUSE), 4, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), (GLvoid*) (sizeof(float) * 3));
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_TINT), 4, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), (GLvoid*) (sizeof(float) * 7));
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_TEXCOORD0), 2, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), (GLvoid*) (sizeof(float) * 11));
glUniform1i(m_CurrentEffect->GetUniformLocation(UNIFORM_TEXTURE_SAMPLER), 0);
}
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glBindVertexArrayOES(m_vertexArray);
glDrawElements(GL_TRIANGLES, sizeof(m_simpleIndices)/sizeof(m_simpleIndices[0]), GL_UNSIGNED_BYTE, 0);
That was very eloquent. And, yes, dabig2 describes it accurately.
I prefer just to remember what it is that I'm actually trying to store. When I say 'new bob[size]' I am getting a pointer to an array of 'bob' objects. When I say 'new bob' I am getting a pointer to a 'bob' object. To me, it's thus obvious that the array requires '.' and the single object requires use '->'.
This understanding depends on the fact that operator[] behaves identically for both pointers to arrays and for arrays themselves. (Which can be further explained, if need be, but the gist of it is that an array object is only barely distinguished from a pointer itself.)
PS. We miss you, cpp_is_king.
Well, this is just one buffer. I thought you wanted two.All right, so here's a more complete version of what I'm doing:
3. Bind the vertex buffer object
Code:GLuint m_simpleVertexBuffer; glGenBuffers(1, &m_simpleVertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_simpleVertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(m_simpleVertices), &m_simpleVertices, GL_STATIC_DRAW); (where m_simpleVertices right now is just an array of vertex structures with position coordinates, texture coordinates and floats)
You need to bind the buffer you want to draw with glBindBuffer(). If you bind when you create the buffer, and never again, the last created buffer will stay bound, and that's it. That might lead to your problem. It actually looks like that's what you're doing.5. And finally draw
Code:glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glBindVertexArrayOES(m_vertexArray); glDrawElements(GL_TRIANGLES, sizeof(m_simpleIndices)/sizeof(m_simpleIndices[0]), GL_UNSIGNED_BYTE, 0);
And I just noticed that: glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_POSITION), 3, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), 0);
Is causing glGetError() to return GL_INVALID_OPERATION. Weird.
if (m_CurrentEffect->GetShaderName() == "Effects/SimpleVertex")
{
m_simpleVertexList = data->GetSimpleVertex();
for (int i=0;i<m_simpleVertexList.size();i++)
{
m_simpleVertices[i] = m_simpleVertexList[i];
}
glGenVertexArraysOES(1, &m_simpleVertexArray);
glBindVertexArrayOES(m_simpleVertexArray);
glGenBuffers(1, &m_simpleVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_simpleVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_simpleVertices), &m_simpleVertices, GL_STATIC_DRAW);
}
else if (m_CurrentEffect->GetShaderName() == "Effects/UIVertex")
{
m_uiVertexList = data->GetUIVertex();
for (int i=0;i<m_uiVertexList.size();i++)
{
m_uiVertices[i] = m_uiVertexList[i];
}
glGenVertexArraysOES(1, &m_uiVertexArray);
glBindVertexArrayOES(m_uiVertexArray);
glGenBuffers(1, &m_uiVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_uiVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_uiVertices), &m_uiVertices, GL_STATIC_DRAW);
}
if (!m_CurrentEffect)
{
cout<<"Bad shader!"<<endl;
return false;
}
if (m_CurrentEffect->GetShaderName() == "Effects/SimpleVertex")
{
SetSimpleVertexAttribs();
glDrawArrays(GL_TRIANGLES, 0, m_simpleVertexList.size());
glBindVertexArrayOES(0);
}
else if (m_CurrentEffect->GetShaderName() == "Effects/UIVertex")
{
SetUIVertexAttribs();
glDrawArrays(GL_TRIANGLES, 0, m_uiVertexList.size());
glBindVertexArrayOES(0);
}
void GLESDevice::SetSimpleVertexAttribs()
{
const GLKMatrix4 *viewProjection = m_CurrentEffect->GetMatrix("ViewProjection");
glUniformMatrix4fv(m_CurrentEffect->GetUniformLocation(UNIFORM_VIEWPROJECTION_MATRIX), 1, 0, viewProjection->m);
glViewport(0, 0, Height, Width);
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_POSITION), 3, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), 0);
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_DIFFUSE), 4, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), (GLvoid*) (sizeof(float) * 3));
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_TINT), 4, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), (GLvoid*) (sizeof(float) * 7));
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_TEXCOORD0), 2, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), (GLvoid*) (sizeof(float) * 11));
glUniform1i(m_CurrentEffect->GetUniformLocation(UNIFORM_TEXTURE_SAMPLER), 0);
}
void GLESDevice::SetUIVertexAttribs()
{
const GLKMatrix4 *viewProjection = m_CurrentEffect->GetMatrix("ViewProjection");
glUniformMatrix4fv(m_CurrentEffect->GetUniformLocation(UNIFORM_VIEWPROJECTION_MATRIX), 1, 0, viewProjection->m);
glViewport(0, 0, Height, Width);
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_POSITION), 3, GL_FLOAT, GL_FALSE, 0, 0);
m_lastError = glGetError();
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_DIFFUSE), 4, GL_FLOAT, GL_FALSE, sizeof(UIVertex), (GLvoid*) (sizeof(float) * 3));
m_lastError = glGetError();
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_TINT), 4, GL_FLOAT, GL_FALSE, sizeof(UIVertex), (GLvoid*) (sizeof(float) * 7));
m_lastError = glGetError();
glVertexAttribPointer(m_CurrentEffect->GetAttributeLocation(ATTRIB_TEXCOORD0), 2, GL_FLOAT, GL_FALSE, sizeof(UIVertex), (GLvoid*) (sizeof(float) * 11));
m_lastError = glGetError();
glUniform1i(m_CurrentEffect->GetUniformLocation(UNIFORM_TEXTURE_SAMPLER), 0);
m_lastError = glGetError();
}
Not necessarily; I was just going by what you were saying in the original posting you said you wanted multiple VBOs (and you can do that, and it makes sense, as long as you're not going crazy with it). Of course you can have one VBO with all objects in it. It completely depends on what you're aiming for.So to clear this up, do I want a buffer for every object on screen, or just every object associated with a particular type of shader?
Well, now that you have multiple buffers: Every time you want to draw a buffer, you need to bind it beforehand. Then draw it according to the index buffer.To be more clear I have the following right now:
Code:glGenBuffers(1, &m_simpleVertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_simpleVertexBuffer); glGenBuffers(1, &m_uiVertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_uiVertexBuffer); if (m_CurrentEffect->GetShaderName() == "Effects/SimpleVertex") { m_simpleVertexList = data->GetSimpleVertex(); for (int i=0;i<m_simpleVertexList.size();i++) { m_simpleVertices[i] = m_simpleVertexList[i]; } glGenBuffers(1, &m_simpleVertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_simpleVertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(m_simpleVertices), &m_simpleVertices, GL_STATIC_DRAW);/ }
glBindBuffer(GL_ARRAY_BUFFER, vboCoords1); // vertex coords
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices1); // indices
// vertex array stuff
glEnableClientState(GL_VERTEX_ARRAY); // vertex coords are in an array
glVertexPointer(3, GL_FLOAT, 0, 0); // trivial triangle setup without stride
// draw 6 quads with an offset following out of index array -- this will pull data from vbo 1
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);
// Switch to another VBO
glBindBuffer(GL_ARRAY_BUFFER, vboCoords2); // vertex coords
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices2); // indices
// draw 6 quads with an offset following out of index array -- this will pull data from vbo 2
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);
glDisableClientState(GL_VERTEX_ARRAY); // done with the vertex array
// bind with 0 -- no more VBOs this frame, the end
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Lets say I have one VBO/VBA pair for my UI elements, how do I make it draw all of them at once? I assume I put all the vertices into one data structure, bind it to the VBO and then draw?
Pretty much. Got to obviously adhere to the structure (triangle strips, count etc), but that's what you do. If you're doing glDrawElements(), you need to use an index array, also. And that has to be in a VBO as well (I think, maybe you can mix there). And then you're done!
I switched away from glDrawElements earlier today, so right now I'm drawing using glDrawArrays. My non vertex stuff seems to drawing a bit better after some reorganization thanks to your tips but the UI stuff is still borked (although I also need to fix the UI shader as I'm still trying to port that from HLSL to GLSL). Then again I'm also getting a weird crash when copying lists that is new too.
For my algorithms class I need to do lab write ups about sort algorithms, usually doing best, worst, and average cases and recording their times. For merge sort, I shouldn't need to do that because the time complexity is the same for each of them, right? If I do, how would I do that?
Don't know whether this is c++ specific or visual studio, but I'm currently working in c++.
I'm trying to debug and have command line arguments, I'm trying to pass in a .txt file. However I don't know how to pass it in. I've already declared the command line arguments in the properties. But I need to pass in a specific file. Any clue?
$(pathfile)?
http://msdn.microsoft.com/en-us/library/ekbzk5f8.aspx
#include <iostream>
using namespace std;
int main ( )
{
int stall;
cout << "--------------------------------------------------------------------------------\n";
cout << "| |\n";
cout << "| |\n";
cout << "| |\n";
cout << "| |\n";
cout << "| |\n";
cout << "| |\n";
cout << "| |\n";
cout << "| |\n";
cout << "| |\n";
cout << "--------------------------------------------------------------------------------\n";
cin >> stall;
return 0;
}
Hey, guys. Pretty much, trying to make a program with a box with info in it for a gift certificate for her bday in about an hour and a half.
Issue is, the EXE gives a 'blahblah.dll not found' error on other computers.
Does anyone know how to fix this without them installing stuff?
code looks like this:
Thanks in advance!
Educated guess: whatever compiler you're using has that dll packaged with it. Copy it over with with exe to the computer you want to run it on.Hey, guys. Pretty much, trying to make a program with a box with info in it for a gift certificate for her bday in about an hour and a half.
Issue is, the EXE gives a 'blahblah.dll not found' error on other computers.
Thanks in advance!
What did you creat the project with? Was it a wizard in Visual Studio?
What's the "blahblah.dll" exactly? It makes a difference. You might be linking in some debug dll that an "ordinary" machine won't have...