Drawing to the alpha channel of the frame buffer on with OpenGL while ignoring RGB values? - iphone

The opaque property is set to NO on my OpenGL view's CAEAGLLayer. There is a UIImageView behind the OpenGL view (the checkboard). A texture is drawn initially on the OpenGL view (the Emu bird photo). Now I want to draw another texture in the middle of the fame buffer. The new texture is completely black in color and the alpha changes from 0 to 255, from top to bottom.
This is my 2nd texture...
This is what I want...
This is what I get...
The checkboard texture is an UIImage in a UIImageView behind the EAGLView.
I do not want to disturb the RGB values in the frame buffer, I only want to write into the Alpha channel. I tried...
glDisable(GL_BLEND) and glColorMask(0, 0, 0, 1)
glEnable(GL_BLEND) and glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO)
Nothing seems to work. The RGB values are always modified, the pixels become brighter.
If source RGBA is (r2, g2, b2, a2) and destination is (r1, g1, b1, a1). I want the final value to be (r1, g1, b1, a2) or preferably (r1, g1, b1, some_function_of(a1, a2)). How do I achieve this?
Here is my code...
Objective C code for drawing the second texture...
- (void) drawTexture {
GLfloat textureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
static const GLfloat imageVertices[] = {
-0.5f, -0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
0.5f, 0.5f,
};
[EAGLContext setCurrentContext:context];
glViewport(0, 0, backingWidth, backingHeight);
glUseProgram(program);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texture);
glEnable (GL_BLEND);
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO);
glUniform1i(inputImageTexture, 2);
glVertexAttribPointer(position, 2, GL_FLOAT, 0, 0, imageVertices);
glVertexAttribPointer(inputTextureCoordinate, 2, GL_FLOAT, 0, 0, textureCoordinates);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
}
Vertex shader...
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
Fragment shader...
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
}

glColorMask must work - it worked for me in my case. Also, as far as I know glBlendFuncSeparate works buggy on iOS.
(In theory) you can do the following:
set blending to multiply mode (GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA)
make your texture white
set glColorMask to all channels enabled
If you have iDevice with iOS 5+ you can look at framebuffer alpha in OpenGL Capture window in XCode.

Related

OpenGL ES 2.0 on iOS non-square texture gets distorted when rendered

I am working on OpenGL ES 2.0 on iOS and I have this...
A texture (T1) with some image (size 1024x768).
An off screen FBO (FBO1) associated texture T1 so that I can render something into T1.
Another texture (T2) of the same size.
Another FBO (FBO2) associated with T2. (I will render to texture T2 with it).
Now in a loop, I render the content of T1 into FBO2 (so T1 gets transferred to T2) and then render T2 into FBO1 (T2 gets transferred back into T1).
After couple of iterations (just 7-8), the original image which was loaded to T1 gets severely distorted/blurred (as if it did a horizontal blur).
But if I do the same thing with a square image (need not be power of two), the image remains clear.
Here is the code that I use to create the texture..
GLuint texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
And here is the code I use to create the FBO...
glGenFramebuffers(1, &targetFBO);
glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
My shaders are the most basic ones, just renders the texture into gl_FragColor.
Here is my render Objective-C code...
- (void) draw {
GLfloat textureCoordinates[] = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
};
GLfloat imageVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
glViewport(0, 0, targetWidth, targetHeight);
glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
glUseProgram(program);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, textureID);
glUniform1i(inputTextureLocation, 2);
glDisable(GL_BLEND);
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, 0, 0, imageVertices);
glVertexAttribPointer(inputTextureCoordinateLocation, 2, GL_FLOAT, 0, 0, textureCoordinates);
// Clear the screen
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
And my vertex shader...
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
Fragment shader...
varying highp vec2 textureCoordinate;
uniform sampler2D inputTexture;
void main()
{
gl_FragColor = texture2D(inputTexture, textureCoordinate);
}
Original image...
Distorted image ...
How do I avoid blurring on non-square textures?
Edit: The problem is actually with No-Power-of-Two textures. Not just non-square. I am not able to find a solution, so I am going with POT textures.

Why my iPhone OpenGL-ES texture does not cover the viewport?

I have a square image of size 320x320, from which I create an OpenGL texture. I use the most basic Vertext and Fragment shaders and I want to display the texture in the entire view. The view (EAGLView derived from UIView as found in many OpenGL iOS samples) is also of size 320x320.
The problem is, the image is drawn on the top left corner, covering only around 50% of the entire view. It does not cover 100% of the view. I don't know why?
Here is my code:
position = glGetAttribLocation(m_shaderProgram, "position");
inputTextureCoordinate = glGetAttribLocation(m_shaderProgram, "inputTextureCoordinate");
inputImageTexture = glGetUniformLocation(m_shaderProgram, "inputImageTexture");
static const GLfloat textureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
static const GLfloat imageVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
[EAGLContext setCurrentContext:context];
glViewport(0, 0, backingWidth, backingHeight); // These are 320, 320
glUseProgram(m_shaderProgram);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, sourceTextureID); // The texture is also of size 320x320
glUniform1i(inputImageTexture, 2);
glVertexAttribPointer(position, 2, GL_FLOAT, 0, 0, imageVertices);
glVertexAttribPointer(textureCoordinate, 2, GL_FLOAT, 0, 0, textureCoordinates);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
Vertext Shader.
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
Fragment Shader.
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
}
So the problem is that the texture's dimensions were not 2's power. So we need to scale the textureCoordinates accordingly. Inserting following lines solved the problem...
GLfloat textureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
float nearest2sPower = 2;
if (nearest2sPower < backingWidth) {
while (nearest2sPower < backingWidth) {
nearest2sPower *= 2;
}
}
verticalFlipTextureCoordinates[2] = backingWidth/nearest2sPower;
verticalFlipTextureCoordinates[6] = backingWidth/nearest2sPower;
nearest2sPower = 2;
if (nearest2sPower < backingWidth) {
while (nearest2sPower < backingWidth) {
nearest2sPower *= 2;
}
}
verticalFlipTextureCoordinates[1] = backingHeight/nearest2sPower;
verticalFlipTextureCoordinates[3] = backingHeight/nearest2sPower;

OpenGL ES How to Correctly Combine Orthof and Frustum

I am beginning to learn OpenGL ES 1.1 for iPhone and would like to draw a 2D image in orthographic projection behind a few 3D objects. Using Jeff Lamarche's tutorials and the book Pro OpenGL ES for iPhone and I've come up with the following couple methods to attempt to do this. If I disable the call to drawSunInRect the 3D objects are rendered just fine and I can move them with touch controls etc. If I uncomment that call and try to draw the sun image, the image appears in the CGRect I supply, but I cannot see any of my other 3D objects - the rest of the screen is black. I've tried to disable/enable depth testing in various places, pass different parameters to glOrthof(), and move around the rectangle but I keep getting the sun image only when the drawSunInRect method is called. I'm assuming it is covering my 3D objects.
// Draw Sun in Rect and with Depth
- (void)drawSunInRect:(CGRect)rect withDepth:(float)depth {
// Get screen bounds
CGRect frame = [[UIScreen mainScreen] bounds];
// Calculate vertices from passed CGRect and depth
GLfloat vertices[] =
{
rect.origin.x, rect.origin.y, depth,
rect.origin.x + rect.size.width , rect.origin.y, depth,
rect.origin.x, rect.size.height+rect.origin.y , depth,
rect.origin.x + rect.size.width , rect.size.height+rect.origin.y ,depth
};
// Map the texture coords - no repeating
static GLfloat textureCoords[] =
{
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0
};
// Disable DEPTH test and setup Ortho
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrthof(0,frame.size.width,frame.size.height,0,0.1f,1000.0);
// Enable blending and configure
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
// Enable VERTEX and TEXTURE client states
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Enable Textures
glEnable(GL_TEXTURE_2D);
// Projection Matrix Mode for ortho and reset
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// No lighting or Depth Mask for 2D - no Culling
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glDisableClientState(GL_COLOR_ARRAY);
// Define ortho
glOrthof(0,frame.size.width,frame.size.height,0,0.1f,1000);
// From Jeff Lamarche Tutorials
// glOrthof(-1.0, // Left
// 1.0, // Right
// -1.0 / (rect.size.width / rect.size.height), // Bottom
// 1.0 / (rect.size.width / rect.size.height), // Top
// 0.01, // Near
// 10000.0); // Far
// Setup Model View Matrix
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// Bind and draw the Texture
glBindTexture(GL_TEXTURE_2D,sunInt);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT,0,textureCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// Re-enable lighting
glEnable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDepthMask(GL_TRUE);
}
// Override the draw in rect function
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
// Initialize and init the rotation stuff for the object
// Identity Matrix
glLoadIdentity();
static GLfloat rot = 0.0;
// Clear any remnants in the drawing buffers
// and fill the background with black
glClearColor(0.0f,0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Render the Sun - 2D Sun Image in CGRect
//[self drawSunInRect:CGRectMake(100, 100, 50, 50) withDepth:-30.0]; // 2D Sun Image
// Render the BattleCruiser - 3D Battlecruiser
[self renderTheBattleCruiser];
// Calculate a time interval to use to rotate the cruiser lives
static NSTimeInterval lastDrawTime;
if (lastDrawTime)
{
NSTimeInterval timeSinceLastDraw = [NSDate timeIntervalSinceReferenceDate] - lastDrawTime;
rot += 75 * timeSinceLastDraw;
}
lastDrawTime = [NSDate timeIntervalSinceReferenceDate];
}
UPDATE
I modified the draw sun method to have only 1 push and 1 pop for the GL_PROJECTION. I am still having the same issue. The sun image appears but I cannot see my 3D Objects. I have tried to re-arrange the calls to the render methods so the 3D objects are rendered first but I get the same results. I would appreciate other ideas on how to see my orthographic texture and 3D objects together.
// Draw Sun in Rect and with Depth
- (void)drawSunInRect:(CGRect)rect withDepth:(float)depth {
// Get screen bounds
CGRect frame = [[UIScreen mainScreen] bounds];
// Calculate vertices from passed CGRect and depth
GLfloat vertices[] =
{
rect.origin.x, rect.origin.y, depth,
rect.origin.x + rect.size.width , rect.origin.y, depth,
rect.origin.x, rect.size.height+rect.origin.y , depth,
rect.origin.x + rect.size.width , rect.size.height+rect.origin.y ,depth
};
// Map the texture coords - no repeating
static GLfloat textureCoords[] =
{
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0
};
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisableClientState(GL_COLOR_ARRAY);
glOrthof(0,frame.size.width,frame.size.height,0,0,1000);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor4f(1,1,1,1);
glBindTexture(GL_TEXTURE_2D,sunInt);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT,0,textureCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glEnable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
I realized I was calling setClipping only once in my viewController viewDidLoad. I moved it to my glkView method and now I get my Sun image and my 3d object.

Draw a line on top of triangles

I created a new iPhone OpenGL Project in Xcode. I filled my background with triangles and gave them a texture, see below:
CGImageRef spriteImage;
CGContextRef spriteContext;
GLubyte *spriteData;
size_t width, height;
// Sets up matrices and transforms for OpenGL ES
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glRotatef(-90,0,0,1);
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
// Clears the view with black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Sets up pointers and enables states needed for using vertex arrays and textures
glVertexPointer(2, GL_FLOAT, 0, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
//glColorPointer(4, GL_FLOAT, 0, triangleColors);
//glColor4f(0.0f,1.0f,0.0f,1.0f);
//glEnableClientState(GL_COLOR_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, spriteTexcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Creates a Core Graphics image from an image file
spriteImage = [UIImage imageNamed:#"Bild.png"].CGImage;
// Get the width and height of the image
width = CGImageGetWidth(spriteImage);
height = CGImageGetHeight(spriteImage);
// Texture dimensions must be a power of 2. If you write an application that allows users to supply an image,
// you'll want to add code that checks the dimensions and takes appropriate action if they are not a power of 2.
if(spriteImage) {
// Allocated memory needed for the bitmap context
spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
// Uses the bitmap creation function provided by the Core Graphics framework.
spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
// After you create the context, you can draw the sprite image to the context.
CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage);
// You don't need the context at this point, so you need to release it to avoid memory leaks.
CGContextRelease(spriteContext);
// Use OpenGL ES to generate a name for the texture.
glGenTextures(1, &spriteTexture);
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, spriteTexture);
// Set the texture parameters to use a minifying filter and a linear filer (weighted average)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Specify a 2D texture image, providing the a pointer to the image data in memory
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
// Release the image data
free(spriteData);
// Enable use of the texture
glEnable(GL_TEXTURE_2D);
// Set a blending function to use
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Enable blending
glEnable(GL_BLEND);
I have got two questions, bc. I am not so familiar with OpenGL.
I want to write a method, which I give two points as parameters and I want a Line between these two points to be drawn above my triangles (background).
- (void) drawLineFromPoint1:(CGPoint)point1 toPoint2:(CGPoint)point2 {
GLfloat triangle[] = { //Just example points
0.0f, 0.0f,
0.1f, 0.0f,
0.1f, 0.0f,
0.1f, 0.1f
};
GLfloat triangleColors[] = {
0.5f, 0.5f, 0.5f, 1.0f
};
//now draw the triangle
}
Something like that. Now I want to have a 2nd method, which erases this line (and not the background)
My drawing method looks like this:
- (void)drawView
{
// Make sure that you are drawing to the current context
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, number_vertices, GL_UNSIGNED_SHORT, indices);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Would be great if you can give e some hints/help,
cheers
The conventional approach would be to redraw everything whenever you move or erase a line.
Well, I got it to work. I just missed to set the Vertex-Pointer in my drawView to my triangles. This here now works:
- (void)drawView
{
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, number_vertices, GL_UNSIGNED_SHORT, indices);
[self drawLines];
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (void) drawLines{
glDisable(GL_TEXTURE_2D);
GLfloat points[4];
for (Dataset *data in buttons) {
CGPoint s = [data screenPosition];
CGPoint p = [data slot];
points[0] = (GLfloat)(768-s.y);
points[1] = (GLfloat)(1024-s.x);
points[2] = (GLfloat)(768-p.y);
points[3] = (GLfloat)(1024-p.x);
glVertexPointer(2, GL_FLOAT, 0, points);
glDrawArrays(GL_LINE_STRIP, 0, 2);
}
glEnable(GL_TEXTURE_2D);
}

Draw Square with OpenGL ES for iOS

I am trying to draw a rectangle using the GLPaint example project provided by apple. I have tried modifying the vertices but cannot get a rectangle to appear on the screen. The finger painting works perfectly. Am I missing something in my renderRect method?
- (void)renderRect {
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
// Replace the implementation of this method to do your own custom drawing.
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f,
};
static float transY = 0.0f;
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Display the buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
The rest of the project is set up stock to allow drawing on the screen but just for reference these are the gl settings that are set.
// Set the view's scale factor
self.contentScaleFactor = 1.0;
// Setup OpenGL states
glMatrixMode(GL_PROJECTION);
CGRect frame = self.bounds;
CGFloat scale = self.contentScaleFactor;
// Setup the view port in Pixels
glOrthof(0, frame.size.width * scale, 0, frame.size.height * scale, -1, 1);
glViewport(0, 0, frame.size.width * scale, frame.size.height * scale);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DITHER);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_BLEND);
// Set a blending function appropriate for premultiplied alpha pixel data
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SPRITE_OES);
glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
glPointSize(width / brushScale);
static const GLfloat squareVertices[] = {
30.0f, 300.0f,//-0.5f, -0.33f,
280.0f, 300.0f,//0.5f, -0.33f,
30.0f, 170.0f,//-0.5f, 0.33f,
280.0f, 170.0f,//0.5f, 0.33f,
};
That's definitely too much. OpenGL has normalized screen coords in range [-1..1]. So you have to convert device coords to normalized ones.
Issues are:
(1) the following code:
glMatrixMode(GL_PROJECTION);
CGRect frame = self.bounds;
CGFloat scale = self.contentScaleFactor;
// Setup the view port in Pixels
glOrthof(0, frame.size.width * scale, 0, frame.size.height * scale, -1, 1);
glViewport(0, 0, frame.size.width * scale, frame.size.height * scale);
Establishes that the on-screen coordinates range from (0, 0) in the lower left to frame.size in the upper right. In other words, one OpenGL unit is one iPhone point. So your array of:
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f,
};
Is less than 1 pixel in size.
(2) you have the following in the setup:
brushImage = [UIImage imageNamed:#"Particle.png"].CGImage;
/* ...brushImage eventually becomes the current texture... */
glEnable(GL_TEXTURE_2D);
You subsequently fail to supply texture coordinates for your quad. Probably you want to disable GL_TEXTURE_2D.
So the following:
static const GLfloat squareVertices[] = {
0.0f, 0.0f,
0.0, 10.0f,
90.0, 0.0f,
90.0f, 10.0f,
};
glDisable(GL_TEXTURE_2D);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Will produce a white quad 90 points wide and 10 points tlal in the lower left of the screen.