/** * Zeichnet einen Vertex (glVertex) mit Texturkoordinaten und gegebenfalls Farbinformationen aber ohne Normale. */ void SGLVektor::DrawVertex() { /* Setzt wenn gegeben Texturkoordinaten für alle Texturrenderer vom der aktiven bis zu GL_TEXTURE0_ARB herunter. (Aber immer nur die Selben) */ std::stringstream buff; bool texOK=false; #ifndef WIN32 if(SGLTextur::TexLoaded) { short coord=texKoord.size(); if(coord<SGLTextur::TexLoaded) { buff << *this; SGLprintWarning("Die geladene Textur hat %d Dimensionen, die Texturkoordinaten des Vertex \"%s\" sind aber nur %d-Dimensional",SGLTextur::TexLoaded,buff.str().c_str(),coord); } int i=GL_TEXTURE0_ARB+SGLTextur::multitex_layer ;//@todo dirty Hack switch(SGLTextur::TexLoaded > coord ? coord:SGLTextur::TexLoaded ) { case 1: for(;i>=GL_TEXTURE0_ARB;i--) glMultiTexCoord1f(i,texKoord[0]); break; case 2: for(;i>=GL_TEXTURE0_ARB;i--) glMultiTexCoord2f(i,texKoord[0], texKoord[1]); break; case 3: for(;i>=GL_TEXTURE0_ARB;i--) glMultiTexCoord3f(i,texKoord[0], texKoord[1],texKoord[2]); break; default:{ buff << *this; SGLprintError("Texturtyp (%d) passt nicht zu den verfügbaren Texturkoordinaten beim Zeichnen des Vertex \"%s\"",SGLTextur::TexLoaded, coord,buff.str().c_str());}break; } texOK=true;//@todo naja nich immer } #else // "Texture loading is currently not supportet for Windows" #endif if(!SGLMaterial::MatLoaded && !texOK) { if(SGLV_R>=0 || SGLV_G>=0 || SGLV_B>=0)glColor3dv(Color); else{ buff << *this; SGLprintWarning("Keine Farbinformationen verfgbar beim Zeichnen des Vertex \"%s\"",buff.str().c_str()); } } DrawPureVertex(); }
void GlSplatRenderer::drawpoints() { glColor4dv(mColor); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); glMultiTexCoord1f(GL_TEXTURE2, mRadius); glNormalPointer(GL_FLOAT, sizeof(GLVertex), (void*)offsetof(GLVertex, nx)); glVertexPointer(3, GL_FLOAT, sizeof(GLVertex), (void*)offsetof(GLVertex, x)); glDrawArrays(GL_POINTS, 0, VertexCount); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL13_nglMultiTexCoord1f(JNIEnv *env, jclass clazz, jint target, jfloat s, jlong function_pointer) { glMultiTexCoord1fPROC glMultiTexCoord1f = (glMultiTexCoord1fPROC)((intptr_t)function_pointer); glMultiTexCoord1f(target, s); }
int shDrawRadialGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max, VGPaintMode mode, GLenum texUnit) { SHint i, j; float a, n; SHfloat cx = p->radialGradient[0]; SHfloat cy = p->radialGradient[1]; SHfloat fx = p->radialGradient[2]; SHfloat fy = p->radialGradient[3]; float r = p->radialGradient[4]; float fcx, fcy, rr, C; SHVector2 ux; SHVector2 uy; SHVector2 c, f; SHVector2 cf; SHMatrix3x3 *m; SHMatrix3x3 mi; SHint invertible; SHVector2 corners[4]; SHVector2 fcorners[4]; SHfloat minOffset=0.0f; SHfloat maxOffset=0.0f; SHint maxI=0, maxJ=0; SHfloat maxA=0.0f; SHfloat startA=0.0f; int numsteps = 100; float step = 2*PI/numsteps; SHVector2 tmin, tmax; SHVector2 min1, max1, min2, max2; /* Pick paint transform matrix */ SH_GETCONTEXT(0); if (mode == VG_FILL_PATH) m = &context->fillTransform; else if (mode == VG_STROKE_PATH) m = &context->strokeTransform; /* Move focus into circle if outside */ SET2(cf, fx,fy); SUB2(cf, cx,cy); n = NORM2(cf); if (n > r) { DIV2(cf, n); fx = cx + 0.995f * r * cf.x; fy = cy + 0.995f * r * cf.y; } /* Precalculations */ rr = r*r; fcx = fx - cx; fcy = fy - cy; C = fcx*fcx + fcy*fcy - rr; /* Apply paint-to-user transformation to focus and unit vectors */ SET2(f, fx, fy); SET2(c, cx, cy); SET2(ux, 1, 0); SET2(uy, 0, 1); ADD2(ux, cx, cy); ADD2(uy, cx, cy); TRANSFORM2(f, (*m)); TRANSFORM2(c, (*m)); TRANSFORM2(ux, (*m)); TRANSFORM2(uy, (*m)); SUB2V(ux, c); SUB2V(uy, c); /* Boundbox corners */ SET2(corners[0], min->x, min->y); SET2(corners[1], max->x, min->y); SET2(corners[2], max->x, max->y); SET2(corners[3], min->x, max->y); /* Find inverse transformation (back to paint space) */ invertible = shInvertMatrix(m, &mi); if (!invertible || r <= 0.0f) { /* Fill boundbox with color at offset 1 */ SHColor *c = &p->stops.items[p->stops.size-1].color; glColor4fv((GLfloat*)c); glBegin(GL_QUADS); for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]); glEnd(); return 1; } /*--------------------------------------------------------*/ /* Find min/max offset */ for (i=0; i<4; ++i) { /* Transform to paint space */ SHfloat ax,ay, A,B,D,t, off; TRANSFORM2TO(corners[i], mi, fcorners[i]); SUB2(fcorners[i], fx, fy); n = NORM2(fcorners[i]); if (n == 0.0f) { /* Avoid zero-length vectors */ off = 0.0f; }else{ /* Distance from focus to circle at corner angle */ DIV2(fcorners[i], n); ax = fcorners[i].x; ay = fcorners[i].y; A = ax*ax + ay*ay; B = 2 * (fcx*ax + fcy*ay); D = B*B - 4*A*C; t = (-B + SH_SQRT(D)) / (2*A); /* Relative offset of boundbox corner */ if (D <= 0.0f) off = 1.0f; else off = n / t; } /* Find smallest and largest offset */ if (off < minOffset || i==0) minOffset = off; if (off > maxOffset || i==0) maxOffset = off; } /* Is transformed focus inside original boundbox? */ if (f.x >= min->x && f.x <= max->x && f.y >= min->y && f.y <= max->y) { /* Draw whole circle */ minOffset = 0.0f; startA = 0.0f; maxA = 2*PI; }else{ /* Find most distant corner pair */ for (i=0; i<3; ++i) { if (ISZERO2(fcorners[i])) continue; for (j=i+1; j<4; ++j) { if (ISZERO2(fcorners[j])) continue; a = ANGLE2N(fcorners[i], fcorners[j]); if (a > maxA || maxA == 0.0f) {maxA=a; maxI=i; maxJ=j;} }} /* Pick starting angle */ if (CROSS2(fcorners[maxI],fcorners[maxJ]) > 0.0f) startA = shVectorOrientation(&fcorners[maxI]); else startA = shVectorOrientation(&fcorners[maxJ]); } /*---------------------------------------------------------*/ /* TODO: for minOffset we'd actually need to find minimum of the gradient function when X and Y are substitued with a line equation for each bound-box edge. As a workaround we use 0.0f for now. */ minOffset = 0.0f; step = PI/50; numsteps = (SHint)SH_CEIL(maxA / step) + 1; glActiveTexture(texUnit); shSetGradientTexGLState(p); glEnable(GL_TEXTURE_1D); glBegin(GL_QUADS); /* Walk the steps and draw gradient mesh */ for (i=0, a=startA; i<numsteps; ++i, a+=step) { /* Distance from focus to circle border at current angle (gradient space) */ float ax = SH_COS(a); float ay = SH_SIN(a); float A = ax*ax + ay*ay; float B = 2 * (fcx*ax + fcy*ay); float D = B*B - 4*A*C; float t = (-B + SH_SQRT(D)) / (2*A); if (D <= 0.0f) t = 0.0f; /* Vectors pointing towards minimum and maximum offset at current angle (gradient space) */ tmin.x = ax * t * minOffset; tmin.y = ay * t * minOffset; tmax.x = ax * t * maxOffset; tmax.y = ay * t * maxOffset; /* Transform back to user space */ min2.x = f.x + tmin.x * ux.x + tmin.y * uy.x; min2.y = f.y + tmin.x * ux.y + tmin.y * uy.y; max2.x = f.x + tmax.x * ux.x + tmax.y * uy.x; max2.y = f.y + tmax.x * ux.y + tmax.y * uy.y; /* Draw quad */ if (i!=0) { glMultiTexCoord1f(texUnit, minOffset); glVertex2fv((GLfloat*)&min1); glVertex2fv((GLfloat*)&min2); glMultiTexCoord1f(texUnit, maxOffset); glVertex2fv((GLfloat*)&max2); glVertex2fv((GLfloat*)&max1); } /* Save prev points */ min1 = min2; max1 = max2; } glEnd(); glDisable(GL_TEXTURE_1D); return 1; }
int shDrawLinearGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max, VGPaintMode mode, GLenum texUnit) { SHint i; SHfloat n; SHfloat x1 = p->linearGradient[0]; SHfloat y1 = p->linearGradient[1]; SHfloat x2 = p->linearGradient[2]; SHfloat y2 = p->linearGradient[3]; SHVector2 c, ux, uy; SHVector2 cc, uux, uuy; SHMatrix3x3 *m; SHMatrix3x3 mi; SHint invertible; SHVector2 corners[4]; SHfloat minOffset = 0.0f; SHfloat maxOffset = 0.0f; SHfloat left = 0.0f; SHfloat right = 0.0f; SHVector2 l1,r1,l2,r2; /* Pick paint transform matrix */ SH_GETCONTEXT(0); if (mode == VG_FILL_PATH) m = &context->fillTransform; else if (mode == VG_STROKE_PATH) m = &context->strokeTransform; /* Gradient center and unit vectors */ SET2(c, x1, y1); SET2(ux, x2-x1, y2-y1); SET2(uy, -ux.y, ux.x); n = NORM2(ux); DIV2(ux, n); NORMALIZE2(uy); /* Apply paint-to-user transformation */ ADD2V(ux, c); ADD2V(uy, c); TRANSFORM2TO(c, (*m), cc); TRANSFORM2TO(ux, (*m), uux); TRANSFORM2TO(uy, (*m), uuy); SUB2V(ux,c); SUB2V(uy,c); SUB2V(uux,cc); SUB2V(uuy,cc); /* Boundbox corners */ SET2(corners[0], min->x, min->y); SET2(corners[1], max->x, min->y); SET2(corners[2], max->x, max->y); SET2(corners[3], min->x, max->y); /* Find inverse transformation (back to paint space) */ invertible = shInvertMatrix(m, &mi); if (!invertible || n==0.0f) { /* Fill boundbox with color at offset 1 */ SHColor *c = &p->stops.items[p->stops.size-1].color; glColor4fv((GLfloat*)c); glBegin(GL_QUADS); for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]); glEnd(); return 1; } /*--------------------------------------------------------*/ for (i=0; i<4; ++i) { /* Find min/max offset and perpendicular span */ SHfloat o, s; TRANSFORM2(corners[i], mi); SUB2V(corners[i], c); o = DOT2(corners[i], ux) / n; s = DOT2(corners[i], uy); if (o < minOffset || i==0) minOffset = o; if (o > maxOffset || i==0) maxOffset = o; if (s < left || i==0) left = s; if (s > right || i==0) right = s; } /*---------------------------------------------------------*/ /* Corners of boundbox in gradient system */ SET2V(l1, cc); SET2V(r1, cc); SET2V(l2, cc); SET2V(r2, cc); OFFSET2V(l1, uuy, left); OFFSET2V(l1, uux, minOffset * n); OFFSET2V(r1, uuy, right); OFFSET2V(r1, uux, minOffset * n); OFFSET2V(l2, uuy, left); OFFSET2V(l2, uux, maxOffset * n); OFFSET2V(r2, uuy, right); OFFSET2V(r2, uux, maxOffset * n); /* Draw quad using color-ramp texture */ glActiveTexture(texUnit); shSetGradientTexGLState(p); glEnable(GL_TEXTURE_1D); glBegin(GL_QUAD_STRIP); glMultiTexCoord1f(texUnit, minOffset); glVertex2fv((GLfloat*)&r1); glVertex2fv((GLfloat*)&l1); glMultiTexCoord1f(texUnit, maxOffset); glVertex2fv((GLfloat*)&r2); glVertex2fv((GLfloat*)&l2); glEnd(); glDisable(GL_TEXTURE_1D); return 1; }
PsychError SCREENDrawDots(void) { PsychWindowRecordType *windowRecord, *parentWindowRecord; int m,n,p,mc,nc,idot_type; int i, nrpoints, nrsize; psych_bool isArgThere, usecolorvector, isdoublecolors, isuint8colors; double *xy, *size, *center, *dot_type, *colors; float *sizef; unsigned char *bytecolors; GLfloat pointsizerange[2]; psych_bool lenient = FALSE; psych_bool usePointSizeArray = FALSE; static psych_bool nocando = FALSE; int oldverbosity; // All sub functions should have these two lines PsychPushHelp(useString, synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; // Check for superfluous arguments PsychErrorExit(PsychCapNumInputArgs(7)); //The maximum number of inputs PsychErrorExit(PsychCapNumOutputArgs(4)); //The maximum number of outputs // Get the window record from the window record argument and get info from the window record PsychAllocInWindowRecordArg(1, kPsychArgRequired, &windowRecord); // Get dot_type argument, if any, as it is already needed for a pure point size range query below: isArgThere = PsychIsArgPresent(PsychArgIn, 6); if(!isArgThere){ idot_type = 0; } else { PsychAllocInDoubleMatArg(6, TRUE, &m, &n, &p, &dot_type); if(p != 1 || n != 1 || m != 1 || (dot_type[0] < 0 || dot_type[0] > 4)) PsychErrorExitMsg(PsychError_user, "dot_type must be 0, 1, 2, 3 or 4"); idot_type = (int) dot_type[0]; } // Query for supported point size range? if (PsychGetNumOutputArgs() > 0) { PsychSetDrawingTarget(windowRecord); // Always query and return aliased range: glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, (GLfloat*) &pointsizerange); PsychCopyOutDoubleArg(3, FALSE, (double) pointsizerange[0]); PsychCopyOutDoubleArg(4, FALSE, (double) pointsizerange[1]); // If driver supports smooth points and usercode doesn't specify a dot type (idot_type 0) // or does not request shader + point-sprite based drawing then return smooth point // size range as "smooth point size range" - query and assign it. Otherwise, ie., code // explicitely wants to use a shader (idot_type >= 3) or has to use one, we will use // point-sprites and that means the GL_ALIASED_POINT_SIZE_RANGE limits apply also to // our shader based smooth dots, so return those: if ((windowRecord->gfxcaps & kPsychGfxCapSmoothPrimitives) && (idot_type < 3)) glGetFloatv(GL_POINT_SIZE_RANGE, (GLfloat*) &pointsizerange); // Whatever the final choice for smooth dots is, return its limits: PsychCopyOutDoubleArg(1, FALSE, (double) pointsizerange[0]); PsychCopyOutDoubleArg(2, FALSE, (double) pointsizerange[1]); // If this was only a query then we are done: if (PsychGetNumInputArgs() < 2) return(PsychError_none); } // Query, allocate and copy in all vectors... nrpoints = 2; nrsize = 0; colors = NULL; bytecolors = NULL; PsychPrepareRenderBatch(windowRecord, 2, &nrpoints, &xy, 4, &nc, &mc, &colors, &bytecolors, 3, &nrsize, &size, (GL_FLOAT == PsychGLFloatType(windowRecord))); isdoublecolors = (colors) ? TRUE:FALSE; isuint8colors = (bytecolors) ? TRUE:FALSE; usecolorvector = (nc>1) ? TRUE:FALSE; // Assign sizef as float-type array of sizes, if float mode active, NULL otherwise: sizef = (GL_FLOAT == PsychGLFloatType(windowRecord)) ? (float*) size : NULL; // Get center argument isArgThere = PsychIsArgPresent(PsychArgIn, 5); if(!isArgThere){ center = (double *) PsychMallocTemp(2 * sizeof(double)); center[0] = 0; center[1] = 0; } else { PsychAllocInDoubleMatArg(5, TRUE, &m, &n, &p, ¢er); if(p!=1 || n!=2 || m!=1) PsychErrorExitMsg(PsychError_user, "center must be a 1-by-2 vector"); } // Turn on antialiasing to draw circles? Or idot_type 4 for shader based square dots? if (idot_type) { // Smooth point rendering supported by gfx-driver and hardware? And user does not request our own stuff? if ((idot_type == 3) || (idot_type == 4) || !(windowRecord->gfxcaps & kPsychGfxCapSmoothPrimitives)) { // No. Need to roll our own shader + point sprite solution. if (!windowRecord->smoothPointShader && !nocando) { parentWindowRecord = PsychGetParentWindow(windowRecord); if (!parentWindowRecord->smoothPointShader) { // Build and assign shader to parent window, but allow this to silently fail: oldverbosity = PsychPrefStateGet_Verbosity(); PsychPrefStateSet_Verbosity(0); parentWindowRecord->smoothPointShader = PsychCreateGLSLProgram(PointSmoothFragmentShaderSrc, PointSmoothVertexShaderSrc, NULL); PsychPrefStateSet_Verbosity(oldverbosity); } if (parentWindowRecord->smoothPointShader) { // Got one compiled - assign it for use: windowRecord->smoothPointShader = parentWindowRecord->smoothPointShader; } else { // Failed. Record this failure so we can avoid retrying at next DrawDots invocation: nocando = TRUE; } } if (windowRecord->smoothPointShader) { // Activate point smooth shader, and point sprite operation on texunit 1 for coordinates on set 1: PsychSetShader(windowRecord, windowRecord->smoothPointShader); glActiveTexture(GL_TEXTURE1); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); glActiveTexture(GL_TEXTURE0); glEnable(GL_POINT_SPRITE); // Tell shader from where to get its color information: Unclamped high precision colors from texture coordinate set 0, or regular colors from vertex color attribute? glUniform1i(glGetUniformLocation(windowRecord->smoothPointShader, "useUnclampedFragColor"), (windowRecord->defaultDrawShader) ? 1 : 0); // Tell shader if it should shade smooth round dots, or square dots: glUniform1i(glGetUniformLocation(windowRecord->smoothPointShader, "drawRoundDots"), (idot_type != 4) ? 1 : 0); // Tell shader about current point size in pointSize uniform: glEnable(GL_PROGRAM_POINT_SIZE); usePointSizeArray = TRUE; } else if (idot_type != 4) { // Game over for round dot drawing: PsychErrorExitMsg(PsychError_user, "Point smoothing unsupported on your system and our shader based implementation failed as well in Screen('DrawDots')."); } else { // Type 4 requested but unsupported. Fallback to type 0, which is the same, just slower: idot_type = 0; } // Request square dots, without anti-aliasing: Better compatibility with // shader + point sprite operation, and needed for idot_type 0 fallback. glDisable(GL_POINT_SMOOTH); glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, (GLfloat*) &pointsizerange); } else { // User wants hw anti-aliased round smooth dots (idot_type = 1 or 2) and // hardware + driver support this. Request smooth points from hardware: glEnable(GL_POINT_SMOOTH); glGetFloatv(GL_POINT_SIZE_RANGE, (GLfloat*) &pointsizerange); // A dot type of 2 requests highest quality point smoothing: glHint(GL_POINT_SMOOTH_HINT, (idot_type > 1) ? GL_NICEST : GL_DONT_CARE); } } else { glDisable(GL_POINT_SMOOTH); glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, (GLfloat*) &pointsizerange); } // Does ES-GPU only support a fixed point diameter of 1 pixel? if ((pointsizerange[1] <= 1) && PsychIsGLES(windowRecord)) { // Yes. Not much point bailing on this, as it should be easily visible // during testing of a studies code on a OpenGL-ES device. lenient = TRUE; } // Accept optional 'lenient' flag, if provided: PsychCopyInFlagArg(7, FALSE, &lenient); // Set size of a single dot: if (!lenient && ((sizef && (sizef[0] > pointsizerange[1] || sizef[0] < pointsizerange[0])) || (!sizef && (size[0] > pointsizerange[1] || size[0] < pointsizerange[0])))) { printf("PTB-ERROR: You requested a point size of %f units, which is not in the range (%f to %f) supported by your graphics hardware.\n", (sizef) ? sizef[0] : size[0], pointsizerange[0], pointsizerange[1]); PsychErrorExitMsg(PsychError_user, "Unsupported point size requested in Screen('DrawDots')."); } // Setup initial common point size for all points: if (!usePointSizeArray) glPointSize((sizef) ? sizef[0] : (float) size[0]); if (usePointSizeArray) glMultiTexCoord1f(GL_TEXTURE2, (sizef) ? sizef[0] : (float) size[0]); // Setup modelview matrix to perform translation by 'center': glMatrixMode(GL_MODELVIEW); // Make a backup copy of the matrix: glPushMatrix(); // Apply a global translation of (center(x,y)) pixels to all following points: glTranslatef((float) center[0], (float) center[1], 0); // Render the array of 2D-Points - Efficient version: // This command sequence allows fast processing of whole arrays // of vertices (or points, in this case). It saves the call overhead // associated with the original implementation below and is potentially // optimized in specific OpenGL implementations. // Pass a pointer to the start of the point-coordinate array: glVertexPointer(2, PSYCHGLFLOAT, 0, &xy[0]); // Enable fast rendering of arrays: glEnableClientState(GL_VERTEX_ARRAY); if (usecolorvector) { PsychSetupVertexColorArrays(windowRecord, TRUE, mc, colors, bytecolors); } // Render all n points, starting at point 0, render them as POINTS: if ((nrsize == 1) || usePointSizeArray) { // Only one common size provided, or efficient shader based // path in use. We can use the fast path of only submitting // one glDrawArrays call to draw all GL_POINTS. For a single // common size, no further setup is needed. if (nrsize > 1) { // Individual size for each dot provided. Setup texture unit 2 // with a 1D texcoord array that stores per point size info in // texture coordinate set 2. But first validate point sizes: for (i = 0; i < nrpoints; i++) { if (!lenient && ((sizef && (sizef[i] > pointsizerange[1] || sizef[i] < pointsizerange[0])) || (!sizef && (size[i] > pointsizerange[1] || size[i] < pointsizerange[0])))) { printf("PTB-ERROR: You requested a point size of %f units, which is not in the range (%f to %f) supported by your graphics hardware.\n", (sizef) ? sizef[i] : size[i], pointsizerange[0], pointsizerange[1]); PsychErrorExitMsg(PsychError_user, "Unsupported point size requested in Screen('DrawDots')."); } } // Sizes are fine, setup texunit 2: glClientActiveTexture(GL_TEXTURE2); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(1, (sizef) ? GL_FLOAT : GL_DOUBLE, 0, (sizef) ? (const GLvoid*) sizef : (const GLvoid*) size); } // Draw all points: glDrawArrays(GL_POINTS, 0, nrpoints); if (nrsize > 1) { // Individual size for each dot provided. Reset texture unit 2: glTexCoordPointer(1, (sizef) ? GL_FLOAT : GL_DOUBLE, 0, (const GLvoid*) NULL); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Back to default texunit 0: glClientActiveTexture(GL_TEXTURE0); } } else { // Different size for each dot provided and we can't use our shader based implementation: // We have to do One GL - call per dot: for (i=0; i<nrpoints; i++) { if (!lenient && ((sizef && (sizef[i] > pointsizerange[1] || sizef[i] < pointsizerange[0])) || (!sizef && (size[i] > pointsizerange[1] || size[i] < pointsizerange[0])))) { printf("PTB-ERROR: You requested a point size of %f units, which is not in the range (%f to %f) supported by your graphics hardware.\n", (sizef) ? sizef[i] : size[i], pointsizerange[0], pointsizerange[1]); PsychErrorExitMsg(PsychError_user, "Unsupported point size requested in Screen('DrawDots')."); } // Setup point size for this point: if (!usePointSizeArray) glPointSize((sizef) ? sizef[i] : (float) size[i]); // Render point: glDrawArrays(GL_POINTS, i, 1); } } // Disable fast rendering of arrays: glDisableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, PSYCHGLFLOAT, 0, NULL); if (usecolorvector) PsychSetupVertexColorArrays(windowRecord, FALSE, 0, NULL, NULL); // Restore old matrix from backup copy, undoing the global translation: glPopMatrix(); // turn off antialiasing again if (idot_type) { glDisable(GL_POINT_SMOOTH); if (windowRecord->smoothPointShader) { // Deactivate point smooth shader and point sprite operation on texunit 1: PsychSetShader(windowRecord, 0); glActiveTexture(GL_TEXTURE1); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE); glActiveTexture(GL_TEXTURE0); glDisable(GL_POINT_SPRITE); glDisable(GL_PROGRAM_POINT_SIZE); } } // Reset pointsize to 1.0 glPointSize(1); // Mark end of drawing op. This is needed for single buffered drawing: PsychFlushGL(windowRecord); //All psychfunctions require this. return(PsychError_none); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL13_nglMultiTexCoord1f(JNIEnv *__env, jclass clazz, jint texture, jfloat s, jlong __functionAddress) { glMultiTexCoord1fPROC glMultiTexCoord1f = (glMultiTexCoord1fPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) glMultiTexCoord1f(texture, s); }
void GL_DrawAliasBlendedFrame(aliashdr_t *paliashdr, int pose1, int pose2, float blend, int shell, int cell) { //float l; trivertx_t* verts1; trivertx_t* verts2; int* order; int count; vec3_t colour, normal; //shell and new blending vec3_t iblendshell; vec3_t blendshell; float iblend; //cell shading vec3_t lightVector; lightVector[0] = 0; lightVector[1] = 0; lightVector[2] = 1; if (r_celshading.getBool() || r_vertexshading.getBool()) { //setup for shading glActiveTexture(GL_TEXTURE1_ARB); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_1D); if (r_celshading.getBool()) glBindTexture(GL_TEXTURE_1D, TextureManager::celtexture); else glBindTexture(GL_TEXTURE_1D, TextureManager::vertextexture); } lastposenum0 = pose1; lastposenum = pose2; verts1 = (trivertx_t *) ((byte *) paliashdr + paliashdr->posedata); verts2 = verts1; verts1 += pose1 * paliashdr->poseverts; verts2 += pose2 * paliashdr->poseverts; order = (int *) ((byte *) paliashdr + paliashdr->commands); //LH: shell blending iblend = 1.0 - blend; if (shell) { iblendshell[0] = iblend * 5; iblendshell[1] = iblend * 5; iblendshell[2] = iblend * 5; blendshell[0] = blend * 5; blendshell[1] = blend * 5; blendshell[2] = blend * 5; } for (;;) { // get the vertex count and primitive type count = *order++; if (!count) break; if (count < 0) { count = -count; glBegin(GL_TRIANGLE_FAN); } else { glBegin(GL_TRIANGLE_STRIP); } do { // normals and vertexes come from the frame list // blend the light intensity from the two frames together colour[0] = colour[1] = colour[2] = shadedots[verts1->lightnormalindex] * iblend + shadedots[verts2->lightnormalindex] * blend; colour[0] *= lightcolor[0]; colour[1] *= lightcolor[1]; colour[2] *= lightcolor[2]; //if (colour[0] > 1) colour[0] = 1; //if (colour[1] > 1) colour[1] = 1; //if (colour[2] > 1) colour[2] = 1; if ((!shell) && (!cell)) glColor3f(colour[0], colour[1], colour[2]); normal[0] = (r_avertexnormals[verts1->lightnormalindex][0] * iblend + r_avertexnormals[verts2->lightnormalindex][0] * blend); normal[1] = (r_avertexnormals[verts1->lightnormalindex][1] * iblend + r_avertexnormals[verts2->lightnormalindex][1] * blend); normal[2] = (r_avertexnormals[verts1->lightnormalindex][2] * iblend + r_avertexnormals[verts2->lightnormalindex][2] * blend); glNormal3fv(&normal[0]); // blend the vertex positions from each frame together if (!shell) { // texture coordinates come from the draw list glMultiTexCoord1f(GL_TEXTURE1_ARB, bound(0, DotProduct(shadevector, normal), 1)); glMultiTexCoord2f(GL_TEXTURE0_ARB, ((float *) order)[0], ((float *) order)[1]); glVertex3f(verts1->v[0] * iblend + verts2->v[0] * blend, verts1->v[1] * iblend + verts2->v[1] * blend, verts1->v[2] * iblend + verts2->v[2] * blend); } else { glTexCoord2f(((float *) order)[0] + realtime * 2, ((float *) order)[1] + realtime * 2); glVertex3f(verts1->v[0] * iblend + verts2->v[0] * blend + r_avertexnormals[verts1->lightnormalindex][0] * iblendshell[0] + r_avertexnormals[verts2->lightnormalindex][0] * blendshell[0], verts1->v[1] * iblend + verts2->v[1] * blend + r_avertexnormals[verts1->lightnormalindex][1] * iblendshell[1] + r_avertexnormals[verts2->lightnormalindex][1] * blendshell[1], verts1->v[2] * iblend + verts2->v[2] * blend + r_avertexnormals[verts1->lightnormalindex][2] * iblendshell[2] + r_avertexnormals[verts2->lightnormalindex][2] * blendshell[2]); } order += 2; verts1++; verts2++; } while (--count); glEnd(); } if (r_celshading.getBool() || r_vertexshading.getBool()) { //setup for shading glDisable(GL_TEXTURE_1D); glActiveTexture(GL_TEXTURE0_ARB); } }
void GL_DrawAliasFrame(aliashdr_t *paliashdr, int posenum, int shell, int cell) { float l; vec3_t colour, normal; trivertx_t *verts; int *order; int count; //cell shading vec3_t lightVector; lightVector[0] = 0; lightVector[1] = 0; lightVector[2] = 1; lastposenum = posenum; verts = (trivertx_t *) ((byte *) paliashdr + paliashdr->posedata); verts += posenum * paliashdr->poseverts; order = (int *) ((byte *) paliashdr + paliashdr->commands); if (r_celshading.getBool() || r_vertexshading.getBool()) { //setup for shading glActiveTexture(GL_TEXTURE1_ARB); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_1D); if (r_celshading.getBool()) glBindTexture(GL_TEXTURE_1D, TextureManager::celtexture); else glBindTexture(GL_TEXTURE_1D, TextureManager::vertextexture); } while (1) { // get the vertex count and primitive type count = *order++; if (!count) break; // done if (count < 0) { count = -count; glBegin(GL_TRIANGLE_FAN); } else glBegin(GL_TRIANGLE_STRIP); do { // normals and vertexes come from the frame list //qmb :alias coloured lighting l = shadedots[verts->lightnormalindex]; VectorScale(lightcolor, l, colour); //if (colour[0] > 1) colour[0] = 1; //if (colour[1] > 1) colour[1] = 1; //if (colour[2] > 1) colour[2] = 1; if ((!shell) && (!cell)) glColor3f(colour[0], colour[1], colour[2]); normal[0] = (r_avertexnormals[verts->lightnormalindex][0]); normal[1] = (r_avertexnormals[verts->lightnormalindex][1]); normal[2] = (r_avertexnormals[verts->lightnormalindex][2]); glNormal3fv(&r_avertexnormals[verts->lightnormalindex][0]); if (!shell) { // texture coordinates come from the draw list glMultiTexCoord1f(GL_TEXTURE1_ARB, bound(0, DotProduct(shadevector, normal), 1)); glMultiTexCoord2f(GL_TEXTURE0_ARB, ((float *) order)[0], ((float *) order)[1]); glVertex3f(verts->v[0], verts->v[1], verts->v[2]); } else { glTexCoord2f(((float *) order)[0] + realtime * 2, ((float *) order)[1] + realtime * 2); glVertex3f(r_avertexnormals[verts->lightnormalindex][0] * 5 + verts->v[0], r_avertexnormals[verts->lightnormalindex][1] * 5 + verts->v[1], r_avertexnormals[verts->lightnormalindex][2] * 5 + verts->v[2]); } order += 2; verts++; } while (--count); glEnd(); } if (r_celshading.getBool() || r_vertexshading.getBool()) { //setup for shading glDisable(GL_TEXTURE_1D); glActiveTexture(GL_TEXTURE0_ARB); } }