Compute shader can't get result image - c++

I am using the compute shader to get a column of colors to match the conditions and I want to get the results for further processing. I want to get the output data in image1D imgOutput, but get_img can't get anything, did I do something wrong?
the texture in the first block has been generated before.
Shader spriteRowProgram, spriteColumnProgram;
unsigned int resultTexture = 0;
const std::string path = found::utils::Environment::GetRunPath();
const std::string sprite_row_path = path + "shaders/glfw_sprite_row.comp";
spriteRowProgram = Shader(sprite_row_path);
std::vector<GLfloat> get_img(qMax(TEX_WIDTH, TEX_HEIGHT) * 4);
glGenTextures(1, &resultTexture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_1D, resultTexture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, qMax(TEX_WIDTH, TEX_HEIGHT), 0, GL_RGBA, GL_FLOAT, get_img.data());
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, texture);
spriteRowProgram.use();
glUniform1i(1, 1);
glBindImageTexture(1, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
glUniform1i(0, 0);
glBindImageTexture(0, resultTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
glClear(GL_COLOR_BUFFER_BIT);
spriteRowProgram.setInt("input_width", TEX_WIDTH);
spriteRowProgram.setInt("input_height", TEX_HEIGHT);
glDispatchCompute(TEX_WIDTH, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
#version 430 core
layout (local_size_x = 1, local_size_y = 1) in;
layout(rgba32f, location = 0, binding = 0) uniform writeonly image1D imgOutput;
// texture samplers
layout(rgba32f, location = 1, binding = 1) uniform readonly image2D inputImage;
uniform int input_width;
uniform int input_height;
void main()
{
vec4 baseColor = imageLoad(inputImage, ivec2(0, 0));
bool alpha = baseColor.w == 1;
bool success = true;
for (int i = 0; i <= input_height; ++i)
{
vec4 current = imageLoad(inputImage, ivec2(gl_GlobalInvocationID.x, i));
if (alpha) {
if (current.w > 0.99) continue;
else {
success = false;
break;
}
} else {
vec4 difference = baseColor - current;
success = abs(difference.x) < 0.01 && abs(difference.y) < 0.01 && abs(difference.z) < 0.01;
if (success) continue;
else {
break;
}
}
}
if (success) baseColor = ivec4(0.1, 0.1, 0.1, 0.1);
else baseColor = ivec4(1.0, 1.0, 1.0, 1.0);
imageStore(imgOutput, int(gl_GlobalInvocationID.x), baseColor);
}

One issue might be that if you want to access images after the compute shader, the argument for glMemoryBarrier should be GL_SHADER_IMAGE_ACCESS_BARRIER_BIT and not GL_SHADER_STORAGE_BARRIER_BIT.
So
spriteRowProgram.setInt("input_width", TEX_WIDTH);
spriteRowProgram.setInt("input_height", TEX_HEIGHT);
glDispatchCompute(TEX_WIDTH, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
should really be
spriteRowProgram.setInt("input_width", TEX_WIDTH);
spriteRowProgram.setInt("input_height", TEX_HEIGHT);
glDispatchCompute(TEX_WIDTH, 1, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

Related

Opengl Textures dont display but give corrupted double linked list error

I've been playing with textures for some time and i just can't get it to work
Here is the code
#include "App.h"
std::array <float, 4> background_col = {0.25, 0.25, 0.25, 1.0} ;
std::string name = "OpenGL" ;
std::string icon = "data/images/dot.png" ;
const int width = 800 ;
const int height = 800 ;
bool anti_aliasing = true ;
bool FPS_60_CAP = true ;
MVP mvp;
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
}
void App::run()
{
Window window(true, anti_aliasing);
window.make_Window(glfwCreateWindow(width, height, name.c_str(), NULL, NULL), key_callback, icon);
srand(time(NULL));
mvp.view = glm::ortho(0.0f, (float)width, 0.0f, (float)height);
Renderer renderer;
Player player;
// redesighn with errors in mind
// 1. TODO: Implement Text
// 2. TODO: Implement UI
std::vector<float> vertexes = {
200, 200, 1, 1, 1, 1, 0, 0,
200, 600, 1, 1, 1, 1, 0, 1,
600, 600, 1, 1, 1, 1, 1, 1,
600, 200, 1, 1, 1, 1, 1, 0
};
std::vector<uint32_t> indexes = {0, 1, 2, 3};
while (!glfwWindowShouldClose(window.window))
{
glClearColor(background_col[0], background_col[1], background_col[2], background_col[3]);
glClear(GL_COLOR_BUFFER_BIT);
warn(0);
Shader shader("shaders/text.shader");
shader.useShader();
warn(1);
Texture tex("data/images/dot.png");
tex.Bind();
warn(2);
shader.uniformMat4Float("u_projection_matrix", mvp.projection * mvp.view * mvp.model);
shader.uniformInt({0}, "tex");
warn(3);
VBO vbo;
VAO vao;
IBO ibo;
warn(4);
vbo.write(vertexes.data(), vertexes.size() * sizeof(float));
ibo.write(indexes.data(), indexes.size() * sizeof(uint32_t));
warn(5);
ibo.bind();
vbo.bind();
vao.bind();
warn(6);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (const void *)(sizeof(float) * 0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (const void *)(sizeof(float) * 2));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (const void *)(sizeof(float) * 6));
warn(7);
glDrawElements(GL_QUADS, indexes.size(), GL_UNSIGNED_INT, nullptr);
warn(8);
ibo.unbind();
vbo.unbind();
vao.unbind();
warn(9);
tex.unBind();
tex.~Texture();
warn(10);
vbo.~VBO();
vao.~VAO();
ibo.~IBO();
warn(11);
shader.deleteShader();
warn(12);
glfwSwapBuffers(window.window);
glfwSwapInterval(FPS_60_CAP);
glfwPollEvents();
}
alcCloseDevice(player.Device);
window.~Window();
}
the texture class:
#include "Core.h"
Texture::Texture(std::string path)
{
this->path = path;
this->bpp = 0;
this->height = 0;
this->width = 0;
this->localbuffer = nullptr;
this->TexID = 0;
stbi_set_flip_vertically_on_load(1);
localbuffer = stbi_load(path.c_str(), &width, &height, &bpp, 4);
glGenTextures(1, &TexID);
glBindTexture(GL_TEXTURE_2D, TexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, localbuffer);
glBindTexture(GL_TEXTURE_2D, 0);
if (localbuffer) { stbi_image_free(localbuffer); }
else { info("h"); }
}
void Texture::Bind(uint32_t slot)
{
glActiveTexture(GL_TEXTURE0 + slot);
}
void Texture::unBind()
{
glBindTexture(GL_TEXTURE_2D, 0);
}
Texture::~Texture()
{
glDeleteTextures(1, &TexID);
}
and the shader:
#shader vertex
#version 400 core
layout (location = 0) in vec4 Pos;
layout (location = 1) in vec4 vColor;
layout (location = 2) in vec2 vTexCoord;
out vec4 color;
out vec2 TexCoord;
uniform mat4 u_projection_matrix;
void main()
{
gl_Position = u_projection_matrix * Pos;
color = vColor;
TexCoord = vTexCoord;
}
#shader fragment
#version 400 core
in vec4 color;
in vec2 TexCoord;
uniform sampler2D tex;
void main()
{
vec4 texcol = texture(tex, TexCoord);
gl_FragColor = texcol;
}
it just stays blank and displays this error
corrupted double-linked list
it is important to mention this error happens on the second frame
The code that I know works because I've got textures to display before correctly is:
the Shader class
VAO VBO and IBO
EDIT: after the fix from rafix07 it doesn't crash anymore it just doesn't display
EDIT2:
I've implemented glDebugMessageCallback, and it gives me this error:
source: 33352
type: 33361
id: 1
severity: 33387
length: 130
GL ERROR!: Shader Stats: SGPRS: 24 VGPRS: 24 Code Size: 72 LDS: 0 Scratch: 0 Max Waves: 10 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
Remove all explicit invocations of destructors, like:
tex.~Texture();
You get corrupted double-linked list because you deallocate a resource twice: first time by calling destructor explicitly and the second one when destructor is called at the end of scope within object is defined.
{
Texture tex;
// ...
tex.~Texture(); // texture is deallocated and id texture is dangling reference
// <-- dtor of tex is called implicitly, and the same id texture is deleted again leading to crash
}

Why always produce 4 pictures in my qt opengl program?

Here is my code:
modify from qt example: Examples\Qt-5.14.2\quick\scenegraph\openglunderqml
void SquircleRenderer::init()
{
unsigned char* data = (unsigned char*)malloc(1200*4);
for(int i=0;i<600;i++)
{
data[i*4] = 0;
data[i*4+1] = 255;
data[i*4+2] = 0;
data[i*4+3] = 255;
}
for(int i=600;i<1200;i++)
{
data[i*4] = 0;
data[i*4+1] = 0;
data[i*4+2] = 255;
data[i*4+3] = 255;
}
if (!m_program) {
QSGRendererInterface *rif = m_window->rendererInterface();
Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::OpenGL || rif->graphicsApi() == QSGRendererInterface::OpenGLRhi);
initializeOpenGLFunctions();
if (texs[0])
{
glDeleteTextures(1, texs);
}
glGenTextures(1, texs);
glBindTexture(GL_TEXTURE_2D, texs[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 30, 40, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
m_program = new QOpenGLShaderProgram();
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertices;"
"varying highp vec2 coords;"
"void main() {"
" gl_Position = vertices;"
" coords = vertices.xy;"
"}");
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,
"varying highp vec2 coords;"
"uniform sampler2D inputImageTexture;"
"void main() {"
" gl_FragColor = texture2D(inputImageTexture, coords);"
"}");
m_program->bindAttributeLocation("vertices", 0);
m_program->link();
arrUni[0] = m_program->uniformLocation("inputImageTexture");
}
}
//! [4] //! [5]
void SquircleRenderer::paint()
{
// Play nice with the RHI. Not strictly needed when the scenegraph uses
// OpenGL directly.
m_window->beginExternalCommands();
m_program->bind();
m_program->enableAttributeArray(0);
float values[] = {
-1, 1,
1, 1,
-1, -1,
1, -1
};
// This example relies on (deprecated) client-side pointers for the vertex
// input. Therefore, we have to make sure no vertex buffer is bound.
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_program->setAttributeArray(0, GL_FLOAT, values, 2);//values
//m_program->setUniformValue("t", (float) m_t);
qDebug()<<m_viewportSize.width()<<m_viewportSize.height()<<"\n";
glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height());
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texs[0]);
glUniform1i(arrUni[0], 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
m_program->disableAttributeArray(0);
m_program->release();
m_window->endExternalCommands();
}
As the picture you can see,it produces 4 same pictures,could you tell me how to produce 1 picture fill the whole window?:
I tried so many methods, but it didn't work, I guess the problem exists in the values array or the glTexImage2D function.
Textures are mapped accross the [0, 1] range, and values outside of that range are modulo-looped back into it, which creates a repeating pattern. Interpreting the texture over the [-1, 1] range leads to what you are seeing since you are mapping exactly twice the UV range in both axises.
There's a few ways to fix this. But my personal preference for a full-framebuffer pass like this is to have the attribute be normalized, and then have it converted to the expected [-1, 1] range for the clip-space coordinate in the vertex shader:
float values[] = {
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f
};
gl_Position = vertices * 2.0 - vec4(1.0, 1.0,0.0,1.0);
Another common technique is to do away with the attribute buffer altogether, and use gl_VertexID to directly generate both the UVs and coordinates.

Open gl draw turns white after one frame drawn

I am newbie in Opengl. I used the following example from Qt as a start in Opengl as I know Qt.
http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-squircle-cpp.html
I replaced the paint function of the program with following code with an intent to draw chess board pattern. Following is not the paint or render function of my program
paint()
{
if (!m_program) {
initializeOpenGLFunctions();
m_program = new QOpenGLShaderProgram();
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertices;"
"varying highp vec2 coords;"
"void main() {"
" gl_Position = vertices;"
" coords = vertices.xy;"
"}");
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,
"uniform lowp float t;"
"varying highp vec2 coords;"
"void main() {"
" lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
" i = smoothstep(t - 0.8, t + 0.8, i);"
" i = floor(i * 20.) / 20.;"
" gl_FragColor = vec4(coords * .5 + .5, i, i);"
"}");
m_program->bindAttributeLocation("vertices", 0);
m_program->link();
}
auto width = static_cast<float>(m_viewportSize.width());
auto height = static_cast<float>(m_viewportSize.height());
auto a = 2.f / width;
auto b = 2.f / height;
std::vector<float> matrix =
{
a , 0, 0, 0,
0, -b, 0, 0,
0, 0, 1, 0,
-1, 1, 0, 1
};
// Set the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(matrix.data());
// Initialize vertices:
std::vector<float> vertices =
{
0, 0,
0, height,
width, height,
width, 0
};
// Initialize colors
std::vector<float> colors =
{
1, 0, 0,
0, 1, 0,
0, 0, 1,
0, 1, 1
};
// Initialize texture virtice
std::vector<float> texCoord =
{
0, 0,
0, 1,
1, 1,
1, 0
};
// Create texture: simple chess board 8x8
auto numRows = 8u;
auto numCols = 8u;
auto character = 172u;
auto remain = 255u - character;
std::vector<unsigned char> texture(numCols * numRows);
for (auto i = 0u; i < texture.size(); ++i)
texture[i] = ((i + (i / numCols)) % 2) * remain + character;
// Upload to GPU texture
unsigned textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, numCols, numRows, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texture.data());
// Initialize clear colors
glClearColor(0.f, 0.f, 0.f, 1.f);
// Activate necessary states
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices.data());
glColorPointer(3, GL_FLOAT, 0, colors.data());
glTexCoordPointer(2, GL_FLOAT, 0, texCoord.data());
// render
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_QUADS, 0, 4);
m_program->disableAttributeArray(0);
m_program->release();
m_window->resetOpenGLState();
}
The chess board is drawn. But its drawn for a split second & then the screen turns fully white. I want to draw the chess board pattern continiously with each frame draw.
Can someone pls point out what might be going wrong ?
At the very top you have:
if (!m_program) {
then you initialize m_program, at the very bottom you have:
m_program->release();
which as Harish in comments points out is equivalent to calling glUseProgram(0);. So in the next iteration of paint your shader is not bound and not available.
According to docs, the reverse of release(); is bind(); so (I am not expert on this class) the solution might be to call QOpenGLShaderProgram::bind() on the next iteration of your paint.
For future reference, it's a good idea to run opengl programs through a graphics debugger like gDEbugger to give you an insight into what's actually happening inside the API.

Shader doesn't write anything for picking by id

I am trying to implement picking by an int id, but it looks like my shader doesn't write anything, althought I can read the clear color properly.
vs, I skipped completely any matrix for debugging:
#version 330
#include semantic.glsl
layout (location = POSITION) in vec3 position;
uniform Transform0
{
mat4 view;
mat4 proj;
mat4 viewProj;
};
uniform Transform1
{
mat4[TRANSFORM1_SIZE] models;
};
uniform Parameters
{
// x = mesh baseVertex
// y = selected
// z = active
// w = id
ivec4[INDICES_SIZE] params;
};
out Block
{
flat int id;
} outBlock;
int getIndex()
{
int iBegin = 0;
int iEnd = params.length() - 1;
int l = iBegin;
int r = iEnd;
int i = 0;
if(params.length > 1)
{
do
{
i = int(((l + r) / 2.0f));
if (l == (r - 1))
if (l == 0 && gl_VertexID <= params[l].x || gl_VertexID <= params[l].x && gl_VertexID > params[l - 1].x)
return l;
else if(gl_VertexID > params[l].x && gl_VertexID <= params[r].x)
return r;
else
return 0;
else if (gl_VertexID == params[i].x)
return i;
else if (gl_VertexID < params[i].x)
r = i;
else if (gl_VertexID > params[i].x)
l = i;
} while (l < r);
}
return 0;
}
void main()
{
int index = getIndex();
mat4 model = models[index];
//gl_Position = proj * (view * (model * vec4(position, 1)));
gl_Position = vec4(4.0 * float(gl_VertexID % 2) - 1.0, 4.0 * float(gl_VertexID / 2) - 1.0, 0.0, 1.0);
outBlock.id = params[index].w;
}
fs, hardcoded value for the moment, output is 0 (FRAG_COLOR), tried also 1 but nothing:
#version 330
#include semantic.glsl
// Outgoing final color.
layout (location = FRAG_COLOR) out int outputColor;
in Block
{
flat int id;
} inBlock;
void main()
{
//outputColor = inBlock.id;
outputColor = 9;
}
Init phase, I have one fbo, called RESOLVE, with 3 attachements, one depth, one float color on 0 and one integer for picking on 1. Fbo is complete:
gl3.glBindTexture(GL_TEXTURE_2D, textureName.get(Texture.RESOLVE_ID));
gl3.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
gl3.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
gl3.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl3.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl3.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl3.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl3.glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, EC.viewer.size.x, EC.viewer.size.y, 0, GL_RED_INTEGER, GL_INT, null);
gl3.glGenFramebuffers(Framebuffer.MAX - (samples == 1 ? 1 : 0), framebufferName);
gl3.glBindFramebuffer(GL_FRAMEBUFFER, framebufferName.get(Framebuffer.RESOLVE));
gl3.glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textureName.get(Texture.RESOLVE_DEPTH), 0);
gl3.glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureName.get(Texture.RESOLVE_COLOR), 0);
gl3.glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, textureName.get(Texture.RESOLVE_ID), 0);
if (gl3.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
System.err.println("incomplete");
return false;
}
and render & reading, added also glFlush, glFinish and glPixelStorei but nothing:
gl3.glBindFramebuffer(GL_FRAMEBUFFER, framebufferName.get(Framebuffer.RESOLVE));
gl3.glDrawBuffer(GL_COLOR_ATTACHMENT1);
gl3.glClearBufferiv(GL_COLOR, 0, clearId.put(0, 0)); // we care clearing only red
gl3.glBindVertexArray(EC.meshManager.vertexArrayName.get(0));
gl3.glEnable(GL_DEPTH_TEST);
gl3.glUseProgram(program.name);
gl3.glDrawElements(GL_TRIANGLES, EC_Gl3MeshManager.ELEMENT_OPAQUE_COUNT, GL_UNSIGNED_INT, 0);
gl3.glDisable(GL_DEPTH_TEST);
gl3.glReadBuffer(GL_COLOR_ATTACHMENT1);
glm.vec._2.i.Vec2i window = new glm.vec._2.i.Vec2i(
EC.inputListener.mousePressed.getX(),
EC.viewer.size.y - EC.inputListener.mousePressed.getY() - 1);
System.out.println("window (" + window.x + ", " + window.y + ")");
gl3.glFlush();
gl3.glFinish();
gl3.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Get the red coordinate reading the pixel click from the color 1 buffer, we can use the clearId buffer
gl3.glReadPixels(window.x, window.y, 1, 1, GL_RED_INTEGER, GL_INT, clearId);
gl3.glReadBuffer(GL_COLOR_ATTACHMENT0);
As I said, if I clear with 10, I read 10, so that is working, the only problematic thing is my shader..
Can you spot the error, guys?
Edit: trying to debug, I am checking the attachment type on color 1
gl3.glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, clearId);
System.out.println("GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: " + clearId.get(0));
gl3.glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, clearId);
System.out.println("GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: " + clearId.get(0)+", tex: "+textureName.get(Texture.RESOLVE_ID));
I get:
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 5890
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 14, tex: 14
5890 is GL_TEXTURE, name looks correct
tried to use glFramebufferTexture2D, but I still get GL_TEXTURE type instead GL_TEXTURE_2D
Edit 2: trying to read the depth component, is always 0
Shame on me, the problem was the depth test, since I forgot to clean the buffer it was never passing

Repeating OpenGL-es texture bound to hills in cocos2d 3.2

ORIGINAL ARTICLE
I am in the process of trying to implement raywenderlich's tutorial on generating hills with repeating striped coordinates using cocos2d, This article was written for Cocos2D, and as I am trying to port it to Cocos2Dx 3.2 This means updating it for openGl-es 2. So far everything has worked perfectly, However I am having problems with getting the texture of the hill to repeat properly and also after some repeatation the texture start degrade ...
please help me to get texture properly.......
Here is my code:
#define Point_FROM_B2VEC(v) Point((v.x*PTM_RATIO),(v.y*PTM_RATIO))
#define B2VEC_FROM_Point(v) b2Vec2(v.x/PTM_RATIO,v.y/PTM_RATIO)
#define PTM_RATIO 32
#define MAX_HILL_POINTS 15
#define MAX_SEGMENTS MAX_HILL_POINTS*10
#define MAX_COORDINATES 600
Point hillTopVertices[MAX_COORDINATES],hillBottomVertices[MAX_COORDINATES];
Point hillTopTexCoords[MAX_COORDINATES];
Point hillBottomTexCoords[MAX_COORDINATES];
GLuint terraintopTexId, terrainBottomTexId;
float terrainTopTexSize, terrainBottomTexSize;
Sending the hills the texture:
texture = Director::getInstance()->getTextureCache()->addImage("surface.png");
terraintopTexId = texture->getName();
terrainTopTexSize = texture->getPixelsWide()/2;
//terrain top texture
texture1 = Director::getInstance()->getTextureCache()->addImage("old_stone_wall_textures_v3_3000x2000_1.jpg");
terrainBottomTexId = texture1->getName();
terrainBottomTexSize = texture1->getPixelsWide()/2;
void Terrain::generateCoordinates()
{
int nTopVertCount = 0;
int nTopVertCount1 = 0;
//get the hill vertex and texcoordinates
for(short i = 0; i < MAX_SEGMENTS; ++i)
{
Point point1 = Point_FROM_B2VEC(vertices[i]);
Point point2 = Point_FROM_B2VEC(vertices[i+1]);
CCLOG("%f",terrainBottomTexSize);
hillTopVertices[nTopVertCount1] = Point(point1.x, point1.y+16);
hillTopTexCoords[nTopVertCount1++] = Point(point1.x/terrainTopTexSize, 1);
hillTopVertices[nTopVertCount1] = Point(point2.x, point2.y+16);
hillTopTexCoords[nTopVertCount1++] = Point(point2.x/terrainTopTexSize, 1);
hillTopVertices[nTopVertCount1] = Point(point1.x, point1.y-16);
hillTopTexCoords[nTopVertCount1++] = Point(point1.x/terrainTopTexSize, 0);
hillTopVertices[nTopVertCount1] = Point(point2.x, point2.y-16);
hillTopTexCoords[nTopVertCount1++] = Point(point2.x/terrainTopTexSize, 0);
}
for(short i = 0; i < MAX_SEGMENTS; ++i)
{
Point point1 = Point_FROM_B2VEC(vertices[i]);
Point point2 = Point_FROM_B2VEC(vertices[i+1]);
hillBottomVertices[nTopVertCount] = Point(point1.x, point1.y-terrainBottomTexSize+1);
hillBottomTexCoords[nTopVertCount++] = Point(point1.x/terrainBottomTexSize, 1);
hillBottomVertices[nTopVertCount] = Point(point2.x, point2.y-terrainBottomTexSize+1);
hillBottomTexCoords[nTopVertCount++] = Point(point2.x/terrainBottomTexSize, 1);
hillBottomVertices[nTopVertCount] = Point(point1.x, point1.y+2);
hillBottomTexCoords[nTopVertCount++] = Point(point1.x/terrainBottomTexSize, 0);
hillBottomVertices[nTopVertCount] = Point(point2.x, point2.y+2);
hillBottomTexCoords[nTopVertCount++] = Point(point2.x/terrainBottomTexSize, 0);
}
//energy adding
//CCLOG("hillsegment---%d,pointx---%f,pointy---%f,offset--%f",i,point1.x,point1.y,offsetX);
}
void Terrain::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
Node::draw(renderer, transform, flags);
_renderCmds[0].init(0.0f);
_renderCmds[0].func = CC_CALLBACK_0(Terrain::onDraw, this, transform);
renderer->addCommand(&_renderCmds[0]);
}
void Terrain::onDraw(const Mat4 &transform) {
auto glProgram = getGLProgram();
glProgram->use();
glProgram->setUniformsForBuiltins(transform);
GL::bindTexture2D( terrainBottomTexId );
GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, hillBottomVertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, hillBottomTexCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)MAX_COORDINATES);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
GL::bindTexture2D(terraintopTexId );
GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, hillTopVertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, hillTopTexCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)MAX_COORDINATES);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}