OpenGL artifacts - triangles on the back overlapping the ones on the front on old iOS device - ipod-touch

I am rendering my scene as the code below
struct vertex
{
float x, y, z, nx, ny, nz;
};
bool CShell::UpdateScene()
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.3f, 0.3f, 0.4f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set the OpenGL projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const float near = 0.1f;
const float far = 1000.0f;
float top = near * tanf(fieldOfView * SIMD_PI / 180.0f);
float bottom = -top;
float left = bottom * aspectRatio;
float right = top * aspectRatio;
glFrustumf(left, right, bottom, top, near, far);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
bool CShell::RenderScene()
{
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, vertsVBO);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, elementSize, 0);
glNormalPointer(GL_FLOAT, elementSize, (const GLvoid*) normalOffset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesVBO);
glEnable(GL_LIGHTING);
lightPosition[0] = (-gravity.x()+0.0)*lightHeight;
lightPosition[1] = (-gravity.y()+0.0)*lightHeight;
lightPosition[2] = (-gravity.z()+0.5)*lightHeight;
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
float worldMat[16];
/// draw donuts
for (int i=0;i<numDonuts;i++)
{
sBoxBodies[i]->getCenterOfMassTransform().getOpenGLMatrix(worldMat);
glPushMatrix();
glMultMatrixf(worldMat);
glVertexPointer(3, GL_FLOAT, elementSize, (const GLvoid*)(char*)sizeof(vertex));
glNormalPointer(GL_FLOAT, elementSize, (const GLvoid*)(char*)(sizeof(vertex)+normalOffset));
glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_SHORT, (const GLvoid*)(char*)sizeof(GLushort));
glPopMatrix();
}
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisable(GL_LIGHTING);
return true;
}
My project uses Oolong Engine
These are two screenshots, iPodTouch 4G (iOS 6.0)
and iPodTouch 2G (iOS 4.2.1)
What could be causing those strange artitacts that appears on the later screenshot?
It apears as if the triangles on the back are overlapping those of the front
It occurs some times thought, as the artifats are jerky, it's like if there is "z-fighting", but triangles on the back have z values below of those for triangles on the front
Here is an image of the vertices and normals z arrangement
The blue arrows are normals shared by the surrounding faces, and the triangle with red lines is a representation of what could be causing those artifacts

it's like if there is "z-fighting", but triangles on the back have z values below of those for triangles on the front
It doesn't matter so much that one has z-value less than the other, you get z-fighting when your objects are too close together and you don't have enough z resolution.
The problem here I guess is that you set your projection range too large, from 0.1 to 1000. The greater magnitude the difference between these numbers, the less z-resolution you will get.
I recommend to try near/far of 0.1/100, or 1.0/1000, as long as that works with your application. It should help your z-fighting issue.

Related

OpenGL ES triangles drawing mistake on iOS

I try to draw multiple triangles using OpenGL ES and iOS. I create vertices array with float values with following structure
{x, y, z, r, g, b, a}
for each vertex. Final array for one triangle is:
{x1, y1, z1, r1, g1, b1, a1, x2, y2, z2, r2, g2, b2, a2, x3, y3, z3,
r3, g3, b3, a3}
Here is my update method:
-(void)update {
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 1.0, 100.0);
self.effect.transform.projectionMatrix = projectionMatrix;
}
and render:
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
[self drawShapes]; // here I fill vertices array
glClearColor(0.65f, 0.65f, 0.8f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int numItems = 3 * trianglesCount;
glBindVertexArrayOES(vao);
[self.effect prepareToDraw];
glUseProgram(shaderProgram);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * itemSize, convertedVerts, GL_DYNAMIC_DRAW);
glVertexAttribPointer(vertexPositionAttribute, 3, GL_FLOAT, false, stride, 0);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(vertexColorAttribute, 4, GL_FLOAT, false, stride, (GLvoid*)(3 * sizeof(float)));
glEnableVertexAttribArray(GLKVertexAttribColor);
glDrawArrays(GL_TRIANGLES, 0, numItems);
}
Context setup. Here I bind my vertex array and generate vertex buffer:
-(void)setupContext
{
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if(!self.context) {
NSLog(#"Failed to create OpenGL ES Context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[EAGLContext setCurrentContext:self.context];
self.effect = [[GLKBaseEffect alloc] init];
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glGenVertexArraysOES(1, &vao);
glBindVertexArrayOES(vao);
glGenBuffers(1, &vbo);
}
Fragment and vertex shaders are pretty simple:
//fragment
varying lowp vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
//vertex
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
varying lowp vec4 vColor;
void main(void) {
gl_Position = vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}
Result. Triangles aren't shown:
Where is mistake? I guess problem is with projection matrix. Here is github link to Xcode project.
Downloaded your code and tried it out. I see the purplish screen and no triangles, so I'm guessing that's the problem. I see two things that could be the problem:
1) You'll need to pass glBufferData the total number of bytes you're sending it, like this: glBufferData(GL_ARRAY_BUFFER, sizeof(float) * itemSize * numItems, convertedVerts, GL_DYNAMIC_DRAW);. Any data related to how to chunk the data stays glVertexAttribPointer.
2) That doesn't seem to be the only thing since I still can't get triangles to show up. I've never used GLKit before (I just have a little experience with OpenGL on the desktop platform). That being said, if I replace GLKVertexAttributePosition and GLKVertexAttribColor with 0 and 1 respectively. And apply the glBufferData fix from 1 I see artifacts flashing on the simulator screen when I move the mouse. So there's gotta be something fishy with those enum values and glVertexAttribPointer.
Edit - clarification for 2:
After changing the glBufferData line as described in 1. I also modified the glEnableVertexAttribArray lines so the looked like this:
glVertexAttribPointer(vertexPositionAttribute, 3, GL_FLOAT, false, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(vertexColorAttribute, 4, GL_FLOAT, false, stride, (GLvoid*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
After both of those changes I can see red triangles flickering on the screen. A step closer, since I couldn't see anything before. But I haven't been able to figure it out any further than that :(

Particle trails OpenGL 3.3, glClear?

I'm an OpenGL newbie. I'm trying to create a system of particles and I have everything set up, but the particle trails.
The easiest way, that I see, for me to implement this is to clear the screen with a nearly transparent colour e.g alpha = 0.05. This will fade the previous positions drawn.
However, this doesn't work. I've also tried to draw a rectangle over the screen.
After setting alpha of my particles to 0.3, my transparency doesn't seem to be working.
This is my code:
do{
glBindVertexArray(VertexArrayID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
time = (float)glfwGetTime();
// ** Calculating new positions and placing into vertex array
iter = 0;
for(int i = 0; i < n; i++){
bodies[i].F(bodies, i, n, 1);
bodies[i].calcPosition(dt);
bodies[i].getVertexArray(vertexArray, iter, scale, i);
}
for(int i = 0; i < n; i++){
bodies[i].F(bodies, i, n, 2);
bodies[i].calcVelocity(dt);
}
// **
glBufferData(GL_ARRAY_BUFFER, 21 * 6 * n * sizeof(float), vertexArray, GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 20 * 3 * n * sizeof(GLuint), elements, GL_STREAM_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
6*sizeof(float),
(void*)0
);
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
4,
GL_FLOAT,
GL_FALSE,
6*sizeof(float),
(void*)(2*sizeof(float))
);
glDrawElements(GL_TRIANGLES, 20 * 3 * n, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers();
while((float)glfwGetTime() - time < dt){
}
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
glfwGetWindowParam( GLFW_OPENED ) );
My shaders:
#version 330 core
in vec4 Color;
out vec4 outColor;
void main()
{
outColor = Color;
}
#version 330 core
layout(location = 0) in vec2 position;
layout(location = 1) in vec4 color;
out vec4 Color;
void main(){
gl_Position = vec4(position, 0.0, 1.0);
Color = color;
}
This outputs n circles (20 sided polygons) travelling round the screen in different colours. All previous drawings stay on the screen, I want them to fade
Thanks
Andy
The easiest way, that I see, for me to implement this is to clear the screen with a nearly transparent colour e.g alpha = 0.05. This will fade the previous positions drawn.
That is not going to work in a double-buffered window (and you don't want a single buffered one). The contents of the back buffer are undefined after SwapBuffer. If you really, really lucky, you might get some of the older image contents (but not the last one, as this is the front buffer now).
To solve this issue, you have to render to a texture, so you can redraw the previous contents (with your fadeout), add the new particle positions (still rendering into a texture for the next frame), and finally render or blit that texture to the real framebuffer. So you need at least two additional textures in a ping-pong fashion.

GLKBaseEffect not loading texture (texture appears black on object)

I'm using GLKit in an OpenGL project. Everything is based on GLKView and GLKBaseEffect (no custom shaders). In my project I have several views that have GLKViews for showing 3D objects, and occasionally several of those view can be "open" at once (i.e. are in the modal view stack).
While until now everything was working great, in a new view I was creating I needed to have a rectangle with texture to simulate a measuring tape for the 3D world of my app. For some unknown reason, in that view only, the texture isn't loaded right into the opengl context: the texture is loaded right by GLKTextureLoader, but when drawing the rectangle is black, and looking at the OpenGL frame in debug, I can see that an empty texture is loaded (there's a reference to a texture, but it's all zeroed out or null).
The shape I'm drawing is defined by: (it was originally a triangle strip, but I switched for triangles to make sure it's not the issue)
static const GLfloat initTape[] = {
-TAPE_WIDTH / 2.0f, 0, 0,
TAPE_WIDTH / 2.0f, 0, 0,
-TAPE_WIDTH / 2.0f, TAPE_INIT_LENGTH, 0,
TAPE_WIDTH / 2.0f, 0, 0,
TAPE_WIDTH / 2.0f, TAPE_INIT_LENGTH, 0,
-TAPE_WIDTH / 2.0f, TAPE_INIT_LENGTH, 0,
};
static const GLfloat initTapeTex[] = {
0, 0,
1, 0,
0, 1.0,
1, 0,
1, 1,
0, 1,
};
I set the effect variable as:
effect.transform.modelviewMatrix = modelview;
effect.light0.enabled = GL_FALSE;
// Projection setup
GLfloat ratio = self.view.bounds.size.width/self.view.bounds.size.height;
GLKMatrix4 projection = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(self.fov), ratio, 0.1f, 1000.0f);
effect.transform.projectionMatrix = projection;
// Set the color of the wireframe.
if (tapeTex == nil) {
NSError* error;
tapeTex = [GLKTextureLoader textureWithContentsOfFile:[[[NSBundle mainBundle] URLForResource:#"ruler_texture" withExtension:#"png"] path] options:nil error:&error];
}
effect.texture2d0.enabled = GL_TRUE;
effect.texture2d0.target = GLKTextureTarget2D;
effect.texture2d0.envMode = GLKTextureEnvModeReplace;
effect.texture2d0.name = tapeTex.name;
And the rendering loop is:
[effect prepareToDraw];
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribPosition, COORDS, GL_FLOAT, GL_FALSE, 0, tapeVerts);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, tapeTexCoord);
glDrawArrays(GL_TRIANGLES, 0, TAPE_VERTS);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
I've also tested the texture itself in another view with other objects and it works fine, so it's not the texture file fault.
Any help would be greatly appreciated, as I'm stuck on this issue for over 3 days.
Update: Also, there are no glErrors during the rendering loop.
After many many days I've finally found my mistake - When using multiple openGL contexts, it's important to create a GLKTextureLoader using a shareGroup, or else the textures aren't necessarily loaded to the right context.
Instead of using the class method textureWithContentOf, every context needs it's own GLKTextureLoader that is initialized with context.sharegroup, and use only that texture loader for that view. (actually the textures can be saved between different contexts, but I didn't needed that feature of sharegroups).
Easy tutorial http://games.ianterrell.com/how-to-texturize-objects-with-glkit/
I think it will help you.

How do I draw thousands of squares with glkit, opengl es2?

I'm trying to draw up to 200,000 squares on the screen. Or a lot of squares basically. I believe I'm just calling way to many draw calls, and it's crippling the performance of the app. The squares only update when I press a button, so I don't necessarily have to update this every frame.
Here's the code i have now:
- (void)glkViewControllerUpdate:(GLKViewController *)controller
{
//static float transY = 0.0f;
//float y = sinf(transY)/2.0f;
//transY += 0.175f;
GLKMatrix4 modelview = GLKMatrix4MakeTranslation(0, 0, -5.f);
effect.transform.modelviewMatrix = modelview;
//GLfloat ratio = self.view.bounds.size.width/self.view.bounds.size.height;
GLKMatrix4 projection = GLKMatrix4MakeOrtho(0, 768, 1024, 0, 0.1f, 20.0f);
effect.transform.projectionMatrix = projection;
_isOpenGLViewReady = YES;
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
if(_model.updateView && _isOpenGLViewReady)
{
glClear(GL_COLOR_BUFFER_BIT);
[effect prepareToDraw];
int pixelSize = _model.pixelSize;
if(!_model.isReady)
return;
//NSLog(#"UPDATING: %d, %d", _model.rows, _model.columns);
for(int i = 0; i < _model.rows; i++)
{
for(int ii = 0; ii < _model.columns; ii++)
{
ColorModel *color = [_model getColorAtRow:i andColumn:ii];
CGRect rect = CGRectMake(ii * pixelSize, i*pixelSize, pixelSize, pixelSize);
//[self drawRectWithRect:rect withColor:c];
GLubyte squareColors[] = {
color.red, color.green, color.blue, 255,
color.red, color.green, color.blue, 255,
color.red, color.green, color.blue, 255,
color.red, color.green, color.blue, 255
};
// NSLog(#"Drawing color with red: %d", color.red);
int xVal = rect.origin.x;
int yVal = rect.origin.y;
int width = rect.size.width;
int height = rect.size.height;
GLfloat squareVertices[] = {
xVal, yVal, 1,
xVal + width, yVal, 1,
xVal, yVal + height, 1,
xVal + width, yVal + height, 1
};
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, squareVertices);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, squareColors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribColor);
}
}
_model.updateView = YES;
}
First, do you really need to draw 200,000 squares? Your viewport only has 786,000 pixels total. You might be able to reduce the number of drawn objects without significantly impacting the overall quality of your scene.
That said, if these are smaller squares, you could draw them as points with a pixel size large enough to cover your square's area. That would require setting gl_PointSize in your vertex shader to the appropriate pixel width. You could then generate your coordinates and send them all to be drawn at once as GL_POINTS. That should remove the overhead of the extra geometry of the triangles and the individual draw calls you are using here.
Even if you don't use points, it's still a good idea to calculate all of the triangle geometry you need first, then send all that in a single draw call. This will significantly reduce your OpenGL ES API call overhead.
One other thing you could look into would be to use vertex buffer objects to store this geometry. If the geometry is static, you can avoid sending it on each drawn frame, or only update a part of it that has changed. Even if you just change out the data each frame, I believe using a VBO for dynamic geometry has performance advantages on the modern iOS devices.
Can you not try to optimize it somehow? I'm not terribly familiar with graphics type stuff, but I'd imagine that if you are drawing 200,000 squares chances that all of them are actually visible seems to be unlikely. Could you not add some sort of isVisible tag for your mySquare class that determines whether or not the square you want to draw is actually visible? Then the obvious next step is to modify your draw function so that if the square isn't visible, you don't draw it.
Or are you asking for someone to try to improve the current code you have, because if your performance is as bad as you say, I don't think making small changes to the above code will solve your problem. You'll have to rethink how you're doing your drawing.
It looks like what your code is actually trying to do is take a _model.rows × _model.columns 2D image and draw it upscaled by _model.pixelSize. If -[ColorModel getColorAtRow:andColumn:] is retrieving 3 bytes at a time from an array of color values, then you may want to consider uploading that array of color values into an OpenGL texture as GL_RGB/GL_UNSIGNED_BYTE data and letting the GPU scale up all of your pixels at once.
Alternatively, if scaling up the contents of your ColorModel is the only reason that you’re using OpenGL ES and GLKit, you might be better off wrapping your color values into a CGImage and allowing UIKit and Core Animation do the drawing for you. How often do the color values in the ColorModel get updated?

GLImageProcessing ROI (Region of Interest)

I am currently trying to blur a part of an image. I use apple's example code here
The example code itself can blur whole image and draw it to the EAGLView, what I want to do is blur only part of the image by supplying an ROI.
I do not know how to supply an ROI to the function.
Here is the code which draws image to the view;
void drawGL(int wide, int high, float val, int mode)
{
static int prevmode = -1;
typedef void (*procfunc)(V2fT2f *, float);
typedef struct {
procfunc func;
procfunc degen;
} Filter;
const Filter filter[] = {
{ brightness },
{ contrast },
{ extrapolate, greyscale },
{ hue },
{ extrapolate, blur }, // The blur could be exaggerated by downsampling to half size
};
#define NUM_FILTERS (sizeof(filter)/sizeof(filter[0]))
rt_assert(mode < NUM_FILTERS);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, wide, 0, high, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(wide, high, 1);
glBindTexture(GL_TEXTURE_2D, Input.texID);
if (prevmode != mode)
{
prevmode = mode;
if (filter[mode].degen)
{
// Cache degenerate image, potentially a different size than the system framebuffer
glBindFramebufferOES(GL_FRAMEBUFFER_OES, DegenFBO);
glViewport(0, 0, Degen.wide*Degen.s, Degen.high*Degen.t);
// The entire framebuffer won't be written to if the image was padded to POT.
// In this case, clearing is a performance win on TBDR systems.
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_BLEND);
filter[mode].degen(fullquad, 1.0);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
}
}
// Render filtered image to system framebuffer
glViewport(0, 0, wide, high);
filter[mode].func(flipquad, val);
glCheckError();
}
And this is the function which blurs the image;
static void blur(V2fT2f *quad, float t) // t = 1
{
GLint tex;
V2fT2f tmpquad[4];
float offw = t / Input.wide;
float offh = t / Input.high;
int i;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);
// Three pass small blur, using rotated pattern to sample 17 texels:
//
// .\/..
// ./\\/
// \/X/\ rotated samples filter across texel corners
// /\\/.
// ../\.
// Pass one: center nearest sample
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f(1.0/5, 1.0/5, 1.0/5, 1.0);
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Pass two: accumulate two rotated linear samples
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
for (i = 0; i < 4; i++)
{
tmpquad[i].x = quad[i].s + 1.5 * offw;
tmpquad[i].y = quad[i].t + 0.5 * offh;
tmpquad[i].s = quad[i].s - 1.5 * offw;
tmpquad[i].t = quad[i].t - 0.5 * offh;
}
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].x);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].s);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, tex);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
glColor4f(0.5, 0.5, 0.5, 2.0/5);
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Pass three: accumulate two rotated linear samples
for (i = 0; i < 4; i++)
{
tmpquad[i].x = quad[i].s - 0.5 * offw;
tmpquad[i].y = quad[i].t + 1.5 * offh;
tmpquad[i].s = quad[i].s + 0.5 * offw;
tmpquad[i].t = quad[i].t - 1.5 * offh;
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Restore state
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Half.texID);
glDisable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glDisable(GL_BLEND);
}
Where should I supply an ROI or if any other way is possible to blur a part of an image without ROI, I would like to know as well.
Thanks.
Im not a big OpenGL ES knower, but this code operate with whole (not ROI) textures on surface.
I using this example too.
I think, you should:
cut ROI of your image
create new texture with this image
blur whole new texture
set new texture over your original texture
Also few links:
How to implement a box or gaussian blur on iPhone, Blur Effect (Wet in Wet effect) in Paint Application Using OpenGL-ES,
how to sharp/blur an uiimage in iphone?
Have you tried glScissor() yet?
from the GLES1.1 spec:
glScissor defines a rectangle, called the scissor box, in window
coordinates. The first two arguments, x and y, specify the lower left
corner of the box. width and height specify the width and height of
the box.
To enable and disable the scissor test, call glEnable and glDisable
with argument GL_SCISSOR_TEST. The scissor test is initially disabled.
While scissor test is enabled, only pixels that lie within the scissor
box can be modified by drawing commands. Window coordinates have
integer values at the shared corners of frame buffer pixels.
glScissor(0, 0, 1, 1) allows modification of only the lower left pixel
in the window,and glScissor(0, 0, 0, 0) doesn't allow modification of
any pixels in the window.
You might have to do 2 draw passes; first the unfiltered image; the second is the filtered image but drawn with the scissor test.

Resources