C++ Character buffer adding no characters

Asked

Viewed 86 times

0

Well, I have an application for android that uses Opengl ES 3.1, I did all the procedure to compile the shaders, I decided to put them in a separate folder in Assets, to recover the content I am using Aassetmanager.

Java code to recover assets and main Activity:

package com.samuelives.hautingground;

import android.content.pm.ActivityInfo;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.WindowManager;

import com.samuelives.hautingground.engine.IESurface;

public class Main extends AppCompatActivity{

    static {
        System.loadLibrary("HGround-Lib");
    }

    private IESurface mGameSurface = null;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        startGame();
        loadAsset(getAssets());

        //Init Surface
        mGameSurface = new IESurface(this);

        setContentView(mGameSurface);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGameSurface.onPause();
        pauseGame();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGameSurface.onResume();
        resumeGame();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        closeGame();
    }

    public native void startGame();
    public native void closeGame();
    public native void pauseGame();
    public native void resumeGame();
    public native void loadAsset(AssetManager manager);
}

C++ code to communicate with java code:

#include <jni.h>
#include <android/log.h>
#include <android/asset_manager_jni.h>
#include <android/asset_manager.h>
#include <GLES3/gl31.h>
#include <string.h>
#include "game/GameMain.h"

GameMain *game = NULL;

extern "C" {

/*    IERender    */

GLuint shader = 0;

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_engine_IERender_initGL(JNIEnv *env, jobject instance)
{

    __android_log_write(ANDROID_LOG_DEBUG, "IERender Native", "initGl called");

    __android_log_print(ANDROID_LOG_DEBUG, "Native Render", "GL Version: %s", glGetString(GL_VERSION));
    __android_log_print(ANDROID_LOG_DEBUG, "Native Render", "GL Extensions: %s", glGetString(GL_EXTENSIONS));
    __android_log_print(ANDROID_LOG_DEBUG, "Native Render", "GL Vendor: %s", glGetString(GL_VENDOR));
    __android_log_print(ANDROID_LOG_DEBUG, "Native Render", "GL Shading: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
    __android_log_print(ANDROID_LOG_DEBUG, "Native Render", "GL Render: %s", glGetString(GL_RENDERER));

    game->init();
}

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_engine_IERender_drawGL(JNIEnv *env, jobject instance)
{
    game->render();
}

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_engine_IERender_resizeGL(JNIEnv *env, jobject instance, jint w, jint h)
{
    __android_log_write(ANDROID_LOG_DEBUG, "IERender Native", "resizeGl called");
    game->resizeRender(w, h);
}

/*    Main    */

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_Main_startGame(JNIEnv *env, jobject instance)
{
    game = new GameMain();
}

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_Main_closeGame(JNIEnv *env, jobject instance)
{
    delete game;
}

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_Main_pauseGame(JNIEnv *env, jobject instance)
{

}

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_Main_resumeGame(JNIEnv *env, jobject instance)
{

}

JNIEXPORT void JNICALL Java_com_samuelives_hautingground_Main_loadAsset(JNIEnv *env, jobject instance, jobject manager)
{

    AAssetManager *mgr = AAssetManager_fromJava(env, manager);
    game->loadShaders(mgr);

}

}

And here is the code to recover the contents of the files:

void GameMain::loadShaders(AAssetManager *mgr)
{

    AAssetDir *shadersDir = AAssetManager_openDir(mgr, "shaders");
    if(shadersDir == NULL){
        __android_log_write(ANDROID_LOG_ERROR, "AAsset Manager", "Shaders dir not found");
        return;
    }

    const char*fileName;

    while((fileName = AAssetDir_getNextFileName(shadersDir)) != NULL){

        __android_log_print(ANDROID_LOG_DEBUG, "AAsset Manager", "Current file %s \n", fileName);

        if(strcmp(fileName, "fragment.fs") != 0){

            AAsset *fragmentAsset = AAssetManager_open(mgr, "shaders/fragment.fs", AASSET_MODE_STREAMING);
            if(fragmentAsset == NULL){
                __android_log_write(ANDROID_LOG_ERROR, "AAsset Manager", "Fragment file not found");
                break;
            }

            off_t fragmentLength = AAsset_getLength(fragmentAsset);
            char *fragmentBuffer = (char*)malloc(fragmentLength);

            AAsset_read(fragmentAsset, fragmentBuffer, fragmentLength);

            fragmentSource = std::string(fragmentBuffer);
            __android_log_print(ANDROID_LOG_DEBUG, "AAsset Manager", "Fragment Length: %d .", fragmentLength);
            __android_log_print(ANDROID_LOG_DEBUG, "AAsset Manager", "Fragment: %s .", fragmentBuffer);

            free(fragmentBuffer);
            AAsset_close(fragmentAsset);

        }else if(strcmp(fileName, "vertex.vs") != 0){

            AAsset *vertexAsset = AAssetManager_open(mgr, "shaders/vertex.vs", AASSET_MODE_STREAMING);
            if(vertexAsset == NULL){
                __android_log_write(ANDROID_LOG_ERROR, "AAsset Manager", "Vertex file not found");
                break;
            }

            off_t vertexLength = AAsset_getLength(vertexAsset);
            char *vertexBuffer = (char*)malloc(vertexLength);

            AAsset_read(vertexAsset, vertexBuffer, vertexLength);

            vertexSource = std::string(vertexBuffer);
            __android_log_print(ANDROID_LOG_DEBUG, "AAsset Manager", "Vertex Length: %d .", vertexLength);
            __android_log_print(ANDROID_LOG_DEBUG, "AAsset Manager", "Vertex: %s .", vertexBuffer);

            free(vertexBuffer);
            AAsset_close(vertexAsset);

        }

    }

    AAssetDir_close(shadersDir);

    m_Render->setShadersSource(vertexSource, fragmentSource);

}

It turns out that the buffer is adding non-existent characters in null files, including thought that a plugin that I installed in android studio to format the glsl code would be adding these characters, but even after uninstalling and checking in windows explorer that the file was size 0.

Here’s the way out:

Saída do compilador de shaders

Saída do log

Note that it also changes the order of the characters, for example here is an excerpt from a Shader:

#version 300 es

//fragment

The output in the log is as follows: #version 300 es //fragmentmll

What could be causing this disorder?

  • put the contents of Shader, after all the message says who has an invalid character in the Shader file and cannot compile it.

1 answer

0

I am very expert in Java or Opengl.

But I’ve handled a lot of CUDA programs ( Nvidia ) with codes in C, C++ and Delphi mixed. And one problem that tends to occur a lot is type compatibility.

For example, in a certain language a Int can be occupy 2 bytes and be the Signed, while in another may occupy 4 bytes may be Signed or unsigned. Since the machine does not actually know any data types, it only receives a bit sequence and interprets it in the way it is ordered.
And this is where the problem comes in: one data was stored in an interpretation in a code of a programming language, and was obtained and handled with another by the other code of the other language.


As I saw from the prints you’re complaining about unknown characters, I’ve come to such conclusion:

Java stores characters in spaces 2 bytes unsigned (unsigned), from 0 to 65,535, as reported here,
C/C++ stores them with 1 byte down-low (Signed), from -128 to +127.

Conventional characters belong to the table ASCII, comprising a total of 128 characters.

The problem must have been that in java a character code 238 ( for example) was put in a char in C/C++, and so did not recognize the character ( because it does not belong to the ASCII table).


Try checking the types and printing the contents of the string through both languages being used, so you know what is going on inside, and then fix by making an appropriate conversion of types.

  • This is kind of weird, Aassetmanager_fromjava should recover the reference from the java Assets manager and take the file contents directly from c++, which is making me confused.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.