ios - OpenGL 2.0 Bug - Setup and shaders work, won't draw -


i've got uiview loads opengl. setup works fine (you can test 'erase' call different colors) , shaders compiled without error.

the shaders basic: vertex shader takes position, fragment shader renders black.

however, won't draw. i've picked apart problem hours , can't find bug.

please help.

#pragma mark imports #import "ochrdrawingview.h"  #pragma mark - definitions #define loquacious yes   typedef struct {     glfloat x;     glfloat y; } vertex;  typedef vertex vector;  typedef struct {     glfloat r;     glfloat g;     glfloat b;     glfloat a; } color;   #pragma mark - inline functions static inline glfloat distancebetweenvertices (vertex one, vertex two) {     return sqrtf((two.x - one.x) * (two.x - one.x) + (two.y - one.y) * (two.y - one.y)); }  static inline glfloat magnitudeofvector (vector vec) {     return sqrtf(vec.x * vec.x + vec.y * vec.y); }  static inline glfloat dotproductofvectors(vector one, vector two) {     return (one.x *two.x + one.y * two.y); }  static inline glfloat crossproductofvectors (vector one, vector two) {     return (one.x * two.y - one.y * two.x); }  static inline vector vectorfromvertices (vertex one, vertex two) {     return (vector) { two.x - one.x, two.y - one.y }; }    #pragma mark - variables , implementation @implementation ochrdrawingview {     eaglcontext *context;     caeagllayer *eagllayer;      // buffers     gluint renderbuffer;     gluint framebuffer;     gluint vertexbufferid;      // attributes in shader program     gluint positionattribute;     gluint colorattribute;      gluint shaderprogram;      // pixel dimensions of backbuffer     glint backingwidth;     glint backingheight;      // bools     bool isfirsttouch;      // points drawing     cgpoint origin;     cgpoint control;     cgpoint destination; }  @synthesize currentcolor;  #pragma mark - opengl setup  + (class) layerclass {     return [caeagllayer class]; }  - (void) setuplayer {     if (loquacious) nslog(@"setuplayer called in ochrdrawingview");     eagllayer = (caeagllayer *) self.layer;     [eagllayer setopaque:yes];     [eagllayer setdrawableproperties:[nsdictionary dictionarywithobjectsandkeys:[nsnumber numberwithbool:yes],     keagldrawablepropertyretainedbacking, keaglcolorformatrgba8, keagldrawablepropertycolorformat, nil]];     }      - (void) setupcontext {     if (loquacious) nslog(@"setupcontext called in ochrdrawingview");     context = [[eaglcontext alloc] initwithapi:keaglrenderingapiopengles2];     [eaglcontext setcurrentcontext:context];     if (!context) {         nslog(@"context failed set properly");     } }  - (void) setuprenderbuffer {     if (loquacious) nslog(@"setuprenderbuffer called in ochrdrawingview");     glgenrenderbuffers(1, &renderbuffer);     glbindrenderbuffer(gl_renderbuffer, renderbuffer);     [context renderbufferstorage:gl_renderbuffer fromdrawable:eagllayer]; }  - (void) setupframebuffer {     if (loquacious) nslog(@"setupframebuffer called in ochrdrawingview");     glgenframebuffers(1, &framebuffer);     glbindframebuffer(gl_framebuffer, framebuffer);     glframebufferrenderbuffer(gl_framebuffer, gl_color_attachment0, gl_renderbuffer, renderbuffer); }  - (void) setupviewport {     if (loquacious) nslog(@"setupviewport called in ochrdrawingview");     glgetrenderbufferparameteriv(gl_renderbuffer, gl_renderbuffer_width, &backingwidth); glgetrenderbufferparameteriv(gl_renderbuffer, gl_renderbuffer_height, &backingheight);     glviewport(0, 0, backingwidth, backingheight);  }  - (void) setupvertexbuffer {     glgenbuffers(1, &vertexbufferid); }  #pragma mark - shaders  - (gluint)compileshaderoftype:(glenum)shadertype {      nsstring *shaderstring;      nsstring *vertexstring =     @" attribute vec4 position; "     @" void main (void) { "     @"      gl_position = position; "     @"      gl_pointsize = 16.0; "     @" } ";      nsstring *fragmentstring =     @" void main (void) { "     @"      gl_fragcolor = vec4(0.0, 0.0, 0.0, 1.0); "     @" } " ;      if (shadertype == gl_vertex_shader) {         shaderstring = vertexstring;         if (loquacious) nslog(@"about compile vertex shader");     } else if (shadertype == gl_fragment_shader) {         shaderstring = fragmentstring;         if (loquacious) nslog(@"about compile fragment shader");     } else {         nslog(@"not valid shader type");     }      gluint shaderhandle = glcreateshader(shadertype);      const char *shaderstringutf8 = [shaderstring utf8string];     int shaderstringlength = [shaderstring length];     glshadersource(shaderhandle, 1, &shaderstringutf8, &shaderstringlength);      glcompileshader(shaderhandle);      glint compilesuccess;     glgetshaderiv(shaderhandle, gl_compile_status, &compilesuccess);     if (compilesuccess == gl_false) {         glchar messages[256];         glgetshaderinfolog(shaderhandle, sizeof(messages), 0, &messages[0]);         nsstring *messagestring = [nsstring stringwithutf8string:messages];         nslog(@"%@", messagestring);         exit(1);     }     return shaderhandle; }  - (void)compileshaders {      if (loquacious) nslog(@"compileshaders called in ochrdrawingview");     gluint vertexshader = [self compileshaderoftype:gl_vertex_shader];     gluint fragmentshader = [self compileshaderoftype:gl_fragment_shader];      shaderprogram = glcreateprogram();     glattachshader(shaderprogram, vertexshader);     glattachshader(shaderprogram, fragmentshader);     gllinkprogram(shaderprogram);      glint linksuccess;     glgetprogramiv(shaderprogram, gl_link_status, &linksuccess);     if (linksuccess == gl_false) {         glchar messages[256];         glgetprograminfolog(shaderprogram, sizeof(messages), 0, &messages[0]);         nsstring *messagestring = [nsstring stringwithutf8string:messages];         nslog(@"%@", messagestring);         exit(1);     }      gluseprogram(shaderprogram);      positionattribute = glgetattriblocation(shaderprogram, "position");     glenablevertexattribarray(positionattribute); }  #pragma mark - init call  - (id)initwithframe:(cgrect)frame {     self = [super initwithframe:frame];     if (self) {         if (loquacious) nslog(@"ochrdrawingview initialize.");         [self setuplayer];         [self setupcontext];         [self setcontentscalefactor:[[uiscreen mainscreen] scale]];         [self setuprenderbuffer];         [self setupframebuffer];         [self setupvertexbuffer];         [self compileshaders];         [self erase];     }     return self; }  // erases screen - (void)erase {     if (loquacious) nslog(@"erase called in ochrdrawingview.");     [eaglcontext setcurrentcontext:context];      // clear buffer     glbindframebuffer(gl_framebuffer, framebuffer);     glclearcolor(1.0, 1.0, 1.0, 1.0);     glclear(gl_color_buffer_bit);      // display buffer     glbindrenderbuffer(gl_renderbuffer, renderbuffer);     [context presentrenderbuffer:gl_renderbuffer]; }   #pragma mark - touch response  - (void) touchesbegan:(nsset *)touches withevent:(uievent *)event {     origin = [[touches anyobject] locationinview:self];     origin.y = self.bounds.size.height - origin.y;     isfirsttouch = yes; }  - (void) touchesmoved:(nsset *)touches withevent:(uievent *)event {     if (isfirsttouch) {         isfirsttouch = no;         destination = [[touches anyobject] locationinview:self];         destination.y = self.bounds.size.height - destination.y;     } else {         origin = destination;         destination = [[touches anyobject] locationinview:self];         destination.y = self.bounds.size.height - destination.y;     }      [self renderlinefrompoint:origin topoint:destination]; }  // handles end of touch event when touch tap. - (void) touchesended:(nsset *)touches withevent:(uievent *)event {     if (isfirsttouch) {         destination = [[touches anyobject] locationinview:self];         destination.y = self.bounds.size.height - destination.y;         [self renderlinefrompoint:origin topoint:destination];     } }  - (void) touchescancelled:(nsset *)touches withevent:(uievent *)event {  }  #pragma mark - drawing algorithm  // drawings line onscreen based on user touches - (void)renderlinefrompoint:(cgpoint)start topoint:(cgpoint)end {     static glfloat *vertexbuffer = null;     static nsuinteger vertexmax = 64;     nsuinteger vertexcount = 0;     nsuinteger count;     nsuinteger i;      [eaglcontext setcurrentcontext:context];     glbindframebuffer(gl_framebuffer, framebuffer);      // convert locations points pixels     cgfloat scale = self.contentscalefactor;     start.x *= scale;     start.y *= scale;     end.x *= scale;     end.y *= scale;      // allocate vertex array buffer     if (vertexbuffer == null) vertexbuffer = malloc(vertexmax * 2 * sizeof(glfloat));      // add points buffer there drawing points every x pixels     count = max(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / 3), 1);      (i = 0; < count; ++i) {         if (vertexcount == vertexmax) {             vertexmax = 2 * vertexmax;             vertexbuffer = realloc(vertexbuffer, vertexmax * 2 * sizeof(glfloat));         }          vertexbuffer[2 * vertexcount + 0] = start.x + (end.x - start.x) * ((glfloat) / (glfloat) count);         vertexbuffer[2 * vertexcount + 1] = start.y + (end.y - start.y) * ((glfloat) / (glfloat) count);         vertexcount++;     }      // load data vertex buffer object     glbindbuffer(gl_array_buffer, vertexbufferid);     glbufferdata(gl_array_buffer, vertexcount * 2 * sizeof(glfloat), vertexbuffer, gl_dynamic_draw);      glenablevertexattribarray(positionattribute);     glvertexattribpointer(positionattribute, 2, gl_float, gl_false, 0, 0);      // draw     gluseprogram(shaderprogram);     gldrawarrays(gl_points, 0, vertexcount);      // display buffer     glbindrenderbuffer(gl_renderbuffer, renderbuffer);     [context presentrenderbuffer:gl_renderbuffer]; }   @end 

it seems me points drawn outside viewport. opengl uses normalised device coordinates in range [-1..1] both x , y.

you're taking position of touch in screen space different. e.g. ipad [0..1024] , [0..768]. in order draw points have convert them screen space ndc space:

ndc_x = 2*(touch_x/screen_size_x) - 1; ndc_y = 2*(touch_y/screen_size_y) - 1; 

Comments

Popular posts from this blog

css - Which browser returns the correct result for getBoundingClientRect of an SVG element? -

gcc - Calling fftR4() in c from assembly -

Function that returns a formatted array in VBA -