Skip to content

Commit 090cf5b

Browse files
authored
Merge pull request #300 from wetstreet/master
#3 #10 第三次实验
2 parents 3d843b4 + 45e3aef commit 090cf5b

File tree

1 file changed

+371
-0
lines changed

1 file changed

+371
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,371 @@
1+
package edu.hzuapps.androidlabs.homeworks.net1414080903226;
2+
3+
import android.content.res.Resources;
4+
import android.graphics.Bitmap;
5+
import android.graphics.BitmapFactory;
6+
import android.graphics.Color;
7+
import android.opengl.GLES20;
8+
import android.opengl.GLUtils;
9+
import android.opengl.Matrix;
10+
import android.util.Log;
11+
12+
import com.chenyirun.theircraft.model.Buffers;
13+
import com.chenyirun.theircraft.model.Point3;
14+
import com.chenyirun.theircraft.model.Point3Int;
15+
16+
import java.nio.ByteBuffer;
17+
import java.nio.ByteOrder;
18+
import java.nio.FloatBuffer;
19+
import java.nio.ShortBuffer;
20+
21+
class Net1414080903226GLHelper {
22+
private static final String TAG = "Net1414080903226GLHelper";
23+
24+
private int blockProgram;
25+
private int lineProgram;
26+
private int pointProgram;
27+
28+
public final float[] modelBlock = new float[16];
29+
private final float[] modelView = new float[16];
30+
private final float[] modelViewProjection = new float[16];
31+
32+
private int textureHandle;
33+
private int textureData;
34+
private int blockPositionParam;
35+
private int blockUVParam;
36+
private int blockModelViewProjectionParam;
37+
private int linePositionParam;
38+
private int lineModelViewProjectionParam;
39+
private int pointPositionParam;
40+
private int pointModelViewProjectionParam;
41+
42+
private static final int COORDS_PER_VERTEX = 3;
43+
private static final int VERTEX_STRIDE = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
44+
45+
private static final String BlockVertexShader =
46+
"uniform mat4 u_MVP;\n" +
47+
"attribute vec4 a_Position;\n" +
48+
"attribute vec2 a_textureCoord;\n" +
49+
"varying vec2 v_textureCoord;\n" +
50+
"\n" +
51+
"void main() {\n" +
52+
" gl_Position = u_MVP * a_Position;\n" +
53+
" v_textureCoord = a_textureCoord;\n" +
54+
"}";
55+
56+
private static final String BlockFragmentShader =
57+
"precision mediump float;\n" +
58+
"uniform sampler2D u_texture;\n" +
59+
"varying vec2 v_textureCoord;\n" +
60+
"\n" +
61+
"void main() {\n" +
62+
" gl_FragColor = texture2D(u_texture, v_textureCoord);\n" +
63+
"}";
64+
65+
private static final String LineVertexShader =
66+
"uniform mat4 u_MVP;\n" +
67+
"attribute vec4 a_Position;\n" +
68+
"\n" +
69+
"void main() {\n" +
70+
" gl_Position = u_MVP * a_Position;\n" +
71+
"}\n";
72+
73+
private static final String LineFragmentShader =
74+
"void main() {\n" +
75+
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
76+
"}\n";
77+
78+
private static final String PointVertexShader =
79+
"uniform mat4 u_MVP;\n" +
80+
"attribute vec4 a_Position;\n" +
81+
"\n" +
82+
"void main() {\n" +
83+
" gl_Position = u_MVP * a_Position;\n" +
84+
"}\n";
85+
86+
private static final String PointFragmentShader =
87+
"void main() {\n" +
88+
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
89+
"}\n";
90+
91+
public void attachVariables(Resources resources){
92+
blockProgram = Net1414080903226GLHelper.linkProgram(BlockVertexShader, BlockFragmentShader);
93+
lineProgram = Net1414080903226GLHelper.linkProgram(LineVertexShader, LineFragmentShader);
94+
pointProgram = Net1414080903226GLHelper.linkProgram(PointVertexShader, PointFragmentShader);
95+
96+
textureData = Net1414080903226GLHelper.loadTexture(resources, R.drawable.texture);
97+
textureHandle = GLES20.glGetUniformLocation(blockProgram, "u_texture");
98+
99+
blockUVParam = GLES20.glGetAttribLocation(blockProgram, "a_textureCoord");
100+
blockPositionParam = GLES20.glGetAttribLocation(blockProgram, "a_Position");
101+
blockModelViewProjectionParam = GLES20.glGetUniformLocation(blockProgram, "u_MVP");
102+
linePositionParam = GLES20.glGetAttribLocation(lineProgram, "a_Position");
103+
lineModelViewProjectionParam = GLES20.glGetUniformLocation(lineProgram, "u_MVP");
104+
pointPositionParam = GLES20.glGetAttribLocation(lineProgram, "a_Position");
105+
pointModelViewProjectionParam = GLES20.glGetUniformLocation(lineProgram, "u_MVP");
106+
}
107+
108+
public void computeMVP(float[] view, float[] perspective){
109+
Matrix.setIdentityM(modelBlock, 0);
110+
Matrix.multiplyMM(modelView, 0, view, 0, modelBlock, 0);
111+
Matrix.multiplyMM(modelViewProjection, 0, perspective, 0, modelView, 0);
112+
}
113+
114+
public void beforeDrawBlocks(){
115+
GLES20.glUseProgram(blockProgram);
116+
GLES20.glUniform1i(textureHandle, 0);
117+
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
118+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureData);
119+
120+
GLES20.glUniformMatrix4fv(blockModelViewProjectionParam, 1, false, modelViewProjection, 0);
121+
122+
GLES20.glEnableVertexAttribArray(blockPositionParam);
123+
GLES20.glEnableVertexAttribArray(blockUVParam);
124+
}
125+
126+
public void drawBlocks(Buffers buffers){
127+
GLES20.glVertexAttribPointer(blockPositionParam, 3, GLES20.GL_FLOAT, false, 0, buffers.vertexBuffer);
128+
GLES20.glVertexAttribPointer(blockUVParam, 2, GLES20.GL_FLOAT, false, 0, buffers.textureCoordBuffer);
129+
130+
GLES20.glDrawElements(
131+
GLES20.GL_TRIANGLES, buffers.drawListBuffer.limit(),
132+
GLES20.GL_UNSIGNED_SHORT, buffers.drawListBuffer);
133+
}
134+
135+
public void afterDrawBlocks(){
136+
GLES20.glDisableVertexAttribArray(blockPositionParam);
137+
GLES20.glDisableVertexAttribArray(blockUVParam);
138+
}
139+
140+
static final float positions[][] = {
141+
{-0.5f, -0.5f, -0.5f},
142+
{-0.5f, -0.5f, +0.5f},
143+
{-0.5f, +0.5f, -0.5f},
144+
{-0.5f, +0.5f, +0.5f},
145+
{+0.5f, -0.5f, -0.5f},
146+
{+0.5f, -0.5f, +0.5f},
147+
{+0.5f, +0.5f, -0.5f},
148+
{+0.5f, +0.5f, +0.5f}
149+
};
150+
static final int indices[] = {
151+
0, 1, 0, 2, 0, 4, 1, 3,
152+
1, 5, 2, 3, 2, 6, 3, 7,
153+
4, 5, 4, 6, 5, 7, 6, 7
154+
};
155+
156+
private float[] genWireFrame(Point3Int pos){
157+
float[] result = new float[72];
158+
for (int i = 0; i < 24; i++) {
159+
int j = indices[i];
160+
result[i*3] = pos.x + positions[j][0];
161+
result[i*3+1] = pos.y + positions[j][1];
162+
result[i*3+2] = pos.z + positions[j][2];
163+
}
164+
return result;
165+
}
166+
167+
public void drawWireFrame(Point3Int pos){
168+
float[] wireFrameCoords = genWireFrame(pos);
169+
drawLines(wireFrameCoords);
170+
}
171+
172+
public void drawSightVector(Point3 sightVector, Point3 pos){
173+
Point3 sv = sightVector.times(3);
174+
float[] coords = {
175+
pos.x , pos.y, pos.z,
176+
//pos.x + sv.x * ratio, pos.y + sv.y * ratio, pos.z + sv.z * ratio,
177+
pos.x + sv.x, pos.y + sv.y, pos.z + sv.z
178+
};
179+
drawLines(coords);
180+
}
181+
/*
182+
public void drawCrossHair(){
183+
float[] coords = {
184+
1920 / 2.0f, 1080.0f / 2.0f,
185+
};
186+
drawPoints(coords, 2);
187+
}
188+
*/
189+
private static final float[] pointMatrix = {
190+
2 / 1920.0f, 0, 0, 0,
191+
0, 2 / 1080.0f, 0, 0,
192+
0, 0, -1, 0,
193+
-1, -1, 0, 1
194+
};
195+
public void drawPoints(float[] pointCoords, int coordsPerVertex) {
196+
ByteBuffer bb = ByteBuffer.allocateDirect(pointCoords.length * 4);
197+
bb.order(ByteOrder.nativeOrder());
198+
FloatBuffer VertexBuffer = bb.asFloatBuffer();
199+
VertexBuffer.put(pointCoords);
200+
VertexBuffer.position(0);
201+
202+
GLES20.glUseProgram(pointProgram);
203+
GLES20.glEnableVertexAttribArray(pointPositionParam);
204+
GLES20.glVertexAttribPointer(pointPositionParam, coordsPerVertex, GLES20.GL_FLOAT, false, coordsPerVertex * 4, VertexBuffer);
205+
GLES20.glUniformMatrix4fv(pointModelViewProjectionParam, 1, false, pointMatrix, 0);
206+
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, pointCoords.length / coordsPerVertex);
207+
GLES20.glDisableVertexAttribArray(pointPositionParam);
208+
}
209+
210+
public void drawLines(float[] lineCoords) {
211+
ByteBuffer bb = ByteBuffer.allocateDirect(lineCoords.length * 4);
212+
bb.order(ByteOrder.nativeOrder());
213+
FloatBuffer VertexBuffer = bb.asFloatBuffer();
214+
VertexBuffer.put(lineCoords);
215+
VertexBuffer.position(0);
216+
217+
GLES20.glUseProgram(lineProgram);
218+
GLES20.glLineWidth(3);
219+
GLES20.glEnableVertexAttribArray(linePositionParam);
220+
GLES20.glVertexAttribPointer(linePositionParam, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, VERTEX_STRIDE, VertexBuffer);
221+
GLES20.glUniformMatrix4fv(lineModelViewProjectionParam, 1, false, modelViewProjection, 0);
222+
GLES20.glDrawArrays(GLES20.GL_LINES, 0, lineCoords.length / COORDS_PER_VERTEX);
223+
GLES20.glDisableVertexAttribArray(linePositionParam);
224+
}
225+
226+
private static final int FLOAT_SIZE_IN_BYTES = 4;
227+
228+
static FloatBuffer createFloatBuffer(float[] from) {
229+
FloatBuffer result = ByteBuffer.allocateDirect(FLOAT_SIZE_IN_BYTES * from.length)
230+
.order(ByteOrder.nativeOrder())
231+
.asFloatBuffer();
232+
result.put(from)
233+
.position(0);
234+
return result;
235+
}
236+
237+
private static final int SHORT_SIZE_IN_BYTES = 2;
238+
239+
static ShortBuffer createShortBuffer(short[] from) {
240+
ShortBuffer result = ByteBuffer.allocateDirect(SHORT_SIZE_IN_BYTES * from.length)
241+
.order(ByteOrder.nativeOrder())
242+
.asShortBuffer();
243+
result.put(from)
244+
.position(0);
245+
return result;
246+
}
247+
248+
/**
249+
* @param type Must be one of GLES20.GL_VERTEX_SHADER or GLES20.GL_FRAGMENT_SHADER).
250+
*/
251+
private static int loadShader(int type, String glsl) {
252+
if (type != GLES20.GL_VERTEX_SHADER && type != GLES20.GL_FRAGMENT_SHADER) {
253+
Exceptions.failIllegalArgument("Unsupported shader type %d", type);
254+
}
255+
256+
int shader = GLES20.glCreateShader(type);
257+
if (shader == 0) {
258+
Exceptions.fail("Failed to create a shader of type %d", type);
259+
}
260+
261+
GLES20.glShaderSource(shader, glsl);
262+
GLES20.glCompileShader(shader);
263+
264+
// Get compilation status.
265+
int[] status = new int[] { GLES20.GL_FALSE };
266+
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, status, 0);
267+
if (status[0] == GLES20.GL_FALSE) {
268+
GLES20.glGetShaderiv(shader, GLES20.GL_INFO_LOG_LENGTH, status, 0);
269+
Log.e(TAG, "Error compiling shader: " + GLES20.glGetShaderInfoLog(shader));
270+
GLES20.glDeleteShader(shader);
271+
Exceptions.fail("Failed to compile a shader of type %d, status: %d", type, status[0]);
272+
}
273+
274+
return shader;
275+
}
276+
277+
static int linkProgram(String vertexShaderGlsl, String fragmentShaderGlsl) {
278+
int vertexShader = Net1414080903226GLHelper.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderGlsl);
279+
int fragmentShader = Net1414080903226GLHelper.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderGlsl);
280+
281+
int program = GLES20.glCreateProgram();
282+
if (program == 0) {
283+
throw new RuntimeException("Failed to create a program");
284+
}
285+
286+
GLES20.glAttachShader(program, vertexShader);
287+
GLES20.glAttachShader(program, fragmentShader);
288+
GLES20.glLinkProgram(program);
289+
290+
// Get link status.
291+
int[] status = new int[] { GLES20.GL_FALSE };
292+
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0);
293+
if (status[0] == GLES20.GL_FALSE) {
294+
GLES20.glGetProgramiv(program, GLES20.GL_INFO_LOG_LENGTH, status, 0);
295+
Log.e(TAG, "Error compiling program: " + GLES20.glGetProgramInfoLog(program));
296+
GLES20.glDeleteProgram(program);
297+
throw new RuntimeException("Failed to link program");
298+
}
299+
300+
GLES20.glDeleteShader(vertexShader);
301+
GLES20.glDeleteShader(fragmentShader);
302+
return program;
303+
}
304+
305+
static int loadTexture(Resources resources, int resourceId) {
306+
int textureHandles[] = new int[1];
307+
GLES20.glGenTextures(1, textureHandles, 0);
308+
if (textureHandles[0] == 0) {
309+
throw new RuntimeException("Failed to create a texture");
310+
}
311+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandles[0]);
312+
313+
Bitmap bitmap = loadBitmap(resources, resourceId);
314+
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
315+
bitmap.recycle();
316+
317+
GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
318+
319+
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
320+
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
321+
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
322+
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
323+
324+
return textureHandles[0];
325+
}
326+
327+
private static Bitmap loadBitmap(Resources resources, int resourceId) {
328+
BitmapFactory.Options options = new BitmapFactory.Options();
329+
options.inScaled = false; // No pre-scaling
330+
Bitmap original = BitmapFactory.decodeResource(resources, resourceId, options);
331+
if (original == null) {
332+
Exceptions.fail("Failed to decode bitmap from resource %d", resourceId);
333+
}
334+
Bitmap processed = setBackgroundTransparent(original, 0xFFFF00FF);
335+
return processed;
336+
}
337+
338+
public static Bitmap setBackgroundTransparent(Bitmap bitmap,int backgroundColor) {
339+
if (bitmap != null) {
340+
int picw = bitmap.getWidth();
341+
int pich = bitmap.getHeight();
342+
int[] pix = new int[picw * pich];
343+
bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
344+
for (int y = 0; y < pich; y++) {
345+
for (int x = 0; x < picw; x++) {
346+
int index = y * picw + x;
347+
if (pix[index] == backgroundColor){
348+
pix[index] = Color.TRANSPARENT;
349+
}
350+
}
351+
}
352+
Bitmap bm = Bitmap.createBitmap(pix, picw, pich,Bitmap.Config.ARGB_8888);
353+
return bm;
354+
}
355+
return null;
356+
}
357+
358+
public static void drawBackground(){
359+
GLES20.glClearColor(0.5f, 0.69f, 1.0f, 1.0f);
360+
}
361+
362+
public static void beforeDraw(){
363+
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
364+
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
365+
GLES20.glFrontFace(GLES20.GL_CCW);
366+
GLES20.glEnable(GLES20.GL_CULL_FACE);
367+
GLES20.glCullFace(GLES20.GL_BACK);
368+
369+
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
370+
}
371+
}

0 commit comments

Comments
 (0)