Added scale and offset uniforms to tex shader to properly handle npot and inverted textures

This commit is contained in:
codeanticode
2012-02-12 15:33:33 +00:00
parent 530c28a5f5
commit 2bae5ffecb
10 changed files with 270 additions and 89 deletions
@@ -23,9 +23,13 @@ precision mediump float;
uniform sampler2D textureSampler;
uniform vec2 texcoordScale;
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec2 vertTexcoord;
void main() {
gl_FragColor = texture2D(textureSampler, vertTexcoord) * vertColor;
vec2 uv = vertTexcoord * texcoordScale + texcoordOffset;
gl_FragColor = texture2D(textureSampler, uv) * vertColor;
}
+3 -3
View File
@@ -402,11 +402,11 @@ public class PGL {
// very large transient array which in certain situations (memory-
// constrained android devices) might lead to an out-of-memory error.
int[] texels = new int[16 * 16];
for (int y = 0; y < height + 16; y += 16) {
for (int y = 0; y < height; y += 16) {
int h = PApplet.min(16, height - y);
for (int x = 0; x < width + 16; x += 16) {
for (int x = 0; x < width; x += 16) {
int w = PApplet.min(16, width - x);
gl.glTexSubImage2D(target, 0, x, y, w, h, format, type, IntBuffer.wrap(texels));
GLES20.glTexSubImage2D(target, 0, x, y, w, h, format, type, IntBuffer.wrap(texels));
}
}
}
@@ -2038,13 +2038,8 @@ public class PGraphicsAndroid3D extends PGraphics {
}
if (textured && textureMode == IMAGE) {
u /= textureImage.width;
v /= textureImage.height;
PTexture tex = queryTexture(textureImage);
if (tex != null && tex.isFlippedY()) {
v = 1 - v;
}
u = PApplet.min(1, u / textureImage.width);
v = PApplet.min(1, v / textureImage.height);
}
inGeo.addVertex(x, y, z,
@@ -2268,10 +2263,10 @@ public class PGraphicsAndroid3D extends PGraphics {
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.fillIndexCount * PGL.SIZEOF_INDEX,
ShortBuffer.wrap(tessGeo.fillIndices, 0, tessGeo.fillIndexCount), vboMode);
texCache.beginRender();
for (int i = 0; i < texCache.count; i++) {
PTexture tex = texCache.getTexture(i);
texCache.beginRender();
for (int i = 0; i < texCache.count; i++) {
PTexture tex = texCache.getTexture(i);
FillShader shader = getFillShader(lights, tex != null);
shader.start();
@@ -2286,8 +2281,9 @@ public class PGraphicsAndroid3D extends PGraphics {
shader.setShininessAttribute(glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, 0);
}
if (tex != null) {
shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0);
if (tex != null) {
shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0);
shader.setTexture(tex);
}
int offset = texCache.firstIndex[i];
@@ -2303,7 +2299,7 @@ public class PGraphicsAndroid3D extends PGraphics {
// Utility function to render current tessellated geometry, under the assumption that
// the texture is already bound.
protected void renderTexFill() {
protected void renderTexFill(PTexture tex) {
if (!fillVBOsCreated) {
createFillBuffers();
fillVBOsCreated = true;
@@ -2316,6 +2312,7 @@ public class PGraphicsAndroid3D extends PGraphics {
shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0);
shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0);
shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0);
shader.setTexture(tex);
if (lights) {
shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0);
@@ -5214,7 +5211,7 @@ public class PGraphicsAndroid3D extends PGraphics {
public PTexture getTexture(PImage img) {
PTexture tex = (PTexture)img.getCache(pg);
if (tex == null) {
tex = addTexture(img);
tex = addTexture(img);
} else {
if (!pgl.contextIsCurrent(tex.context)) {
// The texture was created with a different context. We need
@@ -5265,10 +5262,10 @@ public class PGraphicsAndroid3D extends PGraphics {
params = PTexture.newParameters();
img.setParams(pg, params);
}
PTexture tex = new PTexture(img.parent, img.width, img.height, params);
PTexture tex = new PTexture(img.parent, img.width, img.height, params);
img.loadPixels();
if (img.pixels != null) tex.set(img.pixels);
img.setCache(pg, tex);
if (img.pixels != null) tex.set(img.pixels);
img.setCache(pg, tex);
return tex;
}
@@ -5400,7 +5397,7 @@ public class PGraphicsAndroid3D extends PGraphics {
* Pushes a normalized (1x1) textured quad to the GPU.
*/
protected void drawTexQuad(float u0, float v0, float u1, float v1) {
// TODO: need to test...
// TODO: need to fix null thing, test...
stroke = false;
beginShape(QUAD);
vertex(0, 0, u0, v0);
@@ -5409,7 +5406,7 @@ public class PGraphicsAndroid3D extends PGraphics {
vertex(0, 1, u0, v1);
endShape();
tessellate(OPEN);
renderTexFill();
renderTexFill(null); // we need the texture object here...
}
@@ -5708,7 +5705,8 @@ public class PGraphicsAndroid3D extends PGraphics {
public void setSpecularAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setEmissiveAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setShininessAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setTexture(PTexture tex) { }
}
protected class FillShaderSimple extends FillShader {
@@ -5895,8 +5893,13 @@ public class PGraphicsAndroid3D extends PGraphics {
}
protected class FillShaderTex extends FillShaderSimple {
protected int texcoordScaleLoc;
protected int texcoordOffsetLoc;
protected int inTexcoordLoc;
PTexture texture;
public FillShaderTex(PApplet parent, String vertFilename, String fragFilename) {
super(parent, vertFilename, fragFilename);
}
@@ -5905,6 +5908,13 @@ public class PGraphicsAndroid3D extends PGraphics {
super(parent, vertURL, fragURL);
}
public void loadUniforms() {
super.loadUniforms();
texcoordScaleLoc = getUniformLocation("texcoordScale");
texcoordOffsetLoc = getUniformLocation("texcoordOffset");
}
public void loadAttributes() {
super.loadAttributes();
@@ -5915,6 +5925,26 @@ public class PGraphicsAndroid3D extends PGraphics {
setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset);
}
public void setTexture(PTexture tex) {
texture = tex;
// Calculate scale and offset for texture coordinates
// and passing them to the fragment shader.
float scaleu = tex.maxTexCoordU;
float scalev = tex.maxTexCoordV;
float offsetu = 0;
float offsetv = 0;
if (tex.isFlippedY()) {
scalev *= -1;
offsetv = 1;
}
set2FloatUniform(texcoordScaleLoc, scaleu, scalev);
set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv);
}
public void start() {
super.start();
@@ -5931,6 +5961,9 @@ public class PGraphicsAndroid3D extends PGraphics {
protected class FillShaderFull extends FillShaderLit {
protected int inTexcoordLoc;
protected int texcoordScaleLoc;
protected int texcoordOffsetLoc;
public FillShaderFull(PApplet parent, String vertFilename, String fragFilename) {
super(parent, vertFilename, fragFilename);
}
@@ -5938,6 +5971,13 @@ public class PGraphicsAndroid3D extends PGraphics {
public FillShaderFull(PApplet parent, URL vertURL, URL fragURL) {
super(parent, vertURL, fragURL);
}
public void loadUniforms() {
super.loadUniforms();
texcoordScaleLoc = getUniformLocation("texcoordScale");
texcoordOffsetLoc = getUniformLocation("texcoordOffset");
}
public void loadAttributes() {
super.loadAttributes();
@@ -5949,6 +5989,26 @@ public class PGraphicsAndroid3D extends PGraphics {
setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset);
}
public void setTexture(PTexture tex) {
texture = tex;
// Calculate scale and offset for texture coordinates
// and passing them to the fragment shader.
float scaleu = tex.maxTexCoordU;
float scalev = tex.maxTexCoordV;
float offsetu = 0;
float offsetv = 0;
if (tex.isFlippedY()) {
scalev *= -1;
offsetv = 1;
}
set2FloatUniform(texcoordScaleLoc, scaleu, scalev);
set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv);
}
public void start() {
super.start();
+48 -16
View File
@@ -158,82 +158,114 @@ public class PShader {
public void setIntUniform(int loc, int x) {
pgl.glUniform1i(loc, x);
if (-1 < loc) {
pgl.glUniform1i(loc, x);
}
}
public void set1FloatUniform(int loc, float x) {
pgl.glUniform1f(loc, x);
if (-1 < loc) {
pgl.glUniform1f(loc, x);
}
}
public void set2FloatUniform(int loc, float x, float y) {
pgl.glUniform2f(loc, x, y);
if (-1 < loc) {
pgl.glUniform2f(loc, x, y);
}
}
public void set3FloatUniform(int loc, float x, float y, float z) {
pgl.glUniform3f(loc, x, y, z);
if (-1 < loc) {
pgl.glUniform3f(loc, x, y, z);
}
}
public void set4FloatUniform(int loc, float x, float y, float z, float w) {
pgl.glUniform4f(loc, x, y, z, w);
if (-1 < loc) {
pgl.glUniform4f(loc, x, y, z, w);
}
}
public void set1FloatVecUniform(int loc, float[] vec) {
pgl.glUniform1fv(loc, vec.length, vec, 0);
if (-1 < loc) {
pgl.glUniform1fv(loc, vec.length, vec, 0);
}
}
public void set2FloatVecUniform(int loc, float[] vec) {
pgl.glUniform2fv(loc, vec.length / 2, vec, 0);
if (-1 < loc) {
pgl.glUniform2fv(loc, vec.length / 2, vec, 0);
}
}
public void set3FloatVecUniform(int loc, float[] vec) {
pgl.glUniform3fv(loc, vec.length / 3, vec, 0);
if (-1 < loc) {
pgl.glUniform3fv(loc, vec.length / 3, vec, 0);
}
}
public void set4FloatVecUniform(int loc, float[] vec) {
pgl.glUniform4fv(loc, vec.length / 4, vec, 0);
if (-1 < loc) {
pgl.glUniform4fv(loc, vec.length / 4, vec, 0);
}
}
public void set2x2MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix2fv(loc, 1, false, mat, 0);
if (-1 < loc) {
pgl.glUniformMatrix2fv(loc, 1, false, mat, 0);
}
}
public void set3x3MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix3fv(loc, 1, false, mat, 0);
if (-1 < loc) {
pgl.glUniformMatrix3fv(loc, 1, false, mat, 0);
}
}
public void set4x4MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix4fv(loc, 1, false, mat, 0);
if (-1 < loc) {
pgl.glUniformMatrix4fv(loc, 1, false, mat, 0);
}
}
public void set1FloatAttribute(int loc, float x) {
pgl.glVertexAttrib1f(loc, x);
if (-1 < loc) {
pgl.glVertexAttrib1f(loc, x);
}
}
public void set2FloatAttribute(int loc, float x, float y) {
pgl.glVertexAttrib2f(loc, x, y);
if (-1 < loc) {
pgl.glVertexAttrib2f(loc, x, y);
}
}
public void set3FloatAttribute(int loc, float x, float y, float z) {
pgl.glVertexAttrib3f(loc, x, y, z);
if (-1 < loc) {
pgl.glVertexAttrib3f(loc, x, y, z);
}
}
public void set4FloatAttribute(int loc, float x, float y, float z, float w) {
pgl.glVertexAttrib4f(loc, x, y, z, w);
if (-1 < loc) {
pgl.glVertexAttrib4f(loc, x, y, z, w);
}
}
@@ -610,13 +610,8 @@ public class PShape3D extends PShape {
}
if (texture != null && textureMode == IMAGE) {
u /= texture.width;
v /= texture.height;
PTexture tex = pg.queryTexture(texture);
if (tex != null && tex.isFlippedY()) {
v = 1 - v;
}
u = PApplet.min(1, u / texture.width);
v = PApplet.min(1, v / texture.height);
}
int scolor = 0x00;
@@ -775,19 +775,19 @@ public class PTexture implements PConstants {
pgl.glBindTexture(glTarget, glID);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MIN_FILTER, glMinFilter);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_S, glWrapS);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT);
// First, we use glTexImage2D to set the full size of the texture (glW/glH might be diff
// from w/h in the case that the GPU doesn't support NPOT textures)
pgl.glTexImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, null);
// Makes sure that the texture buffer in video memory doesn't contain any garbage.
pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE);
pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE);
pgl.glBindTexture(glTarget, 0);
pgl.disableTexturing(glTarget);
pgl.disableTexturing(glTarget);
}
@@ -21,9 +21,13 @@
uniform sampler2D textureSampler;
uniform vec2 texcoordScale;
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec2 vertTexcoord;
void main() {
gl_FragColor = texture2D(textureSampler, vertTexcoord) * vertColor;
vec2 uv = vertTexcoord * texcoordScale + texcoordOffset;
gl_FragColor = texture2D(textureSampler, uv) * vertColor;
}
@@ -2044,13 +2044,8 @@ public class PGraphicsOpenGL extends PGraphics {
}
if (textured && textureMode == IMAGE) {
u /= textureImage.width;
v /= textureImage.height;
PTexture tex = queryTexture(textureImage);
if (tex != null && tex.isFlippedY()) {
v = 1 - v;
}
u = PApplet.min(1, u / textureImage.width);
v = PApplet.min(1, v / textureImage.height);
}
inGeo.addVertex(x, y, z,
@@ -2293,7 +2288,8 @@ public class PGraphicsOpenGL extends PGraphics {
}
if (tex != null) {
shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0);
shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0);
shader.setTexture(tex);
}
int offset = texCache.firstIndex[i];
@@ -2309,7 +2305,7 @@ public class PGraphicsOpenGL extends PGraphics {
// Utility function to render current tessellated geometry, under the assumption that
// the texture is already bound.
protected void renderTexFill() {
protected void renderTexFill(PTexture tex) {
if (!fillVBOsCreated) {
createFillBuffers();
fillVBOsCreated = true;
@@ -2322,6 +2318,7 @@ public class PGraphicsOpenGL extends PGraphics {
shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0);
shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0);
shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0);
shader.setTexture(tex);
if (lights) {
shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0);
@@ -5406,7 +5403,7 @@ public class PGraphicsOpenGL extends PGraphics {
* Pushes a normalized (1x1) textured quad to the GPU.
*/
protected void drawTexQuad(float u0, float v0, float u1, float v1) {
// TODO: need to test...
// TODO: need to fix null thing, test...
stroke = false;
beginShape(QUAD);
vertex(0, 0, u0, v0);
@@ -5415,7 +5412,7 @@ public class PGraphicsOpenGL extends PGraphics {
vertex(0, 1, u0, v1);
endShape();
tessellate(OPEN);
renderTexFill();
renderTexFill(null); // we need the texture object here...
}
@@ -5714,7 +5711,8 @@ public class PGraphicsOpenGL extends PGraphics {
public void setSpecularAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setEmissiveAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setShininessAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { }
public void setTexture(PTexture tex) { }
}
protected class FillShaderSimple extends FillShader {
@@ -5902,8 +5900,13 @@ public class PGraphicsOpenGL extends PGraphics {
}
protected class FillShaderTex extends FillShaderSimple {
protected int texcoordScaleLoc;
protected int texcoordOffsetLoc;
protected int inTexcoordLoc;
PTexture texture;
public FillShaderTex(PApplet parent, String vertFilename, String fragFilename) {
super(parent, vertFilename, fragFilename);
}
@@ -5912,6 +5915,13 @@ public class PGraphicsOpenGL extends PGraphics {
super(parent, vertURL, fragURL);
}
public void loadUniforms() {
super.loadUniforms();
texcoordScaleLoc = getUniformLocation("texcoordScale");
texcoordOffsetLoc = getUniformLocation("texcoordOffset");
}
public void loadAttributes() {
super.loadAttributes();
@@ -5922,6 +5932,26 @@ public class PGraphicsOpenGL extends PGraphics {
setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset);
}
public void setTexture(PTexture tex) {
texture = tex;
// Calculate scale and offset for texture coordinates
// and passing them to the fragment shader.
float scaleu = tex.maxTexCoordU;
float scalev = tex.maxTexCoordV;
float offsetu = 0;
float offsetv = 0;
if (tex.isFlippedY()) {
scalev *= -1;
offsetv = 1;
}
set2FloatUniform(texcoordScaleLoc, scaleu, scalev);
set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv);
}
public void start() {
super.start();
@@ -5938,6 +5968,9 @@ public class PGraphicsOpenGL extends PGraphics {
protected class FillShaderFull extends FillShaderLit {
protected int inTexcoordLoc;
protected int texcoordScaleLoc;
protected int texcoordOffsetLoc;
public FillShaderFull(PApplet parent, String vertFilename, String fragFilename) {
super(parent, vertFilename, fragFilename);
}
@@ -5945,6 +5978,13 @@ public class PGraphicsOpenGL extends PGraphics {
public FillShaderFull(PApplet parent, URL vertURL, URL fragURL) {
super(parent, vertURL, fragURL);
}
public void loadUniforms() {
super.loadUniforms();
texcoordScaleLoc = getUniformLocation("texcoordScale");
texcoordOffsetLoc = getUniformLocation("texcoordOffset");
}
public void loadAttributes() {
super.loadAttributes();
@@ -5956,6 +5996,26 @@ public class PGraphicsOpenGL extends PGraphics {
setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset);
}
public void setTexture(PTexture tex) {
texture = tex;
// Calculate scale and offset for texture coordinates
// and passing them to the fragment shader.
float scaleu = tex.maxTexCoordU;
float scalev = tex.maxTexCoordV;
float offsetu = 0;
float offsetv = 0;
if (tex.isFlippedY()) {
scalev *= -1;
offsetv = 1;
}
set2FloatUniform(texcoordScaleLoc, scaleu, scalev);
set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv);
}
public void start() {
super.start();
@@ -160,84 +160,115 @@ public class PShader {
public void setIntUniform(int loc, int x) {
pgl.glUniform1i(loc, x);
if (-1 < loc) {
pgl.glUniform1i(loc, x);
}
}
public void set1FloatUniform(int loc, float x) {
pgl.glUniform1f(loc, x);
if (-1 < loc) {
pgl.glUniform1f(loc, x);
}
}
public void set2FloatUniform(int loc, float x, float y) {
pgl.glUniform2f(loc, x, y);
if (-1 < loc) {
pgl.glUniform2f(loc, x, y);
}
}
public void set3FloatUniform(int loc, float x, float y, float z) {
pgl.glUniform3f(loc, x, y, z);
if (-1 < loc) {
pgl.glUniform3f(loc, x, y, z);
}
}
public void set4FloatUniform(int loc, float x, float y, float z, float w) {
pgl.glUniform4f(loc, x, y, z, w);
if (-1 < loc) {
pgl.glUniform4f(loc, x, y, z, w);
}
}
public void set1FloatVecUniform(int loc, float[] vec) {
pgl.glUniform1fv(loc, vec.length, vec, 0);
if (-1 < loc) {
pgl.glUniform1fv(loc, vec.length, vec, 0);
}
}
public void set2FloatVecUniform(int loc, float[] vec) {
pgl.glUniform2fv(loc, vec.length / 2, vec, 0);
if (-1 < loc) {
pgl.glUniform2fv(loc, vec.length / 2, vec, 0);
}
}
public void set3FloatVecUniform(int loc, float[] vec) {
pgl.glUniform3fv(loc, vec.length / 3, vec, 0);
if (-1 < loc) {
pgl.glUniform3fv(loc, vec.length / 3, vec, 0);
}
}
public void set4FloatVecUniform(int loc, float[] vec) {
pgl.glUniform4fv(loc, vec.length / 4, vec, 0);
if (-1 < loc) {
pgl.glUniform4fv(loc, vec.length / 4, vec, 0);
}
}
public void set2x2MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix2fv(loc, 1, false, mat, 0);
if (-1 < loc) {
pgl.glUniformMatrix2fv(loc, 1, false, mat, 0);
}
}
public void set3x3MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix3fv(loc, 1, false, mat, 0);
if (-1 < loc) {
pgl.glUniformMatrix3fv(loc, 1, false, mat, 0);
}
}
public void set4x4MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix4fv(loc, 1, false, mat, 0);
if (-1 < loc) {
pgl.glUniformMatrix4fv(loc, 1, false, mat, 0);
}
}
public void set1FloatAttribute(int loc, float x) {
pgl.glVertexAttrib1f(loc, x);
if (-1 < loc) {
pgl.glVertexAttrib1f(loc, x);
}
}
public void set2FloatAttribute(int loc, float x, float y) {
pgl.glVertexAttrib2f(loc, x, y);
if (-1 < loc) {
pgl.glVertexAttrib2f(loc, x, y);
}
}
public void set3FloatAttribute(int loc, float x, float y, float z) {
pgl.glVertexAttrib3f(loc, x, y, z);
if (-1 < loc) {
pgl.glVertexAttrib3f(loc, x, y, z);
}
}
public void set4FloatAttribute(int loc, float x, float y, float z, float w) {
pgl.glVertexAttrib4f(loc, x, y, z, w);
if (-1 < loc) {
pgl.glVertexAttrib4f(loc, x, y, z, w);
}
}
protected void init() {
if (programObject == 0) {
@@ -627,13 +627,8 @@ public class PShape3D extends PShape {
}
if (texture != null && textureMode == IMAGE) {
u /= texture.width;
v /= texture.height;
PTexture tex = pg.queryTexture(texture);
if (tex != null && tex.isFlippedY()) {
v = 1 - v;
}
u = PApplet.min(1, u / texture.width);
v = PApplet.min(1, v / texture.height);
}
int scolor = 0x00;