openframeworks / openframeworks/openFrameworks

Setting uniform arrays using index

Open
#4,444 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
10.4k
Forks
2.6k
Avg merge
1d 21h
Merged PRs (30d)
9

Description

I was working with some shadow mapping code I had and noticed it wasn't working, I've narrowed it down to change in behaviour, though perhaps there is a new way of doing this now.

If you have a uniform like this in your shader:

uniform vec4 colorPalette[5];  

You used to be able to address it using an index by doing this, which doesn't seem to work anymore:

shader.setUniform4fv("colorPalette[3]", (float*)&ofFloatColor::red.v[0] );

I've put together an example to show the difference between two commits.

main.cpp

#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main()
{
    ofGLWindowSettings settings;
    settings.setGLVersion(4,1);
    settings.width  = 640;
    settings.height = 480;
    settings.windowMode = OF_WINDOW;
    ofCreateWindow(settings);

    ofRunApp(new ofApp());
}

ofApp.h

#pragma once

#include "ofMain.h"

#define GLSL(version, shader)  "#version " #version "\n" #shader

class ofApp : public ofBaseApp
{
    public:

        // ---------------------------------------------
        void setup()
        {

            const GLchar* vert = GLSL(410,

                 precision highp float;

                  layout(location = 0) in vec4  position;
                  layout(location = 1) in vec4  color;
                  layout(location = 2) in vec3  normal;
                  layout(location = 3) in vec2  texcoord;

                  uniform mat4 modelViewProjectionMatrix;

                  out VertexAttrib {
                      vec2 texcoord;
                  } vertex;

                  void main()
                  {
                      vertex.texcoord = texcoord;
                      gl_Position = modelViewProjectionMatrix * position;
                  }

              );


            const GLchar* frag = GLSL(410,

                  precision highp float;

                  in VertexAttrib {
                      vec2 texcoord;
                  } vertex;

                  uniform float screenWidth;
                  uniform vec4 colorPalette[5];

                  out vec4 fragColor;

                  void main()
                  {
                      int numColors = 5;
                      float tmpNorm = (gl_FragCoord.x / screenWidth);
                      fragColor = colorPalette[int(tmpNorm * float(numColors))];
                  }

              );

            shader.setupShaderFromSource( GL_VERTEX_SHADER, vert );
            shader.setupShaderFromSource( GL_FRAGMENT_SHADER, frag );
            shader.linkProgram();

            shader.printActiveUniforms();

            /*
            Output with de6ac6acadfe5c5d28f5e689c5766dc60c77f83d

             [notice ] ofShader: [0] modelViewProjectionMatrix @ index 0
             [notice ] ofShader: [1] colorPalette[0] @ index 4
             [notice ] ofShader: [2] screenWidth @ index 9

             */

            /*

            Output with 79c7d4292b8f87e4c805f4ef531ccf5f5bc98b7d

            [notice ] ofShader: [0] modelViewProjectionMatrix @ index 0
            [notice ] ofShader: [1] colorPalette[0] @ index 4
            [notice ] ofShader: [2] screenWidth @ index 9
            */


            uploadNewColors();
        }


        // ---------------------------------------------    
        void draw()
        {
            if( ofGetFrameNum() % 120 == 0 ) { uploadNewColors(); }

            ofDisableArbTex();
            shader.begin();
                shader.setUniform1f("screenWidth",  ofGetWidth() );
                ofDrawRectangle(0, 0, ofGetWidth(), ofGetHeight() );
            shader.end();
        }

        // ---------------------------------------------
        void uploadNewColors()
        {
            ofFloatColor tmpCols[5];
            for(int i = 0; i < 5; i++ )
            {
                tmpCols[i] = ofFloatColor::fromHsb( ofRandom(1), 0.7, 0.9 );
            }

            shader.begin();

                /*
                // With de6ac6acadfe5c5d28f5e689c5766dc60c77f83d
                shader.setUniform4fv("colorPalette", (float*)&tmpCols[0].v[0], 5 );
                shader.setUniform4fv("colorPalette[3]", (float*)&ofFloatColor::red.v[0] );  // this is also possible
                */


                // With 79c7d4292b8f87e4c805f4ef531ccf5f5bc98b7d
                shader.setUniform4fv("colorPalette[0]", (float*)&tmpCols[0].v[0], 5 );
                shader.setUniform4fv("colorPalette[3]", (float*)&ofFloatColor::red.v[0] );  // this doesn't work anymore

            shader.end();

        }

        ofShader shader;
};

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue from main.cpp and ofApp.h, focusing on the shader.setUniform4fv calls for colorPalette[0] and colorPalette[3]. Compare the behavior between commits de6ac6acadfe5c5d28f5e689c5766dc60c77f83d and 79c7d4292b8f87e4c805f4ef531ccf5f5bc98b7d, then inspect the ofShader uniform-setting entry points. Done means indexed array elements can again be assigned individually while bulk array uploads still work.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.