最後に、他のいくつかの投稿などに従って、OpenGL 2.0 (Android) で球体を作成しました。
ただし、現在は塗りつぶされているのではなく、ワイヤーフレームとしてレンダリングされています。
ドローコード
public void draw()
{
// Set our per-vertex lighting program.
GLES20.glUseProgram(mProgramHandle);
// Set program handles for drawing.
mRenderer.mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
mRenderer.mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
mNormalHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Normal");
mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
mColorHandle = GLES20.glGetUniformLocation(mProgramHandle, "v_Color");
// Translate the cube into the screen.
Matrix.setIdentityM(mRenderer.mModelMatrix, 0);
Matrix.translateM(mRenderer.mModelMatrix, 0, position.x, position.y, position.z);
Matrix.scaleM(mRenderer.mModelMatrix, 0, scale.x, scale.y, scale.z);
Matrix.rotateM(mRenderer.mModelMatrix, 0, rotation.x, 1, 0,0);
Matrix.rotateM(mRenderer.mModelMatrix, 0, rotation.y, 0, 1,0);
Matrix.rotateM(mRenderer.mModelMatrix, 0, rotation.z, 0, 0,1);
float color[] = { 0.0f, 0.0f, 1.0f, 1.0f };
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, BYTES_PER_VERTEX, vertexBuffer);
GLES20.glEnableVertexAttribArray(mNormalHandle);
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mRenderer.mMVPMatrix, 0, mRenderer.mViewMatrix, 0, mRenderer.mModelMatrix, 0);
// Pass in the modelview matrix.
GLES20.glUniformMatrix4fv(mRenderer.mMVMatrixHandle, 1, false, mRenderer.mMVPMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mTemporaryMatrix, 0, mRenderer.mProjectionMatrix, 0, mRenderer.mMVPMatrix, 0);
System.arraycopy(mTemporaryMatrix, 0, mRenderer.mMVPMatrix, 0, 16);
// Pass in the combined matrix.
GLES20.glUniformMatrix4fv(mRenderer.mMVPMatrixHandle, 1, false, mRenderer.mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);
//GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
}
球体作成コード
private void generateSphereCoords(float radius, int stacks, int slices)
{
for (int stackNumber = 0; stackNumber <= stacks; ++stackNumber)
{
for (int sliceNumber = 0; sliceNumber < slices; ++sliceNumber)
{
float theta = (float) (stackNumber * Math.PI / stacks);
float phi = (float) (sliceNumber * 2 * Math.PI / slices);
float sinTheta = FloatMath.sin(theta);
float sinPhi = FloatMath.sin(phi);
float cosTheta = FloatMath.cos(theta);
float cosPhi = FloatMath.cos(phi);
vertexBuffer.put(new float[]{radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta});
}
}
for (int stackNumber = 0; stackNumber < stacks; ++stackNumber)
{
for (int sliceNumber = 0; sliceNumber <= slices; ++sliceNumber)
{
indexBuffer.put((short) ((stackNumber * slices) + (sliceNumber % slices)));
indexBuffer.put((short) (((stackNumber + 1) * slices) + (sliceNumber % slices)));
}
}
}
ワイヤーフレームの代わりにこの 1 つのフルカラーを作成する方法はありますか?
私が持っているフラグメントシェーダーで
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform vec3 u_LightPos; // The position of the light in eye space.
uniform sampler2D u_Texture; // The input texture.
uniform vec4 v_Color;
varying vec3 v_Position; // Interpolated position for this fragment.
varying vec3 v_Normal; // Interpolated normal for this fragment.
// The entry point for our fragment shader.
void main()
{
// Will be used for attenuation.
float distance = length(u_LightPos - v_Position);
// Get a lighting direction vector from the light to the vertex.
vec3 lightVector = normalize(u_LightPos - v_Position);
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
float diffuse = max(dot(v_Normal, lightVector), 0.0);
// Add attenuation.
diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance)));
// Add ambient lighting
diffuse = diffuse + 0.7;
gl_FragColor = v_Color;
}
バーテックス
uniform mat4 u_MVPMatrix; // A constant representing the combined model/view/projection matrix.
uniform mat4 u_MVMatrix; // A constant representing the combined model/view matrix.
attribute vec4 a_Position; // Per-vertex position information we will pass in.
attribute vec3 a_Normal; // Per-vertex normal information we will pass in.
varying vec3 v_Position; // This will be passed into the fragment shader.
varying vec3 v_Normal; // This will be passed into the fragment shader.
// The entry point for our vertex shader.
void main()
{
// Transform the vertex into eye space.
v_Position = vec3(u_MVMatrix * a_Position);
// Transform the normal's orientation into eye space.
v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));
// gl_Position is a special variable used to store the final position.
// Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
gl_Position = u_MVPMatrix * a_Position;
}