Sign in to follow this  
widggman

problem with glUniform2fv

Recommended Posts

Hey everyone,

I have a weird problem with glUniform2fv. I use it to update a variable "uniform vec2 name[3];" in my fragment shader. The only thing, is that only the x value of each vec2 is replaces, the y doesn't work. Here's the piece of code updating it:


[code]
static float DATA_POINTS[6] = {0.1, 0.1, 0.5, 0.5, 0.8, 0.7};
static float sec_speed[3] = {0.5f, 1.0f, 1.5f};
void updateData(float time)
{
for (int i = 0, j = 0; i < 6; i += 2, ++j)
{
float t = DATA_POINTS[i] + time * sec_speed[j];
if (t > 1.0f)
t -= 1.0f;
DATA_POINTS[i] = t;
}
glUniform2fv(uni_pt, 3, (float*)&DATA_POINTS);
}[/code]


this one works perfectly... but when I change it to DATA_POINTS[i + 1], to get my y coordinate in both places, the values are not updated at all. What am I missing here ?

Share this post


Link to post
Share on other sites
You don't need to take the address of DATA_POINTS (&DATA_POINTS) it is already a pointer to the start of the array. Try this:
[code]

glUniform2fv(uni_pt, 3, (GLfloat*)DATA_POINTS);
[/code]


I think what is probably happening is that DATA_POINTS (the pointer) happens to be followed by zeros in memory. The pointer is also 32bits, which happens to be the same size as GLfloat.

Share this post


Link to post
Share on other sites
So here's my code.

The fragment file:

[code]//uniform vec2 pt[3] = {vec2(0.1, 0.1), vec2(0.1, 0.5), vec2(0.8, 0.7)};
uniform float pt[6] = { 0.1, 0.1, 0.1, 0.5, 0.8, 0.7 };

void main()
{
float d1 = 0.5;
float d2 = 1.0;
/*
vec2 v0 = vec2(gl_TexCoord[0].x - pt[0].x, gl_TexCoord[0].y - pt[0].y);
vec2 v1 = vec2(gl_TexCoord[0].x - pt[1].x, gl_TexCoord[0].y - pt[1].y);
vec2 v2 = vec2(gl_TexCoord[0].x - pt[2].x, gl_TexCoord[0].y - pt[2].y);
/**/

vec2 v0 = vec2(gl_TexCoord[0].x - pt[0], gl_TexCoord[0].y - pt[1]);
vec2 v1 = vec2(gl_TexCoord[0].x - pt[2], gl_TexCoord[0].y - pt[3]);
vec2 v2 = vec2(gl_TexCoord[0].x - pt[4], gl_TexCoord[0].y - pt[5]);
/**/
float len0 = sqrt(v0*v0);
float len1 = sqrt(v1*v1);
float len2 = sqrt(v2*v2);

if (len0 < len1)
{
d1 = len0;
d2 = len1;
}
else
{
d1 = len1;
d2 = len0;
}
if (len2 < d1)
{
d2 = d1;
d1 = len2;
}
else if (len2 < d2)
d2 = len2;

float res = d1/d2;
gl_FragColor = vec4(res, res, res, 1.0);
}[/code]


and my source file

[code]#include <cstdlib>
#include <cstdio>
#include <sys/time.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>

using namespace std;

void clear_gl(int i);

char *frag = 0;

char *load_shader(const char *file_name)
{
ifstream in(file_name);
int sz = in.rdbuf()->pubseekoff (0,ios::end,ios::in);
in.rdbuf()->pubseekpos (0,ios::in);
char *buffer = new char[sz+1];

in.rdbuf()->sgetn(buffer, sz);
in.close();
return buffer;
}

GLuint sp = 0;
int uni_pt = 0;
void initGL(void)
{
int val;

glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, (const char**)&frag, NULL);
glCompileShader(fs);
val = glGetError();
if (val != GL_NO_ERROR)
{
cout << __LINE__ << " - The error is: " << gluErrorString(val) << endl;
clear_gl(1);
}

sp = glCreateProgram();
val = glGetError();
if (val != GL_NO_ERROR)
{
cout << __LINE__ << " - The error is: " << gluErrorString(val) << endl;
clear_gl(1);
}
glAttachShader(sp, fs);
val = glGetError();
if (val != GL_NO_ERROR)
{
cout << __LINE__ << " - The error is: " << gluErrorString(val) << endl;
clear_gl(1);
}
glLinkProgram(sp);
val = glGetError();
if (val != GL_NO_ERROR)
{
cout << __LINE__ << " - The error is: " << gluErrorString(val) << endl;
clear_gl(1);
}

glUseProgram(sp);
val = glGetError();
if (val != GL_NO_ERROR)
{
cout << __LINE__ << " - The error is: " << gluErrorString(val) << endl;
clear_gl(1);
}

uni_pt = glGetUniformLocation(sp, "pt");
val = glGetError();
if (val != GL_NO_ERROR)
{
cout << __LINE__ << " - The error is: " << gluErrorString(val) << endl;
clear_gl(1);
}
}

float random_value(void)
{
return (rand() % 16777217) / 16777216.0f;
}

static float DATA_POINTS[6] = {0.1, 0.1, 0.1, 0.5, 0.8, 0.7};
static float sec_speed[3] = {0.05f, 0.001f, 0.0005f};
void updateData(float time)
{
for (int i = 0, j = 0; j < 3; i += 2, ++j)
{
float t = DATA_POINTS[i] + time * sec_speed[j];
if (t > 1.0f)
t -= 1.0f;
DATA_POINTS[i] = t;

t = DATA_POINTS[i+1] + time * sec_speed[j];
if (t > 1.0f)
t -= 1.0f;
DATA_POINTS[i+1] = t;
}
glUniform1fv(uni_pt, 6, (float*)DATA_POINTS);
int val = glGetError();
if (val != GL_NO_ERROR)
{
cout << __LINE__ << " - The error is: " << gluErrorString(val) << endl;
clear_gl(1);
}
}

void clear_gl(int i)
{
if (frag) delete [] frag;

// TODO: clear everything
glDeleteProgram(sp);
cout << "CLEARING" << endl;
exit(i);
}

void resizeWindow (int width, int height)
{
glViewport(0, 0, width, height);

const GLdouble verticalFieldOfViewInDegrees = 60;
const GLdouble aspectRatio = (height == 0) ? 1.0 : (GLdouble) width / (GLdouble) height;
const GLdouble nearDistance = 1.0;
const GLdouble farDistance = 20.0;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(verticalFieldOfViewInDegrees, aspectRatio, nearDistance, farDistance);
glMatrixMode(GL_MODELVIEW);

glutPostRedisplay();
}

/**
* Compute the time elapse between now and the last frame.
*/
static int LAST_T;
float computeDT()
{
int CURR = glutGet(GLUT_ELAPSED_TIME);

float res = (CURR - LAST_T) * 0.001f;
if (res < 0.03333)
return -1.0f;
LAST_T = CURR;
return res < 0.001 ? 0.001 : res;
}

void displayWindow ()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glLoadIdentity();
glTranslatef(0.0f, 0.0f, -2.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.1f, 1.1f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();

glutSwapBuffers();
}

void idle ()
{
const double DT = computeDT();
if (DT >= 0.0f)
{
updateData(DT);
cout << DT << endl;
}
glutPostRedisplay();
}

extern void switch_function_in_system(void);
void normalKeyPressed(unsigned char character, int x, int y)
{
switch(character)
{
case 27:
clear_gl(0);
break;
}
//glutPostRedisplay();
}

void processMouse(int button, int state, int x, int y)
{
}

void processMouseActiveMotion(int x, int y)
{
}

int main(int argc, char **argv)
{
srand(time(0));

frag = load_shader("frag.txt");

//Setup general facilities.
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_STENCIL | GLUT_MULTISAMPLE);
glutInitWindowSize (512, 512);
glutCreateWindow("GLSL test");

//Specify function handlers.
glutDisplayFunc(displayWindow);
glutReshapeFunc(resizeWindow);
glutKeyboardFunc(normalKeyPressed);
glutMouseFunc(processMouse);
glutMotionFunc(processMouseActiveMotion);
glutIdleFunc(idle);

LAST_T = glutGet(GLUT_ELAPSED_TIME);

initGL();
glutMainLoop ();
return 0;
}
[/code]

I also tried to replace my vec2 pt[3] by float pt[6], but the problem is the same!


see function "updateData" for the source of the problem! But it can be somewhere else too.

Share this post


Link to post
Share on other sites
Sorry can't see the problem. You are using array initialization in the shader which is a nVidia extension as far as I know. I can't arrays to work AT ALL on ATI. My programs will build but program validation fails. Try doing [url="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml"]glValidateProgram[/url], remember to get the program log results. Also try using gDEbugger see if it shows up any errors.

Share this post


Link to post
Share on other sites
How exactly are you testing the values in the shader? You have a random equation of variables that output some color. How do you conclude that it is just the y values? Can you just output:

glFragColor(pt[n], pt[n],pt[n], 1.0);

Where you recompile for n = 0 through 6 and manually verify. I just don't see in that code how well your getting any feedback of whats in the arrays.

Share this post


Link to post
Share on other sites
[quote name='dpadam450' timestamp='1307127035' post='4819174']How exactly are you testing the values in the shader? You have a random equation of variables that output some color. How do you conclude that it is just the y values? Can you just output:

glFragColor(pt[n], pt[n],pt[n], 1.0);

Where you recompile for n = 0 through 6 and manually verify. I just don't see in that code how well your getting any feedback of whats in the arrays.
[/quote]


Okay... so the problem is not that the information with glUniform is not transfered. I tried your suggestion, and for each of them, the new value was there.

So the problem is in my logic in the shader.

Thanks everyone!

Share this post


Link to post
Share on other sites
[quote name='bluntman' timestamp='1307122801' post='4819147']
Sorry can't see the problem. You are using array initialization in the shader which is a nVidia extension as far as I know. I can't arrays to work AT ALL on ATI. My programs will build but program validation fails. Try doing [url="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml"]glValidateProgram[/url], remember to get the program log results. Also try using gDEbugger see if it shows up any errors.
[/quote]

It was probably introduced in one of the GLSL versions. I'm too lazy to look it up now.
Also, it is a good idea to declare the #version at the top of the shader otherwise you migt get GLSL 1.10

Share this post


Link to post
Share on other sites
[quote name='V-man' timestamp='1307134137' post='4819216']
It was probably introduced in one of the GLSL versions. I'm too lazy to look it up now.
Also, it is a good idea to declare the #version at the top of the shader otherwise you migt get GLSL 1.10
[/quote]

Yeah I specify #version 330 in my shaders and they still refuse to validate with arrays in them. The nVidia OpenGL SDK examples that use arrays also fail to work (although they use uniform initialization in the shader code itself). Latest ATI drivers and everything..

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this