Android OpenGL shader


#1

Hi, I’m new in shader mobile programming sorry from stupid question :slight_smile:
I create OpenGLRenderer component and try use shaders.
In windows work fine, but in phone i see black screen.
Create simple check that LanguageVersion used,
windows showed version 4.5 and in phone 1 (click on screen)
Test my phone that the version is supported

I think that by default used version 1, how to switch to the second version
Android 5.1

compile setting:
android {
compileSdkVersion = 21
buildToolsVersion = "25"
defaultConfig.with {
applicationId = "appid"
minSdkVersion.apiLevel = 21
targetSdkVersion.apiLevel =21
}
}

class Shader : public Component, public OpenGLRenderer, public Timer
{
public:
	Shader(){
		openGLContext.setComponentPaintingEnabled(true);
		openGLContext.setRenderer(this); //set openglrenderer to this
		openGLContext.setContinuousRepainting(true);
		openGLContext.attachTo(*this); //atach context to this
		startTimer(30);
		
	}
	~Shader() {
		sp->release();
	}


	void timerCallback(void) override
	{
	}
	void mouseDown(const MouseEvent &m) override
	{
		NativeMessageBox::showMessageBoxAsync(AlertWindow::NoIcon, String(LanguageVersion), String(LanguageVersion));
	}
	void newOpenGLContextCreated() {}
	void openGLContextClosing() {}
	void renderOpenGL() override 
	{
		static int show = 0;
		if(show == 0)
		{
			sp = new OpenGLShaderProgram(openGLContext);
			show = 1;
			LanguageVersion = sp->getLanguageVersion();

			const char* vsSource =
				"attribute vec2 position;\n"
				"attribute vec4 color;\n"
				"uniform vec2 translate;\n"
				"varying vec4 interpolatedColor;\n"
				"void main() {\n"
				"  gl_Position = vec4(position.x + translate.x, position.y + translate.y, 0.0, 1.0);\n"
				"  interpolatedColor = color;\n"
				"}\n";
			const char* fsSource =
				"varying vec4 interpolatedColor;\n"
				"void main() {\n"
				"  gl_FragColor = interpolatedColor;\n"
				"}\n";
					
			sp->addVertexShader(vsSource);
            sp->addFragmentShader(fsSource);
            sp->link();
			Program = sp->getProgramID();
			attr_position = OpenGLShaderProgram::Attribute(*sp, "position").attributeID;
			attr_color = OpenGLShaderProgram::Attribute(*sp, "color").attributeID;
		}
	
		glViewport(0, 0, getWidth(), getHeight());   
		glClear(GL_COLOR_BUFFER_BIT);

		static float red[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; 
		static float colors[] = {
			1.0f,0.0f,0.0f,1.0f,
			0.0f,1.0f,0.0f,1.0f,
			0.0f,0.0f,1.0f,1.0f,
		};
		static float position[] = {
			 -0.7f,-0.7f ,
			 0.7f, -0.7f ,
			 0.0f,0.7f  
		};
		sp->use();
		openGLContext.extensions.glEnableVertexAttribArray(attr_position);
		openGLContext.extensions.glVertexAttribPointer(attr_position, 2, GL_FLOAT, false, sizeof(float) * 2, position);
		openGLContext.extensions.glEnableVertexAttribArray(attr_color);
		openGLContext.extensions.glVertexAttribPointer(attr_color, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, colors);

		glDrawArrays(GL_TRIANGLES, 0, 3);
		return;
}
private:
	OpenGLContext openGLContext;
	double LanguageVersion;
	ScopedPointer<OpenGLShaderProgram> sp;
	GLuint Program;
	GLuint attr_position;
	GLuint attr_color;
};

#2

OpenGLContext::setOpenGLVersionRequired might help


#3

Thanks for your answer, unfortunately did not help. I decided to abandon the shaders to make it use paint function


#4

Hey Navira, seems you have OpenGL experience, do you know if what we have now on OpenGL + Juce i can play a video on Android… i’m so lost at this…!! any help will be appreciated…

Cheers, Happy St Patrick


#5

Hi, Inside the code I could not find a way to play the video, I can help by showing how to link Java and С++ (create simple messagebox with java and c++)
First need create new code inside java

public final void MyMessageBox (String title, String message, final long callback)
{
    AlertDialog.Builder builder = new AlertDialog.Builder (this);
    builder.setTitle (title)
            .setMessage (message)
            .setCancelable (true)
            .setPositiveButton ("OK", new DialogInterface.OnClickListener()
            {
                public void onClick (DialogInterface dialog, int id)
                {
                    dialog.cancel();

                }
            });

    builder.create().show();
}

then goto juce_android_JNIHelpers.h and add line
METHOD(MyMessageBox, "MyMessageBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
im added it after 277 line
then goto juce_NativeMessageBox.h and add

   static void JUCE_CALLTYPE showmymessage (AlertWindow::AlertIconType iconType,
    const String& title,
    const String& message,
            Component* associatedComponent = nullptr,
            ModalComponentManager::Callback* callback = nullptr);

and then goto juce_android_Windowing.cpp and add

void JUCE_CALLTYPE NativeMessageBox::showmymessage (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
        Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
android.activity.callVoidMethod (JuceAppActivity.MyMessageBox, javaString (title).get(),
        javaString (message).get(), (jlong) (pointer_sized_int) callback);
}

now we can use new java function (im not sure that this right way, but it work)
NativeMessageBox::showmymessage(AlertWindow::NoIcon,String("Hi java"),String::empty);
I hope this helps you


Video on Android
#6

OmG Navira, this looks quite straightforward, ill try it tonight when im home!

Cant thank you enough for this…!!

One question, do you think this will work for VideoView or that thing whatever is called on Java.


void sayThanksToNavira()
{

for (int i = 0; i < 100000; ++i)
{
  printf( "thanks\n" );
}
}


#7

I’ve never played a video before :smile: but in java already have class
public static class NativeSurfaceView
I think you need to create a videoview in a similar way


#8

Thanks man! I got it done thanks of you!