Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: Texture is not rendering (renders black)

  1. #1
    Junior Member Newbie
    Join Date
    May 2018
    Posts
    4

    Texture is not rendering (renders black)

    Hi,

    I'm starting using OpenGL for an Android project as the task I am doing requires OpenGL.
    Using OpenGL ES 2.0 on Android 7. I'm trying to draw a texture as a test but it's just rendering black:Click image for larger version. 

Name:	2537b5bc-3833-4410-9858-75b56f7274d1.jpg 
Views:	100 
Size:	28.1 KB 
ID:	2756

    texture: Click image for larger version. 

Name:	texture.jpg 
Views:	33 
Size:	14.9 KB 
ID:	2757

    glGetError returns 0, shader compiles, other examples don't seem to do anything different..I'm out of options.
    Need to clean up some of the code including writing a custom log function, so don't be confused by that.
    Error is likely somewhere at glTexture2D where I create the texture. I can verify that the shader and textureVertices array works, if I take out the texture2D function in the Fragment shader it is working.
    Thank you for your time.
    Here is my code, it's just lots as the error could be anywhere:

    Fragment Shader:

    Code :
    #version 100
    precision mediump float;
     
    varying vec3 Color;
    varying vec2 Texcoord;
     
    uniform sampler2D tex;
     
     
    void main()
    {
    gl_FragColor = texture2D(tex, Texcoord) * vec4(Color, 1.0);
    }

    Vertex Shader:
    Code :
    #version 100
    attribute vec2 position;
    attribute vec3 color;
    attribute vec2 texcoord;
     
    varying vec3 Color;
    varying vec2 Texcoord;
     
     
    void main()
    {
     
    gl_Position = vec4(position, 0.0, 1.0);
    Color = color;
    Texcoord = texcoord;
    }


    fileManager.cpp:

    Code :
    ...
    const char* FileManager::ReadFile(const char *path, off_t& length)
    {
        AAsset* asset=AAssetManager_open(FileManager::assetManager,path,AASSET_MODE_BUFFER);
     
        char* buff = new char[AAsset_getLength(asset)];
        length = AAsset_getLength(asset);
        AAsset_read(asset,buff,(size_t)length);
        AAsset_close(asset);
        return buff;
    }

    texture2d.cpp:

    Code :
    #include "texture2D.h"
    #include "defines.h"
    #if defined(OPENGL)
    #include "gl/glTexture2D.h"
    #endif
     
     
     
    shared_ptr<Texture2D>  Texture2D::Load(string &location) {
    #if defined(OPENGL)
        return shared_ptr<Texture2D>(new GlTexture2D(location));
    #endif
    }


    glTexture2D.h:

    Code :
    #pragma once
     
    #include <GLES2/gl2.h>
    #include "../texture2D.h"
     
    class GlTexture2D : public Texture2D {
     
    private:
        GLuint texture;
        static constexpr float textureVertices[] = {
    //          Position      Color             Texcoords
                -0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
                0.5f,  0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
                0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
                -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f  // Bottom-left
        };
     
     
        static constexpr GLuint elements[] = { 0, 1, 2, 2, 3, 0 };
     
        static GLuint shaderProgram;
     
        GLuint ebo;
     
    public:
        GlTexture2D(string& path);
        void Draw() override ;
    };

    glTexture2D.cpp:

    Code :
     
    #include <cstdlib>
    #include <android/log.h>
     
    #include "glTexture2D.h"
    #include "pngLoader.h"
    #include "../fileManager.h"
    #include "../openGLRenderer.h"
    #include "glHelper.h"
     
    using namespace std;
     
    constexpr float GlTexture2D::textureVertices[28];
    constexpr GLuint GlTexture2D::elements[6];
    GLuint GlTexture2D::shaderProgram;
     
     
    GlTexture2D::GlTexture2D (string& path)
    {
        int32_t length = (int32_t)path.length();
        string extension = "";
        for (int i = length-1;i >= 0;--i)
        {
            char letter = path[i];
            extension = letter+extension;
     
            if(letter == '.')
                break;
        }
     
        if(extension != ".png")
        {
            printf("Error. Can only load PNG textures.");
            return;
        }
     
        int width, height;
        GLint format;
        const void* data = NULL;
     
        data = PngLoader::loadPng(path.c_str(),width,height, format);
        if(data == NULL)
        {
            printf("Error. PNGLoader could not load png file.");
            return;
        }
     
     
     
     
     
        GLuint vbo;
        // Generate 1 vertex buffer
        glGenBuffers(1, &vbo);
        // Bind the buffer (tell the buffer what type of buffer it is)
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
     
        // Copy vertex data to our array buffer (note how we reference it by GL_ARRAY_BUFFER, NOT the vbo int
        glBufferData(GL_ARRAY_BUFFER, sizeof(GlTexture2D::textureVertices), GlTexture2D::textureVertices, GL_STATIC_DRAW);
     
     
        // generate 1 element buffer
      // connection?
        glGenBuffers(1, &ebo);
     
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GlTexture2D::elements), GlTexture2D::elements, GL_STATIC_DRAW);
     
        // Load shader
     
     
     
       GLuint result = GlHelper::loadShader((char*)"openGLShader/default.frag",(char*)"openGLShader/default.vert");
        if(!result)
        {
            printf("Shader compile fail");
            return;
        }
        shaderProgram = result;
     
     
     
        // Generate the OpenGL texture object
     
        glGenTextures(1, &texture);
     
     
     
     
     
       //float pixels[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
       //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels);
     
        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
     
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        GLint loc = glGetUniformLocation (shaderProgram,"tex");
        glUniform1i(loc,0);
     
        //glGenerateMipmap(GL_TEXTURE_2D);
     
     
     
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     
     
     
        //free((char*)data);
    }
     
    void GlTexture2D ::Draw()
    {
     
     glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, nullptr);
    }



    glHelper.cpp:
    Code :
     
    #include "glHelper.h"
    #include "../fileManager.h"
    #include "../openGLRenderer.h"
    #include <android/log.h>
    #include <sys/types.h>
     
    GLuint GlHelper::loadShader(char* fragment, char* vertical)
    {
        off_t fLength;
        const char *vertexSource = FileManager::ReadFile(vertical,fLength);
     
        //fReader.ReadAll(vertexSourcePath);
        // Create vertex shader
        GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexSource, NULL);
        glCompileShader(vertexShader);
     
     
        GLint status; GLint logLength;
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
     
     
     
        if (status != GL_TRUE)
        {
     
            glGetShaderiv(vertexShader,GL_INFO_LOG_LENGTH,&logLength);
            char buffer[logLength];
            glGetShaderInfoLog(vertexShader, logLength, NULL, buffer);
     
     
            // Reason for %s formating: https://stackoverflow.com/questions/9306175/how-to-fix-this-compiler-error-format-not-a-string-literal-and-no-format-argume
            // A char buffer can't be applied with specifying it to avoid potential security leak.
            __android_log_print(ANDROID_LOG_ERROR, QS_OPENGLTAG, "%s",buffer);
            // Shader compile fail.
     
            return 0;
        }
     
        off_t fLength2;
        const char *fragmentSource = FileManager::ReadFile(fragment,fLength2);
     
        GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
        glCompileShader(fragmentShader);
     
        glGetShaderiv(fragmentShader,GL_COMPILE_STATUS, &status);
     
     
     
        if (status != GL_TRUE)
        {
     
            glGetShaderiv(fragmentShader,GL_INFO_LOG_LENGTH,&logLength);
            char buffer[logLength];
            glGetShaderInfoLog(fragmentShader, logLength, NULL, buffer);
     
     
            // Shader compile fail.
            __android_log_print(ANDROID_LOG_ERROR, QS_OPENGLTAG,"%s", buffer);
            return 0;
        }
     
        GLuint shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
     
        // OpenGL ES only supports 1 vertex shader output. The following line is nessesary if you had more than 1 outputs in normal openGL
        //glBindFragDataLocation(shaderProgram, 0, "outColor");
     
        // Link the shaders
     
     
     
        glLinkProgram(shaderProgram);
     
     
        glGetProgramiv(shaderProgram,GL_LINK_STATUS,&status);
     
     
        if(status != GL_TRUE)
        {
            glGetProgramiv(shaderProgram,GL_INFO_LOG_LENGTH,&logLength);
            char buffer[logLength];
            glGetProgramInfoLog(shaderProgram,logLength,NULL,buffer);
            __android_log_print(ANDROID_LOG_ERROR,QS_OPENGLTAG,"%s",buffer);
            return 0;
        }
     
        // Validate and error check.
        glValidateProgram(shaderProgram);
     
     
        glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &status);
        if(status != GL_TRUE)
        {
            glGetProgramiv(shaderProgram,GL_INFO_LOG_LENGTH,&logLength);
            char buffer[logLength];
            glGetProgramInfoLog(shaderProgram,logLength,NULL,buffer);
            __android_log_print(ANDROID_LOG_ERROR,QS_OPENGLTAG,"%s",buffer);
            return 0;
        }
     
        glUseProgram(shaderProgram);
     
        GLenum  err = glGetError();
        if(err != GL_NO_ERROR)
        {
            __android_log_print(ANDROID_LOG_ERROR,QS_OPENGLTAG,"%s","OpenGL error code: "); // + to_string((int)err));
            return 0;
        }
     
     
     
     
        GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
        glEnableVertexAttribArray(posAttrib);
        glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), 0);
     
        GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
        glEnableVertexAttribArray(colAttrib);
        glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(2*sizeof(float)));
     
     
        GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
        glEnableVertexAttribArray(texAttrib);
        glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(5*sizeof(float)));
     
     
     
        return shaderProgram;
    }



    openGlRenderer.cpp

    Init:
    Code :
    ...
       glClearColor(0,1,0,1);
     string path ("textures/metalplate.png");
     texture = Texture2D::Load(path);
    Draw:
    Code :
    ...
    glClear(GL_COLOR_BUFFER_BIT);
    texture->Draw();

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,480
    You didn't call glBindTexture before you called glTexImage2D.

  3. #3
    Junior Member Newbie
    Join Date
    May 2018
    Posts
    4
    Thanks for your quick response.
    I changed that, unfortunately still getting the same result :/

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,480
    I'd recommend getting filling the quad with a solid color (without texture) working first. Then when you add texture support, if you have problems, you'll know where the problem lies.
    Last edited by Dark Photon; 05-12-2018 at 11:45 AM.

  5. #5
    Junior Member Newbie
    Join Date
    May 2018
    Posts
    4
    If I change
    Code :
      gl_FragColor = texture2D(tex, Texcoord) * vec4(Color, 1.0);
    to
    Code :
      gl_FragColor = vec4(Color, 1.0);

    it works, so I highly think it must be the texture.

    Let's say I'm loading it wrong, I also tested with this:

    Code :
       float pixels[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels);

    Still gives me the same.

    What I also found out is whenever I use
    Code :
     glGenerateMipmap(GL_TEXTURE_2D);
    glGetError returns 1281.
    Last edited by bbbb0x; 05-12-2018 at 11:45 AM.

  6. #6
    Junior Member Newbie
    Join Date
    May 2018
    Posts
    4
    Okay, I got it to work. Pretty weird but well that was expected.

    One post I found googling got me the idea to put these lines
    Code :
     GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
        glEnableVertexAttribArray(posAttrib);
        glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), 0);
     
        GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
        glEnableVertexAttribArray(colAttrib);
        glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(2*sizeof(float)));
     
     
        GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
        glEnableVertexAttribArray(texAttrib);
        glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(5*sizeof(float)));

    behind the texture binding, even through done differently in my code samples.
    Now it works.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •