Files
nfsmw-online/app/src/main/java/com/ea/ironmonkey/SplashScreen.java
T

256 lines
8.9 KiB
Java

package com.ea.ironmonkey;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class SplashScreen {
private static final String TAG = "SplashScreen";
private Activity _activity;
private int _attPosition;
private int _attSampler;
private int _attTexCoord;
private int _fragmentShader;
private int _program;
private int _vertexShader;
private FloatBuffer vBuffer;
// Вершинный шейдер
private final String vShaderStr =
"attribute vec4 a_position; \n" +
"attribute vec2 a_texCoord; \n" +
"varying vec2 v_texCoord; \n" +
"void main() { \n" +
" gl_Position = a_position; \n" +
" v_texCoord = a_texCoord; \n" +
"} \n";
// Фрагментный шейдер
private final String fShaderStr =
"precision mediump float; \n" +
"varying vec2 v_texCoord; \n" +
"uniform sampler2D s_texture; \n" +
"void main() { \n" +
" gl_FragColor = texture2D(s_texture, v_texCoord); \n" +
"} \n";
private int[] _textureId = new int[1];
public SplashScreen(Activity activity) {
this._activity = activity;
}
public void init(GL10 gl10, int width, int height) {
if (!initRenderer()) {
destroy(gl10);
return;
}
// Загрузка текстуры
GLES20.glGenTextures(1, _textureId, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, _textureId[0]);
// Установка параметров текстуры
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
// Загрузка изображения
Bitmap bitmap = null;
try {
InputStream is = _activity.getAssets().open("splash.png");
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {
Log.e(TAG, "Could not load bitmap", e);
}
if (bitmap != null) {
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
} else {
Log.e(TAG, "Failed to load bitmap");
destroy(gl10);
return;
}
// Проверка ошибок
int error = GLES20.glGetError();
if (error != GLES20.GL_NO_ERROR) {
Log.e(TAG, "Texture Load GLError: " + error);
destroy(gl10);
}
}
private boolean initRenderer() {
// Загрузка шейдеров
_vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vShaderStr);
_fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fShaderStr);
// Создание программы
_program = GLES20.glCreateProgram();
if (_program == 0) {
Log.e(TAG, "Failed to create program");
return false;
}
// Прикрепление шейдеров
GLES20.glAttachShader(_program, _vertexShader);
GLES20.glAttachShader(_program, _fragmentShader);
// Линковка программы
GLES20.glLinkProgram(_program);
// Проверка статуса линковки
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(_program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
Log.e(TAG, "Could not link program: " + GLES20.glGetProgramInfoLog(_program));
GLES20.glDeleteProgram(_program);
_program = 0;
return false;
}
// Получение атрибутов
_attPosition = GLES20.glGetAttribLocation(_program, "a_position");
_attTexCoord = GLES20.glGetAttribLocation(_program, "a_texCoord");
_attSampler = GLES20.glGetUniformLocation(_program, "s_texture");
return true;
}
private int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
if (shader == 0) {
Log.e(TAG, "Failed to create shader");
return 0;
}
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
// Проверка статуса компиляции
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader: " + GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
return 0;
}
return shader;
}
public boolean draw(GL10 gl10, int width, int height) {
if (_textureId[0] == 0 || _program == 0) {
return false;
}
// Расчет координат с уменьшением на 20%
float ratio = (float) width / height;
float imageRatio = 1.0f; // Предполагаем квадратное изображение
float scaleX, scaleY;
if (ratio > imageRatio) {
// Шире, чем изображение
scaleY = 0.8f; // Уменьшаем на 20%
scaleX = imageRatio / ratio * 0.8f;
} else {
// Уже, чем изображение
scaleX = 0.8f; // Уменьшаем на 20%
scaleY = ratio / imageRatio * 0.8f;
}
// Координаты вершин и текстур
float[] vertices = {
-scaleX, -scaleY, 0.0f, // нижний левый
scaleX, -scaleY, 0.0f, // нижний правый
-scaleX, scaleY, 0.0f, // верхний левый
scaleX, scaleY, 0.0f // верхний правый
};
float[] texCoords = {
0.0f, 1.0f, // нижний левый
1.0f, 1.0f, // нижний правый
0.0f, 0.0f, // верхний левый
1.0f, 0.0f // верхний правый
};
// Создание буферов
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
bb = ByteBuffer.allocateDirect(texCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer texBuffer = bb.asFloatBuffer();
texBuffer.put(texCoords);
texBuffer.position(0);
// Отрисовка с белым фоном
GLES20.glViewport(0, 0, width, height);
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Белый цвет
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(_program);
// Передача вершин
GLES20.glVertexAttribPointer(_attPosition, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
GLES20.glEnableVertexAttribArray(_attPosition);
// Передача текстурных координат
GLES20.glVertexAttribPointer(_attTexCoord, 2, GLES20.GL_FLOAT, false, 0, texBuffer);
GLES20.glEnableVertexAttribArray(_attTexCoord);
// Активация текстуры
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, _textureId[0]);
GLES20.glUniform1i(_attSampler, 0);
// Отрисовка
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
// Отключение атрибутов
GLES20.glDisableVertexAttribArray(_attPosition);
GLES20.glDisableVertexAttribArray(_attTexCoord);
return true;
}
public void destroy(GL10 gl10) {
if (_textureId[0] != 0) {
GLES20.glDeleteTextures(1, _textureId, 0);
_textureId[0] = 0;
}
if (_program != 0) {
GLES20.glDeleteProgram(_program);
_program = 0;
}
if (_vertexShader != 0) {
GLES20.glDeleteShader(_vertexShader);
_vertexShader = 0;
}
if (_fragmentShader != 0) {
GLES20.glDeleteShader(_fragmentShader);
_fragmentShader = 0;
}
if (vBuffer != null) {
vBuffer.clear();
vBuffer = null;
}
}
}