我正在绘制一个简单的3D形状。从.obj文件中读取形状,整个形状有一种颜色。 我想创造一种改变颜色的可能性。例如,如果我点击按钮,我想让结构变红。
我已经阅读了很多教程,但我无法弄清楚如何在运行时更改颜色(重绘元素?)。我在onDrawFrame
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, colorBuffer);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
但没有任何改变。
我应该在何处以及如何实施此类行动?
//更新
绘制方法
if(!initialized) {
init(gl);
initialized = true;
}
if(glCameraMatrixBuffer != null) {
glMatrixBuffer.put(glMatrix);
glMatrixBuffer.position(0);
//argDrawMode3D
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
//argDraw3dCamera
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadMatrixf( glCameraMatrixBuffer );
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadMatrixf(glMatrixBuffer);
}
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, colorBuffer);
for(int i=0; i<parts.size(); i++){
TDModelPart t=parts.get(i);
Material m=t.getMaterial();
if(m!=null){
FloatBuffer a=m.getAmbientColorBuffer();
FloatBuffer d=m.getDiffuseColorBuffer();
FloatBuffer s=m.getSpecularColorBuffer();
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_AMBIENT,a);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_SPECULAR,s);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_DIFFUSE,d);
}
gl.glNormalPointer(GL10.GL_FLOAT, 0, t.getNormalBuffer());
gl.glDrawElements(GL10.GL_TRIANGLES,t.getFacesCount(),GL10.GL_UNSIGNED_SHORT,t.getFaceBuffer());
}
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
public final void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
if (DEBUG) {
gl = (GL10) GLDebugHelper.wrap(gl, GLDebugHelper.CONFIG_CHECK_GL_ERROR, log);
}
setupDraw2D(gl);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glDisable(GL10.GL_LIGHTING);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
//load new preview frame as a texture, if needed
if (frameEnqueued) {
frameLock.lock();
if (!isTextureInitialized) {
initializeTexture(gl);
} else {
//just update the image
//can we just update a portion(non power of two)?...seems to work
gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, previewFrameWidth, previewFrameHeight,
mode, GL10.GL_UNSIGNED_BYTE, frameData);
}
frameLock.unlock();
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
frameEnqueued = false;
}
gl.glColor4f(1, 1, 1, 1f);
//draw camera preview frame:
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, squareBuffer);
//draw camera square
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
if (customRenderer != null) {
customRenderer.setupEnv(gl);
} else {
// gl.glEnable(GL10.GL_LIGHTING);
// gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientLightBuffer);
// gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuseLightBuffer);
// gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specularLightBuffer);
// gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPositionBuffer);
// gl.glEnable(GL10.GL_LIGHT0);
}
matrixGrabber.getCurrentState(gl);
if (performAction) {
Log.d("ZMIANA_KOLORY", "akcja się wola");
int[] c = new int[]{255, 0, 0};
Vector<Float> v = markerInfo.getObjects().get(0).vectors;
ByteBuffer vBuf = ByteBuffer.allocateDirect(v.size() * 4);
vBuf.order(ByteOrder.nativeOrder());
float[] newColor = new float[c.length + 1];
for (int i = 0; i < c.length; i++) {
newColor[i] = (1.0f / 255) * c[i];
newColor[3] = 1.0f;
}
Log.d("ZMIANA_KOLORY", newColor[0] + " " + newColor[1] + " " + newColor[2] + " " + newColor[3] + " ");
FloatBuffer colorBuffer = vBuf.asFloatBuffer();
colorBuffer.put(newColor);
colorBuffer.position(0);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, colorBuffer);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
performAction = false;
// Log.d("PERFORM_ACTION", "wykonuję akcję: " + actionName);
// switch (actionName) {
// case "Highlight":
//
// for(ARObject obj : markerInfo.getObjects()) {
//// if(tmp.get)
//
// }
//
// actionName = null;
// performAction = false;
// break;
// }
}
markerInfo.draw(gl);
if (customRenderer != null) {
customRenderer.draw(gl);
}
if (takeScreenshot) {
Log.d("SCREENSHOT", "Sprawdzam touched");
Ray r = new Ray(gl, screenWidth, screenHeight, x, y);
Log.d("SCREENSHOT", "Near Coord =" + Arrays.toString(r.P0));
Log.d("SCREENSHOT", "Far Coord =" + Arrays.toString(r.P1));
takeScreenshot = false;
}
}
答案 0 :(得分:0)
OpenGL是一个基于状态的绘图系统。在您进行绘图调用的那一刻,未激活/启用的状态无效。您正在启用颜色数组,设置指针,然后再次禁用它后立即。对于要考虑的颜色顶点数组,必须启用它。
但是你似乎也在那里使用纹理。最重要的是,您正在使用固定功能管道(FFP)。纹理,颜色和照明之间存在许多相互作用,这些相互作用都会导致颜色不显示或没有像您期望的那样出现。
帮自己一个忙,开始使用着色器。了解FFP的工作方式并不难;但是它增长了很多状态切换和数据路径,使用它变得非常麻烦。您可以根据需要编写40多行代码来设置FFP,也可以编写单行着色器代码以达到同样的效果。