Advertisement

Render Texture from PNG to Screen not working correctly OpenGL ES 3.0

Started by May 17, 2018 11:21 AM
28 comments, last by DevAndroid 6 years, 8 months ago

Yes that's what I tried initially but the texture was not rendered correctly

On 5/17/2018 at 1:21 PM, DevAndroid said:


GLfloat vertices[6][4] = { 
	{ x, y + 32, 0.0, 0.0 }, 
	{ x, y, 0.0, 1.0 },	
	{ x + 32, y, 1.0, 1.0 }, 
	{ x, y + 32, 0.0, 0.0 }, 
	{ x + 32, y, 1.0, 1.0 }, 
	{ x + 32, y + 32, 1.0, 0.0 } 
}; 
glBindTexture(GL_TEXTURE_2D, idTexture); 
glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferSubData(GL_ARRAY_BUFFER, GL_ZERO, sizeof(vertices), vertices); 
glBindBuffer(GL_ARRAY_BUFFER, GL_ZERO); 
glUniform1i(this->mTextShaderHandle, GL_ZERO); 
glDrawArrays(GL_TRIANGLE_STRIP, GL_ZERO, 6);

What maybe I'm wrong on the last 2 values ?

13 minutes ago, Andrey OGL_D3D said:

Problem with Z coordinates for textured quad ?

Sorry, I mean that texture is not displayed at all !

Try to use separate vertex shader for texture printing:


const char           gVertexShader[] =
        "#version 320 es\n"
                "layout (location = 0) in vec4 vertex;\n"
                "out vec2 TexCoords;\n"
        "uniform mat4 projection;\n"
                "void main() {\n"
                "  gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\n"
        "  TexCoords = vertex.xy;\n"
                "}\n"

Because we needn't calculate of texture coordinates for quad with the same textures size, but for text symbol we should calculate them.

also, check correct texture coordinates in 


GLfloat vertices[6][4] = { 
	{ x, y + 32, 0.0, 0.0 }, 
	{ x, y, 0.0, 1.0 },	
	{ x + 32, y, 1.0, 1.0 }, 
	{ x, y + 32, 0.0, 0.0 }, 
	{ x + 32, y, 1.0, 1.0 }, 
	{ x + 32, y + 32, 1.0, 0.0 } 

 

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

Advertisement

Is it possible to have multiple vertex shader in one program ? I did not know it was possible. So I need to compile 3 programs ?

(2 vertex shaders and 1 fragment shader) How to switch between them ?

It's not possible to tag the current texture I want to display in a single Vertex Shader like for example :


const char           gVertexShader[] =
        "#version 320 es\n"
        "layout (location = 0) in vec4 vertex;\n"
        "out vec2 TexCoords;\n"
        "uniform mat4 projection;\n"
        "void main() {\n"
		"   if (!textureIsFont) {\n"
        "      gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\n"
        "      TexCoords = vertex.xy;\n"
		"   } else {\n"
		"      gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\n"
		"      TexCoords = vertex.zw;\n"
		"    }"
        "}\n"

 

6 minutes ago, DevAndroid said:

Is it possible to have multiple vertex shader in one program ? I did not know it was possible. So I need to compile 3 programs ?

yes, you should compile 2 vertex shader and one pixel shader, and link two separate program. Also you can use Separate Shader Objects(OpenGL ES 3.1 and above or EXT_separate_shader_objects)

12 minutes ago, DevAndroid said:

How to switch between them ?


glUniform1i(textureIsFont, 1);

glUseProgram(text);

....

glUniform1i(textureIsFont, 0);

glUseProgram(textureQuad);

 

11 minutes ago, DevAndroid said:

It's not possible to tag the current texture I want to display in a single Vertex Shader like for example :

you can use uniform variable


"#version 320 es\n"
        "layout (location = 0) in vec4 vertex;\n"
        "out vec2 TexCoords;\n"
        "uniform mat4 projection;\n"
		"uniform int textureIsFont;\n"
        "void main() {\n"
		"   if (!textureIsFont) {\n"
        "      gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\n"
        "      TexCoords = vertex.xy;\n"
		"   } else {\n"
		"      gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\n"
		"      TexCoords = vertex.zw;\n"
		"    }"
        "}\n"

 

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

Thank you for all this information.

What's the best way ? I mean the most efficient ?

The 2 programs or the if else ?

3 minutes ago, DevAndroid said:

What's the best way ? I mean the most efficient ?

The Branche in fragment shader can decrease performance, so separate shader program may be better, but "if/else" is simpler.

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

Advertisement

Hello Andrey,

I tested with the if/else for the moment but nothing is displaying.

Here is my new printTexture method. (I tried with the two vertices : mine and yours to see if something is changing).


void Cluster::printTexture(GLuint idTexture, GLfloat x, GLfloat y) {
    glActiveTexture(GL_TEXTURE0);
    glBindVertexArray(this->VAO[0]); //VAO[0] or VAO[1] depending on wich Vertices I'm using.
    
    glUniform1i(this->mTagShaderHandle, 0); // this will set the variable on the shader to 0.

    /*GLfloat vertices[6][4] = {
            { x,     y + 32,   	0.0, 0.0 },
            { x,     y,       	0.0, 1.0 },
            { x + 32, y,       	1.0, 1.0 },

            { x,     y + 32,   	0.0, 0.0 },
            { x + 32, y,       	1.0, 1.0 },
            { x + 32, y + 32,   	1.0, 0.0 }          
        };*/

    GLfloat vertices[6][2] = {
            { x,     	y + 32	},
            { x,     	y	},
            { x + 32, 	y      	},

            { x,     	y + 32	},
            { x + 32, 	y	},
            { x + 32,   y + 32	}         
     };

    glBindTexture(GL_TEXTURE_2D, idTexture);
    glBindBuffer(GL_ARRAY_BUFFER, this->VBO[0]);

    glBufferSubData(GL_ARRAY_BUFFER, GL_ZERO, sizeof(vertices), vertices);
    glDrawArrays(GL_TRIANGLE_STRIP, GL_ZERO, 6);
    glBindVertexArray(GL_ZERO);
    glBindTexture(GL_TEXTURE_2D, GL_ZERO);
}

Here is how I init my vertices :


//init VAO[0] VBO[0]
    	glBindVertexArray(this->VAO[0]);
    	glBindBuffer(GL_ARRAY_BUFFER, this->VBO[0]);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, GL_ZERO, GL_DYNAMIC_DRAW);
    	glEnableVertexAttribArray(GL_ZERO);
    	glVertexAttribPointer(GL_ZERO, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), GL_ZERO);
    	glBindVertexArray(GL_ZERO);

	//init VAO[1] VBO[1]
    	glBindVertexArray(this->VAO[1]);
    	glBindBuffer(GL_ARRAY_BUFFER, this->VBO[1]);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 2, GL_ZERO, GL_STATIC_DRAW);
    	glEnableVertexAttribArray(GL_ZERO);
    	glVertexAttribPointer(GL_ZERO, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), GL_ZERO);
    	glBindVertexArray(GL_ZERO);

And the shader here :


const char           gVertexShader[] =
		"#version 320 es\n"
        "layout (location = 0) in vec4 vertex;\n"
        "out vec2 TexCoords;\n"
		"uniform mat4 projection;\n"
		"uniform int tag;"
        "void main() {\n"
        "  gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\n"
		"  if (tag > 0) {\n"
		"      TexCoords = vertex.zw;\n"
        "  } else {\n"
        "      TexCoords = vertex.xy;\n"
		"  }\n"
        "}\n";

On my main I'm just trying to print a texture for the moment but nothing appears...

I don't know if it could be the glActivityTexture or the Slot ID of where the texture is bound...

Do you have an idea ? Thank you for your effort.

Hi, DevAndroid

Sorry my mistakes!

1) Your shader and function printTexture(float vertices[6][4]) on first post is correct! 

2) You can use single shader for text and texture printing.

3) Use separate VBO for texture and text, also you can use static buffer for print texture(Without glBufferSubData, only glBufferData during preparing vertices)

Try it.

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

Hi Andrey,

No problem, I learned a lot of things, thank you.

Ok so I tried like that. Just so you know, I kept my shader program with if/else I just set TAG uniform value to 1 so it goes on


TexCoords = vertex.zw;

Here is my function printTexture :
 


void printTexture(GLuint idTexture, GLfloat x, GLfloat y) {
    glActiveTexture(GL_TEXTURE0);
    glBindVertexArray(this->VAO[1]);
    
    glUniform1i(this->mTagShaderHandle, 1);
    glUniform1i(this->mTextShaderHandle, 0);

    GLfloat xpos = x;
    GLfloat ypos = y;

    GLfloat w = 32;
    GLfloat h = 32;

    GLfloat vertices[6][4] = {
            { xpos,     ypos + h,       0.0, 0.0 },
            { xpos,     ypos,           0.0, 1.0 },
            { xpos + w, ypos,           1.0, 1.0 },

            { xpos,     ypos + h,       0.0, 0.0 },
            { xpos + w, ypos,           1.0, 1.0 },
            { xpos + w, ypos + h,       1.0, 0.0 }          
    };

    glBindTexture(GL_TEXTURE_2D, idTexture);
    glBindBuffer(GL_ARRAY_BUFFER, this->VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(GL_ZERO);
    glVertexAttribPointer(GL_ZERO, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), GL_ZERO);
    glDrawArrays(GL_TRIANGLE_STRIP, GL_ZERO, 6);
    glBindVertexArray(GL_ZERO);
    glBindTexture(GL_TEXTURE_2D, GL_ZERO);
}

Result is like I had on the first post... I see my texture on the right position but it's not rendered correctly.

In attach you'll see what's the result. I expect a full blue square in the middle like the png is but it's not. (But position is correct, that's a good point)

IMG_20180516_171103__01.jpg

Hi, DevAndroid

Can you show me expected result ?

May be need to set some RenderState parameters ? "Z Write enable" "Z Test" ...?

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

This topic is closed to new replies.

Advertisement