0
votes

I'm new at OpenGL and glsl and trying to use it on RPI2. I did my first practice example on OpenGL 2.1 and glsl version120. Now I'm working on OpenGLES 2.0.

What I want to do is that store float values to a texture and send it to vertex shader to make lines.

So, I made one array for float values to store, and passing these values to one FBO. And I send this FBO to UniformTexture. But It seems vertex shader doesn't get any values.

OpenGL ES 2.0 document states that "Texture lookup functions are available to both vertex and fragment shaders." Also I have checked GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS in RPI2 and it returns 8. Unfortunately, I cannot fetch any values form texture that I send to vertex shader.

What am I missing here? I posted this question at openframeworks forum as well. Any help would be appreciated. I really hope. Thanks !

vertex shader code

precision highp float;

uniform mat4 modelViewProjectionMatrix;
uniform sampler2D valTex;
uniform vec2 spaceSize;

attribute vec4 position;
attribute vec2 texcoord;

void main() {

    vec4 pixPos = position;

    vec2 valAmt = texture2D(valTex, texcoord).xy;
    valAmt.x *= spaceSize.x;
    valAmt.y *= spaceSize.y;

    vec2 nPos;
    nPos.x =  (pixPos.x + valAmt.x);
    nPos.y =  (pixPos.y + valAmt.y);

    if ((v_pos.x <= 1.0)) {
        gl_Position = modelViewProjectionMatrix * vec4(pixPos.x, pixPos.y, 0, 1);
    }else{
        gl_Position = modelViewProjectionMatrix * vec4(nPos.x, nPos.y, 0, 1);
    }
}

Fragment shader

void main() {

    gl_FragColor = vec4(1.0, 1.0, 0.5, 1.0);
}

OFX CODE

#include "ofApp.h"

void ofApp::setup(){

    string ShaderFolder;
    ShaderFolder = "shader_gles";
    renderShader.load(ShaderFolder + "/fluidRender.vert", ShaderFolder + "/fluidRender.frag");

    renderFbo.allocate(spaceSize, spaceSize, GL_RGB); //Render to Screen 
    renderFbo.begin();
    ofClear(0);
    renderFbo.end();

    valTex.allocate(gridSize, gridSize, GL_RGB); //Store values from array
    valTex.begin();
    ofClear(0);
    valTex.end();

    int vertexNum = gridSize * gridSize;

    vector<float> val(vertexNum * 3); //Store values

    for (int x = 0; x < gridSize; x++) {
        for (int y = 0; y < gridSize; y++) {
            val[((x * 3 * gridSize) + y * 3) + 0] = 200.0; //x pos value
            val[((x * 3 * gridSize) + y * 3) + 1] = 200.0; //y pos value
            val[((x * 3 * gridSize) + y * 3) + 2] = 0.0;
        }
    }
    valTex.getTexture().loadData(val.data(), gridSize, gridSize, GL_RGB);

    mesh.setMode(OF_PRIMITIVE_LINES);

    for (int x = 0; x < gridSize; x++) {
        for (int y = 0; y < gridSize; y++) {

            mesh.addVertex(ofVec3f(x * cellSize, y * cellSize)); //center vertex
            mesh.addTexCoord(ofVec2f(1.1, 1.1));

            mesh.addVertex(ofVec3f(x * cellSize, y * cellSize)); //val vertex
            mesh.addTexCoord(ofVec2f(x / gridSize - 1, y / gridSize - 1)); //normalize texcoord

            mesh.addIndex((x * 2) * gridSize + (y * 2) + 0);
            mesh.addIndex((x * 2) * gridSize + (y * 2) + 1);
        }
    }
    glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vertex_texture_units);
}

void ofApp::update(){
    vertexRender();
}

void ofApp::draw(){
    ofBackground(0);
    renderFbo.draw(0, 0);
    ofDrawBitmapString("v_tex_unit : " + ofToString(vertex_texture_units), 15, 15);
}

void ofApp::vertexRender(){
    renderFbo.begin();

    ofClear(0);
    renderShader.begin();
    renderShader.setUniformTexture("velTex", valTex.getTexture(), 0);
    renderShader.setUniform2f("spaceSize", spaceSize, spaceSize);
    mesh.draw();
    renderShader.end();

    renderFbo.end();
}

NOTE Not GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS in description. It is GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS in the code.

EDIT

This screen shot below is what I want to draw using vertex shader. Currently in this case, I send mouse x and y position float value (0 to screen size which is 960.0 in this case) to uniform to display value vertex. Each line has two vertex. One has fixed position which is from 'addVertex(x,y)' function.

mesh.addVertex(ofVec3f(x * cellSize, y * cellSize));

Another one has 'fixed position value + mouse position value'. So If mouse moves, It makes a line connecting fixed position vertex and 'fixed position + mouse position' vertex.

renderShader.setUniform2f("mousePos", mouseX, mouseY);

in GLSL

vec2 pixPos = position;
vec2 nPos;
nPos.x =  (pixPos.x + mousePos.x);
nPos.y =  (pixPos.y + mousePos.y);

vertex_mouse_position //<-sccreen shot (I can't embed pictures directly yet. sorry.)

Another picture is when I send texture(FBO) to vertex shader. I made an array and set 200.0 float value for each x, y position and load this array to FBO.

vector<float> val(vertexNum * 3); //Store values

    for (int x = 0; x < gridSize; x++) {
        for (int y = 0; y < gridSize; y++) {
            val[((x * 3 * gridSize) + y * 3) + 0] = 200.0; //x pos value
            val[((x * 3 * gridSize) + y * 3) + 1] = 200.0; //y pos value
            val[((x * 3 * gridSize) + y * 3) + 2] = 0.0;
        }
    }
    valTex.getTexture().loadData(val.data(), gridSize, gridSize, GL_RGB);

then send this FBO to vertex shader.

renderShader.setUniformTexture("velTex", valTex.getTexture(), 0);

But, I just get black screen displaying noting.

vertex_texture

I hope this help you to more understanding for my issue. Thank for reply. I really appreciate.

1
What do you actually mean by "unfortunately, I cannot fetch any values form texture that I send to vertex shader". What is the actual behavior / error you are getting?solidpixel
What values are you passing in to the uniforms? Is your output coordinate defiantly inside the clip-space volume (+1/-1 cube)?solidpixel

1 Answers

0
votes

You are checking the wrong query - check GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS.

On most GLES 2.0 implementations this will return zero; i.e. vertex texturing not supported. It's mandatory in GLES 3.x.