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.
I hope this help you to more understanding for my issue. Thank for reply. I really appreciate.