Passing TexCoords to GLSL

Started by
4 comments, last by 21st Century Moose 12 years, 7 months ago
This is how I think my program works, and how I want it to work.
  • Program creates a OpenGL program
  • Program creates VBO's
  • VBO's are drawn using the shaders.
  • The result is drawn to screen.
So basically now I want to pass not only my Vertex data to the Shaders but the Tex-Coords as well.
I would think I would need to add another in variable. However I don't understand how the program knows which variables to pass the Vertices to and which to pass the Tex-Coords to.

I included all 4 parts that I use, the main parts being the scene.draw and the 2 shaders, However I included the main.cpp as well

Is there a way I need to tell it that "in vec3 in_vertex;" is for the verticies and "in vec2 in_coord;" is for the texCoords?

Something is just not right, the image is drawing incorrecly. I think it's the texcoords are wrong.

Moving from OpenGL 1.1 seems like an problem with infinite steps to the solution.

Thanks in advance!

CoderWalker

Main.cpp
#include "fv.h"
#include "math.h"

//3d Data
fv::scene* mainScene;

//Draw Data
static const GLfloat g_vertex_buffer_data2[] = {
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
static const GLushort g_element_buffer_data[] = { 0, 1, 2, 3 };
std::vector<fVertex3d> g_vertex_buffer_data;

std::vector<vert> vertexData;
//Resources
static struct
{
GLuint program;
struct
{
GLint fade_factor;
GLint xSin,xCos;
GLint textures[2];
} uniforms;
struct
{
GLint position;
} attributes;
GLfloat fade_factor;
GLfloat xSin,xCos;
GLuint vBuffer, eBuffer;
GLuint textures[2];
} resources;
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//GLprogram related
glUseProgram(resources.program);

glUniform1f(resources.uniforms.fade_factor, resources.fade_factor);

glUniform1f(resources.uniforms.xSin, resources.xSin);

glUniform1f(resources.uniforms.xCos, resources.xCos);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, resources.textures[0]);
glUniform1i(resources.uniforms.textures[0], 0);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, resources.textures[1]);
glUniform1i(resources.uniforms.textures[1], 1);

mainScene->draw();
SDL_GL_SwapBuffers();
}
static void update()
{
int milliseconds = SDL_GetTicks();
//resources.fade_factor = sin((float)milliseconds * 0.001f) * 0.5f + 0.5f;
resources.fade_factor = (float)milliseconds;
resources.xCos = cos((float)milliseconds * 0.001f);
resources.xSin = sin((float)milliseconds * 0.001f);
//glutPostRedisplay();
SDL_Event event;
while( SDL_PollEvent( &event ) )
{
//Handle key presses
if( event.type == SDL_QUIT )
{
//quit
}
}
}
inline void addVert(float x, float y, float z)
{
fVertex3d tmp;
tmp.x = x;
tmp.y = y;
tmp.z = z;
g_vertex_buffer_data.push_back(tmp);
}
inline void newVert(float x, float y, float z, float tx, float ty)
{
vert tmp;
tmp.x = x;
tmp.y = y;
tmp.z = z;
tmp.tx = tx;
tmp.ty = ty;
vertexData.push_back(tmp);
}
int main( int argc, char *argv[] )
{
fv::init();
fv::createWindow(640,480,32,"OpenGL 2.0 drawing");
fv::gl::initAdvanced();
glEnable(GL_DEPTH_TEST);

//Create the scene
mainScene = new fv::scene();
//Create a model
vertexData.clear();
newVert(-1,-1,-1, 0, 1);
newVert( 1,-1,-1, 1, 1);
newVert(-1, 1,-1, 0, 0);
newVert( 1, 1,-1, 1, 0);
/*newVert(-1,-1, 1, 0, 1);
newVert( 1,-1, 1, 1, 1);
newVert(-1, 1, 1, 0, 0);
newVert( 1, 1, 1, 1, 0);

newVert(-1,-1,-1, 0, 1);
newVert( 1,-1,-1, 1, 1);
newVert(-1,-1, 1, 0, 0);
newVert( 1,-1, 1, 1, 0);
newVert(-1, 1,-1, 0, 1);
newVert( 1, 1,-1, 1, 1);
newVert(-1, 1, 1, 0, 0);
newVert( 1, 1, 1, 1, 0);

newVert(-1,-1,-1, 0, 1);
newVert(-1,-1, 1, 1, 1);
newVert(-1, 1,-1, 0, 0);
newVert(-1, 1, 1, 1, 0);
newVert( 1,-1,-1, 0, 1);
newVert( 1,-1, 1, 1, 1);
newVert( 1, 1,-1, 0, 0);
newVert( 1, 1, 1, 1, 0);*/
fv::model* cube = new fv::model(&vertexData[0],vertexData.size());
mainScene->add(cube);

//Load textures and Program
resources.textures[0] = fv::file::loadTexture("crate.png");
resources.textures[1] = fv::file::loadTexture("sonic.png");
resources.program = fv::gl::loadShaders("fvDraw.f.glsl","fvDraw.v.glsl");
//Get Program variable locations
resources.uniforms.fade_factor = glGetUniformLocation(resources.program, "fade_factor");
resources.uniforms.xSin = glGetUniformLocation(resources.program, "xSin");
resources.uniforms.xCos = glGetUniformLocation(resources.program, "xCos");
resources.uniforms.textures[0] = glGetUniformLocation(resources.program, "textures[0]");
resources.uniforms.textures[1] = glGetUniformLocation(resources.program, "textures[1]");
resources.attributes.position = glGetAttribLocation(resources.program, "position");
fv::gl::vertVar = resources.attributes.position;
while (1)
{
render();
update();
}
return 0;
}

Scene.render()
void scene::draw()
{
int len = objects.size();
for (int i=0; i<len; i++)
{
//Set the buffers as the supplying data
glBindBuffer(GL_ARRAY_BUFFER, objects->buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vert), BUFFER_OFFSET(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vert), BUFFER_OFFSET(12));
//Draw
//glEnableVertexAttribArray(gl::vertVar);
glDrawArrays(GL_TRIANGLE_STRIP,0,objects->size);
//glDisableVertexAttribArray(gl::vertVar);
}
}

fvDraw.v.glsl
#version 140

uniform float fade_factor;
uniform float xSin;
uniform float xCos;

in vec3 in_vertex;
in vec2 in_coord;

out vec2 out_coord;

void main()
{
float time = fade_factor*0.001;
mat3 rotation = mat3(
vec3(0.75, 0.0, 0.0),
vec3(0.0, cos(time), sin(time)),
vec3( 0.0, -sin(time), cos(time))
);

gl_Position = vec4(in_vertex*rotation,1.0);
//texcoord.x = position.x * -0.5 + 0.5;
//texcoord.y = position.y * -0.5 + 0.5;
out_coord = in_coord;
}


fvDraw.f.glsl
#version 140

in float fade_factor;
uniform sampler2D textures[2];

in vec2 out_coord;

void main()
{
gl_FragColor = mix(
texture2D(textures[0], out_coord),
texture2D(textures[1], out_coord),
sin(fade_factor)
);
}
If this post was helpful please +1 or like it !

Webstrand
Advertisement
From this

glBindBuffer(GL_ARRAY_BUFFER, objects->buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vert), BUFFER_OFFSET(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vert), BUFFER_OFFSET(12));

I would say that yo have interleaved your vertices and texcoords. Which is fine.
I didn't see how you are creating your VBO so you should check that out.

Also, I didn't see it but you need to use glGetAttribLocation to get the location for our "in vertex" and "in texcoord".
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

From this

glBindBuffer(GL_ARRAY_BUFFER, objects->buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vert), BUFFER_OFFSET(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vert), BUFFER_OFFSET(12));

I would say that yo have interleaved your vertices and texcoords. Which is fine.
I didn't see how you are creating your VBO so you should check that out.

Also, I didn't see it but you need to use glGetAttribLocation to get the location for our "in vertex" and "in texcoord".


Yea, they are interleaved like the following. I thought interleaved was best for speed?
struct vert
{
float x,y,z;
float tx,ty;
float nx,ny,nz;
};


Also do I need to find their locations? If so, once I find them (in vertex. in texcoord)how do I pass the data to them?
If this post was helpful please +1 or like it !

Webstrand


[quote name='coderWalker' timestamp='1316141065' post='4862297']
Also, I didn't see it but you need to use glGetAttribLocation to get the location for our "in vertex" and "in texcoord".



^^ this ^^

The results returned from the TWO calls to glGetAttribLocation you need (one for the verts, one for the textcoords) , should return two int values, which can then be used for the first args to glVertexAttribPointer (inplace of the 0 and 1 you have there currently)
[color=#1C2837][size=2]
Yea, they are interleaved like the following. I thought interleaved was best for speed?[/quote]
[color=#1C2837][size=2]

[color=#1C2837][size=2]Yes, I have not tested it, but its because the data is close in memory so they having the tex coords right next to the current vertex, the tex coords should be loaded into the cache right along with the vertex.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

In the old software T&L days non-interleaved was considered preferable; you would find examples where position was padded to 4 bytes for more optimal SIMD performance. In hardware T&L days this is irrelevant; transforms happen on the GPU and cache locality is more important.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement