problem with glUniform2fv

Started by
8 comments, last by bluntman 12 years, 10 months ago
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:



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 + time * sec_speed[j];
if (t > 1.0f)
t -= 1.0f;
DATA_POINTS = t;
}
glUniform2fv(uni_pt, 3, (float*)&DATA_POINTS);
}



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 ?

Advertisement
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:


glUniform2fv(uni_pt, 3, (GLfloat*)DATA_POINTS);



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.
I replace the part of the code with your suggestion and it doesn't work. Actually, it still work for DATA_POINTS, the result is the same, but not for DATA_POINTS[i+1].






In that case please post more code. The entire program if it's not multiple files. Post the fail case as well.
So here's my code.

The fragment file:

//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);
}



and my source file

#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 + time * sec_speed[j];
if (t > 1.0f)
t -= 1.0f;
DATA_POINTS = 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;
}


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.

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 glValidateProgram, remember to get the program log results. Also try using gDEbugger see if it shows up any errors.
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.

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

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.



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!



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 glValidateProgram, remember to get the program log results. Also try using gDEbugger see if it shows up any errors.


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
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);

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


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..

This topic is closed to new replies.

Advertisement