Q:

2D Animating in OpenGL

I am trying to animate a texture in OpenGL. I feel like it should be easy, as I know how to animate in SDL and other libraries but I am having trouble. I have a x,y,w,h that holds the texture coordinates for the frame I want. My vertex data has a x,y for the vertex, and a x,y for the texture coordinates. I know how to change these, but the problem is the width and height. How do I change these in a spritesheet? All I see is 2d vectors with no width or height. Am I overlooking something? Should I be doing this in the VBO, or in the vertex shader? I looked through several other related questions but they were all looking for what is the best strategy, or most optimizes or a unrelated to this animation question. 
Edit I realized I was looking at this the wrong way. I can show a portion of the texture, then decided which portion to look at, in the vertex shader very easily.

A:

You are indeed on the right mental path.
When you draw geometry, the vertex shader runs separately on each vertex of the geometry and transforms the positions into clip space, as well as letting you manipulate any associated attributes.
The fragment shader is invoked on each pixel that is considered to be covered by the geometry, and the attributes of the three vertices are interpolated across the triangle.
If you want to alter the position of your sprite in the view, you would alter the position attribute, either by editing the vertex buffer, or editing parameters to your shader with which you can offset the geometry in space. Similarly, you can alter the texture coordinates to decide which region of the texture you're interested in sampling from.
If you only draw one or a few sprites, what you do doesn't matter overly much performance-wise.
If you're interested in drawing them in bulk, you will run into several bottlenecks:

recalculating and storing the vertices of all your sprites has a CPU and memory cost;
uploading the geometry has a bandwidth and latency hit;
each draw call has a lot of overhead in the driver.

A common solution to this is instancing. Instead of binding a single set of vertex buffers that contain the vertex attributes for a mesh, you bind two sets.
One of the sets will be a set of vertices, describing a single piece of geometry.
The other set represents distinct instances of that master geometry, containing per-instance attributes.
If you previously had vertex attributes pos and tc in a configuration like this:
vertices = 
// position                        texcoord
{ {corner                        , tc_corner}
, {corner + float2(width, 0)     , tc_corner + float2(sprite_width, 0)            }
, {corner + float2(width, height), tc_corner + float2(sprite_width, sprite_height)}
, {corner + float2(0, height)    , tc_corner + float2(0, sprite_height)           } }

you would with instances be able to separate out the things that vary per instance, leaving you with a vertex buffer that can be reused across multiple sprites:
pervertex =
// position      texcoord
{ {float2(0, 0), float2(0, 0)}
, {float2(1, 0), float2(1, 0)}
, {float2(1, 1), float2(1, 1)}
, {float2(0, 1), float2(0, 1)} }

perinstance =
// world_pos  world_size             texture_pos  texture_size
{ {corner,    float2(width, height), tc_corner,   float2(sprite_width, sprite_height)}
, another_instance
, more_instances... }

From the perspective of the vertex shader, it's going to look just like a bunch of attributes, the distribution of per-vertex and per-instance attributes are done by the input assembly beforehand.
Your vertex shader would simply do the math along the lines of:
out_tc = texture_pos + tc * texture_size;
gl_Position = float4(world_pos + pos * world_size, 0.0, 1.0);

Note that instancing is not necessary to do this kind of thing, you can emulate it reasonably well by multiple draw calls and passing the per-instance parameters in uniform variables to your shader program.

