Passing arrays to shader

Hi, I have two questions, I am implementing spherical harmonics lighting and trying to use GLSL for the real time part. I have an array consisting of 16 element with type of Color. Color is a class with R, G and B which are float. how should I pass this array to shader?

This is my vertex shader:


varying vec4 oColor;
varying vec3 oView;

uniform vec3 vf3Light[16];

void main()
{
	vec4 pos_MW = gl_ModelViewMatrix * gl_Vertex;
	gl_Position = gl_ProjectionMatrix * pos_MW;
	
	oView = pos_MW.xyz;
	oColor = vec4(0.0, 0.0, 0.0, 1.0);
	for(int i =0; i< 16; i++)
	{
		oColor.xyz += vf3Light[i];
		
	} 
}

and I want to send

Color *m_shCoeffRead;

to

uniform vec3 vf3Light[16];

.

I tried


int sh_location = glGetUniformLocation(SHShader.GetID(), "vf3Light");
	glUniform3fvARB(sh_location, 16, light_tex.m_shCoeffRead);

but I get the error!

My other question is that, for each vertex I have 16 coefficients which I’m reading them from a file and have to send them to my shader for calculating light, but I have no idea how to send them, I though about dividing them into 4 part and assign each part to a texture, but i don’t think it’s a good idea.

what is the error message? does adding casting fix the problem


glUniform3fv(sh_location, 16, (const GLfloat*) light_tex.m_shCoeffRead);

int sh_location = glGetUniformLocation(SHShader.GetID(), "vf3Light");
	glUniform3fvARB(sh_location, 16, light_tex.m_shCoeffRead);

This mixes the ARB extension GLSL functions (from ARB_shader_objects) with core GLSL functions. That is never a good idea. Just use the core functionality, not the functions that end in ARB.

As to the second question … take a look at Post234658.

Not certain, but sounds like you are trying to do something like


attribute mat4 transformmatrix;

void main()
{
    mat4 mvp = gl_ModelViewProjectionMatrix * transformmatrix;

    gl_Position = mvp * gl_Vertex;
}

which would have corresponding C code


int pos = glGetAttribLocation(shader_instancedarrays.program, "transformmatrix");
int pos1 = pos + 0; 
int pos2 = pos + 1; 
int pos3 = pos + 2; 
int pos4 = pos + 3; 
glEnableVertexAttribArray(pos1);
glEnableVertexAttribArray(pos2);
glEnableVertexAttribArray(pos3);
glEnableVertexAttribArray(pos4);
glBindBuffer(GL_ARRAY_BUFFER, VBO_containing_matrices);
glVertexAttribPointer(pos1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(0));
glVertexAttribPointer(pos2, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 4));
glVertexAttribPointer(pos3, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 8));
glVertexAttribPointer(pos4, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 12));

Reference here.

Can you explain why it’s not a good idea to use ARB?

yeah that can be what i want! A 4*4 matrix can work too, but is there any other ways without using VBO? I’m don’t know about vertex buffers and try to not to use it.

Can you explain why it’s not a good idea to use ARB?

Because it is ancient. It was only ever a test run for GLSL. The interaction between GLSL versions 1.10 and above are not defined when using ARB_shader_objects.

You shouldn’t be using it at all.

In general, if something is in core, you should use it as a core feature. Only if it is only available as an extension (or you need to support some version of OpenGL in which it is not core) should you do it. And you should never mix the two.

yeah that can be what i want! A 4*4 matrix can work too, but is there any other ways without using VBO? I’m don’t know about vertex buffers and try to not to use it.

The previosly noted reference talks about other methods but the VBO is the recommended one. It is well worth the effort to learn about VBOs.

tnx! :slight_smile:

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.