// cleans up anything the program was using void cleanUp(ShaderProgram *program) { glDisableVertexAttribArray(program->positionAttribute); glDisableVertexAttribArray(program->texCoordAttribute); SDL_Quit(); }
void drawLine(int x1, int y1, int x2, int y2) { int x, y; bool backwards = false; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 < 0) x2 = 0; if (y2 < 0) y2 = 0; if (x1 > sceneWidth) x1 = sceneWidth - 1; if (x2 > sceneWidth) x2 = sceneWidth - 1; if (y1 > sceneHeight) y1 = sceneHeight - 1; if (y2 > sceneHeight) y2 = sceneHeight - 1; if (x1 > x2) { x = x2; backwards = !backwards; } else x = x1; if (y1 > y2) { y = y2; backwards = !backwards; } else y = y1; int diffX = abs(x2-x1); int diffY = abs(y2-y1); if (! diffX) { diffX = 1; if (x == sceneWidth - 1) x = sceneWidth -2; } if (! diffY) { diffY = 1; if (y == sceneHeight - 1) y = sceneHeight -2; } setPixelCoords (true); glLineWidth (2.0); int xoffset = 0; while (xoffset < diffX) { int w = (diffX-xoffset < viewportWidth) ? diffX-xoffset : viewportWidth; int yoffset = 0; while (yoffset < diffY) { int h = (diffY-yoffset < viewportHeight) ? diffY-yoffset : viewportHeight; // Render the scene - first the old backdrop glBindTexture (GL_TEXTURE_2D, backdropTextureName); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLfloat vertices[] = { (GLfloat)-x-xoffset, (GLfloat)1-y-yoffset, 0., (GLfloat)sceneWidth-x-xoffset, (GLfloat)1-y-yoffset, 0., (GLfloat)-x-xoffset, (GLfloat)sceneHeight-y-yoffset, 0., (GLfloat)sceneWidth-x-xoffset, (GLfloat)sceneHeight-y-yoffset, 0. }; const GLfloat texCoords[] = { 0.0f, 0.0f, backdropTexW, 0.0f, 0.0f, backdropTexH, backdropTexW, backdropTexH }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, texCoords); // Then the line //FIXME:Removing the lines doesn't work, but also didn't work properly before. GLint xo1=-xoffset, xo2=-xoffset; if (! backwards) { xo2 += diffX; } else { xo1 += diffX; } const GLint lineVertices[] = { xo1, -yoffset, 0, xo2, -yoffset+diffY, 0, }; glUseProgram(shader.color); setPMVMatrix(shader.color); glUniform4f(glGetUniformLocation(shader.color, "myColor"), 0.0f, 0.0f, 0.0f, 1.0f); int vertexLoc = glGetAttribLocation(shader.color, "myVertex"); glEnableVertexAttribArray(vertexLoc); glVertexAttribPointer(vertexLoc, 3, GL_INT, GL_FALSE, 0, lineVertices); glDrawArrays(GL_LINES, 0, 2); glDisableVertexAttribArray(vertexLoc); glUseProgram(0); // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, x+xoffset, y+yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); }
void GLBitmapFont_drawString(void * selfPtr, const char * string, size_t length, float emHeight, float offsetX, float offsetY, float offsetZ) { GLBitmapFont * self = selfPtr; struct vertex_p4f_t2f * vertices; GLushort * indexes; size_t charIndex, kernCharIndex, printableCharCount = 0, vertexIndex = 0, indexIndex = 0; float positionX = 0.0f; unsigned int charEntryIndex; for (charIndex = 0; charIndex < length; charIndex++) { if (string[charIndex] >= GLBITMAPFONT_PRINTABLE_MIN && string[charIndex] <= GLBITMAPFONT_PRINTABLE_MAX) { printableCharCount++; } } vertices = malloc(sizeof(struct vertex_p4f_t2f) * 4 * printableCharCount); indexes = malloc(sizeof(GLushort) * 6 * printableCharCount); for (charIndex = 0; charIndex < length; charIndex++) { if (string[charIndex] >= GLBITMAPFONT_PRINTABLE_MIN && string[charIndex] <= GLBITMAPFONT_PRINTABLE_MAX) { charEntryIndex = string[charIndex] - GLBITMAPFONT_PRINTABLE_MIN; if (charIndex > 0) { for (kernCharIndex = 0; kernCharIndex < self->characters[charEntryIndex].kernCharCount; kernCharIndex++) { if (string[charIndex - 1] == self->characters[charEntryIndex].kernChars[kernCharIndex].previous) { positionX += self->characters[charEntryIndex].kernChars[kernCharIndex].offset; break; } } } vertices[vertexIndex].position[0] = offsetX + (positionX + self->characters[charEntryIndex].glyphOffset) * emHeight; vertices[vertexIndex].position[1] = offsetY + emHeight; vertices[vertexIndex].position[2] = offsetZ; vertices[vertexIndex].position[3] = 1.0f; vertices[vertexIndex].texCoords[0] = self->characters[charEntryIndex].textureLeft; vertices[vertexIndex].texCoords[1] = self->characters[charEntryIndex].textureTop; vertices[vertexIndex + 1].position[0] = offsetX + (positionX + self->characters[charEntryIndex].glyphOffset) * emHeight; vertices[vertexIndex + 1].position[1] = offsetY; vertices[vertexIndex + 1].position[2] = offsetZ; vertices[vertexIndex + 1].position[3] = 1.0f; vertices[vertexIndex + 1].texCoords[0] = self->characters[charEntryIndex].textureLeft; vertices[vertexIndex + 1].texCoords[1] = self->characters[charEntryIndex].textureBottom; vertices[vertexIndex + 2].position[0] = offsetX + (positionX + self->characters[charEntryIndex].glyphOffset + self->characters[charEntryIndex].glyphWidth) * emHeight; vertices[vertexIndex + 2].position[1] = offsetY; vertices[vertexIndex + 2].position[2] = offsetZ; vertices[vertexIndex + 2].position[3] = 1.0f; vertices[vertexIndex + 2].texCoords[0] = self->characters[charEntryIndex].textureRight; vertices[vertexIndex + 2].texCoords[1] = self->characters[charEntryIndex].textureBottom; vertices[vertexIndex + 3].position[0] = offsetX + (positionX + self->characters[charEntryIndex].glyphOffset + self->characters[charEntryIndex].glyphWidth) * emHeight; vertices[vertexIndex + 3].position[1] = offsetY + emHeight; vertices[vertexIndex + 3].position[2] = offsetZ; vertices[vertexIndex + 3].position[3] = 1.0f; vertices[vertexIndex + 3].texCoords[0] = self->characters[charEntryIndex].textureRight; vertices[vertexIndex + 3].texCoords[1] = self->characters[charEntryIndex].textureTop; indexes[indexIndex] = vertexIndex; indexes[indexIndex + 1] = vertexIndex + 1; indexes[indexIndex + 2] = vertexIndex + 2; indexes[indexIndex + 3] = vertexIndex + 2; indexes[indexIndex + 4] = vertexIndex + 3; indexes[indexIndex + 5] = vertexIndex; vertexIndex += 4; indexIndex += 6; positionX += self->characters[charEntryIndex].advance; } } if (GLGraphics_getOpenGLAPIVersion() == GL_API_VERSION_ES2) { glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(struct vertex_p4f_t2f), vertices[0].position); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex_p4f_t2f), vertices[0].texCoords); } else { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(4, GL_FLOAT, sizeof(struct vertex_p4f_t2f), vertices[0].position); glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex_p4f_t2f), vertices[0].texCoords); } self->texture->activate(self->texture); glDrawElements(GL_TRIANGLES, indexIndex, GL_UNSIGNED_SHORT, indexes); self->texture->deactivate(self->texture); if (GLGraphics_getOpenGLAPIVersion() == GL_API_VERSION_ES2) { glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); } else { glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } free(vertices); free(indexes); }
void GLBackend::do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset) { glDisableVertexAttribArray(batch._params[paramOffset]._uint); (void) CHECK_GL_ERROR(); }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_winSz[0], g_winSz[1]); //SwapBuffers( g_hDC ); //return; // // setup the block1 with base matrices // // g_transfBlock1.m4_Proj already done vec3 up(0,1,0); look_at(g_transfBlock1.m4_View, g_camera.curEyePos, g_camera.curFocusPos, up); //g_transfBlock1.m4_ViewIT = ...todo g_transfBlock1.m4_ViewProj = g_transfBlock1.m4_Proj * g_transfBlock1.m4_View; g_transfBlock1.eyePos = g_camera.curEyePos; // copy the block to OGL if(fx_transfBlock1) { void* p; fx_transfBlock1->mapBuffer(&p); memcpy(p, &g_transfBlock1, sizeof(transfBlock1)); fx_transfBlock1->unmapBuffer(); } //----------------------------------------------------------------- // // Render a basic floor // //glBeginQuery(GL_TIME_ELAPSED, timerQueries[tqOffset]); #define U 1.0f #define DU 0.1f struct Grid { Grid() { Elts = 0; for(float i=-U; i<=(U+DU); i+=DU) { vtx[Elts++] = vec3(-U, 0, i); vtx[Elts++] = vec3( U, 0, i); vtx[Elts++] = vec3(i, 0,-U); vtx[Elts++] = vec3(i, 0, U); } glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vec3)*(10*10+2), vtx[0].vec_array, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } int Elts; GLuint vbo; vec3 vtx[10*10+2]; }; static Grid sgrid; if(fx_TechFloor) { fx_pass = fx_TechFloor->getPass(0); fx_pass->execute(); } glEnableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glDisableVertexAttribArray(3); glDisableVertexAttribArray(4); glBindBuffer(GL_ARRAY_BUFFER, sgrid.vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glDrawArrays(GL_LINES, 0, sgrid.Elts); glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); if(fx_pass) fx_pass->unbindProgram(); fx_pass = NULL; //glEndQuery(GL_TIME_ELAPSED); // // Mesh rendering // //glBeginQuery(GL_TIME_ELAPSED, timerQueries[tqOffset+1]); if(!meshFile) { #ifdef NOGLUT SwapBuffers( g_hDC ); #else glutSwapBuffers(); #endif return; } // // default values for second block made of World... // mat4 m4_world1; g_transfBlock2.m4_World.identity(); g_transfBlock2.m4_WorldView = g_transfBlock1.m4_View * g_transfBlock2.m4_World; g_transfBlock2.m4_WorldViewProj = g_transfBlock1.m4_Proj * g_transfBlock2.m4_WorldView; mat4 WI; invert(WI, g_transfBlock2.m4_World); transpose(g_transfBlock2.m4_WorldIT, WI); if(fx_transfBlock2) { #ifdef USECSTBUFUNIFORMS // we use setXXX() for constant buffer's uniforms fx_m4_World->setMatrix4f(g_transfBlock2.m4_World.mat_array); fx_m4_WorldIT->setMatrix4f(g_transfBlock2.m4_WorldIT.mat_array); fx_m4_WorldView->setMatrix4f(g_transfBlock2.m4_WorldView.mat_array); fx_m4_WorldViewProj->setMatrix4f(g_transfBlock2.m4_WorldViewProj.mat_array); // we dont need this update call: the Pass::execute() will take care of it if not done //fx_transfBlock2->update(); no need #else void* p; fx_transfBlock2->mapBuffer(&p); memcpy(p, &g_transfBlock2, sizeof(transfBlock2)); fx_transfBlock2->unmapBuffer(); #endif } nvFX::PassInfo passInfo; // structure in which many things are returned by execute() if(fx_Tech) { fx_pass = fx_Tech->getPass(0); fx_pass->execute(&passInfo); } else { glClearColor(1.0,0,0,0.0); } for(int i=0; i< meshFile->pMeshes->n; i++) { bk3d::Mesh *pMesh = meshFile->pMeshes->p[i]; // case where the mesh references a transformation // the absolute value must be available by default // if more than one transf, skip it : this might be a list of skeleton transformations if(pMesh->pTransforms && pMesh->pTransforms->n == 1) { g_transfBlock2.m4_World = mat4(pMesh->pTransforms->p[0]->abs_matrix); g_transfBlock2.m4_WorldView = g_transfBlock1.m4_View * g_transfBlock2.m4_World; g_transfBlock2.m4_WorldViewProj = g_transfBlock1.m4_Proj * g_transfBlock2.m4_WorldView; mat4 WI; invert(WI, g_transfBlock2.m4_World); transpose(g_transfBlock2.m4_WorldIT, WI); if(fx_transfBlock2) { #ifdef USECSTBUFUNIFORMS fx_m4_World->setMatrix4f(g_transfBlock2.m4_World.mat_array); fx_m4_WorldIT->setMatrix4f(g_transfBlock2.m4_WorldIT.mat_array); fx_m4_WorldView->setMatrix4f(g_transfBlock2.m4_WorldView.mat_array); fx_m4_WorldViewProj->setMatrix4f(g_transfBlock2.m4_WorldViewProj.mat_array); // Because we are AFTER the Pass::execute(), we must make sure that the constant buffer // gets updated as soon as we changed all the uniforms we wanted to change fx_transfBlock2->update(); #else void* p; fx_transfBlock2->mapBuffer(&p); memcpy(p, &g_transfBlock2, sizeof(transfBlock2)); fx_transfBlock2->unmapBuffer(); #endif } } // // let's make it very simple : each mesh attribute is *supposed* to match // the attribute Id of the effect. In real, meshes might not always match // but this is totally arbitrary... // we assume the mesh got baked as follow: // 0: would be pos; 1: normal; 2: TC; 3 and 4: Tan Binorm // int j = 0; for(int k=0; k<pMesh->pSlots->n;k++) { bk3d::Slot* pSlot = pMesh->pSlots->p[k]; glBindBuffer(GL_ARRAY_BUFFER, pSlot->userData); // assign buffers for(int l=0; l<pSlot->pAttributes->n; l++) { glEnableVertexAttribArray(j); glVertexAttribPointer(j, pSlot->pAttributes->p[l].p->numComp, pSlot->pAttributes->p[l].p->formatGL, GL_FALSE, pSlot->pAttributes->p[l].p->strideBytes, (void*)pSlot->pAttributes->p[l].p->dataOffsetBytes); j++; } } glBindBuffer(GL_ARRAY_BUFFER, 0); int MaxAttr = 16; //glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &MaxAttr); for(; j<MaxAttr;j++) glDisableVertexAttribArray(j); for(int pg=0; pg<pMesh->pPrimGroups->n; pg++) { bk3d::PrimGroup* pPG = pMesh->pPrimGroups->p[pg]; //if( ( (pPG->topologyGL == GL_LINES) // ||(pPG->topologyGL == GL_LINE_LOOP) // ||(pPG->topologyGL == GL_LINE_STRIP))) //{ } // case where the Primitive group references a transformation // the absolute value must be available by default if(pPG->pTransforms && pPG->pTransforms->n > 0) { g_transfBlock2.m4_World = mat4(pPG->pTransforms->p[0]->abs_matrix); g_transfBlock2.m4_WorldView = g_transfBlock1.m4_View * g_transfBlock2.m4_World; g_transfBlock2.m4_WorldViewProj = g_transfBlock1.m4_Proj * g_transfBlock2.m4_WorldView; //g_transfBlock2.m4_WorldIT = ... todo; if(fx_transfBlock2) { #ifdef USECSTBUFUNIFORMS fx_m4_World->setMatrix4f(g_transfBlock2.m4_World.mat_array); fx_m4_WorldView->setMatrix4f(g_transfBlock2.m4_WorldView.mat_array); fx_m4_WorldViewProj->setMatrix4f(g_transfBlock2.m4_WorldViewProj.mat_array); // Because we are AFTER the Pass::execute(), we must make sure that the constant buffer // gets updated as soon as we changed all the uniforms we wanted to change fx_transfBlock2->update(); #else void* p; fx_transfBlock2->mapBuffer(&p); memcpy(p, &g_transfBlock2, sizeof(transfBlock2)); fx_transfBlock2->unmapBuffer(); #endif } } bk3d::Material *pMat = pPG->pMaterial; if(pMat && g_bUseMaterial && fx_materialBlock) { MaterialBlock* p; fx_materialBlock->mapBuffer((void**)&p); // small issue with original modell (has a black material by default...) if(pMat->diffuse[0]==0.0==pMat->diffuse[1]==pMat->diffuse[2]) pMat->diffuse[0]=pMat->diffuse[1]=pMat->diffuse[2]= 0.7f; // simply copy of the data as they are in the original model memory int sz = sizeof(MaterialBlock); memcpy(p, pMat->diffuse, sz); fx_materialBlock->unmapBuffer(); } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (long)pPG->userPtr); // arbitrarily stating that (passInfo.renderingGroup == 3) means we need to feed // the GPU with patches, instead of regular primitives // assuming here that we are dealing only with triangles if(pPG->topologyGL == GL_TRIANGLES) { if(passInfo.renderingGroup == 3) glPatchParameteri(GL_PATCH_VERTICES, 3); glDrawElements( (passInfo.renderingGroup == 3) ? GL_PATCHES : GL_TRIANGLES, pPG->indexCount, pPG->indexFormatGL, (void*)pPG->indexArrayByteOffset);// pIndexBufferData); } } } if(fx_pass) fx_pass->unbindProgram(); fx_pass = NULL; //glEndQuery(GL_TIME_ELAPSED); #ifdef NOGLUT SwapBuffers( g_hDC ); #else glutSwapBuffers(); #endif // // Timer Query results // //tqOffset = tqOffset ? 0 : 2; // alternate between 2 groups //if(tqStart) // special case of the first render // tqStart = false; //else //{ // int available = 0; // while (!available) // { // glGetQueryObjectiv(timerQueries[tqOffset+1], GL_QUERY_RESULT_AVAILABLE, &available); // } // GLuint64 timeElapsed; // for (int i = 0; i < 2; i++) // { // // See how much time the rendering of object i took in nanoseconds. // glGetQueryObjectui64v(timerQueries[tqOffset+i], GL_QUERY_RESULT, &timeElapsed); // } //} }
int GameWindow::DisableAttribArray(uint32_t Attrib) { glDisableVertexAttribArray(uniforms[Attrib]); return uniforms[Attrib]; }
void DisplayClass::createRedSquare(mat4 modelMatrix) { //these four points define where the quad would be BEFORE transformations //this is referred to as object-space and it's best to center geometry at the origin for easier transformations float* vertices = new float[16]; vertices[0] = -4.0f; vertices[1] = 4.0f; vertices[2] = -1.0f; vertices[3] = 1.0f; vertices[4] = -4.0f; vertices[5] = -4.0f; vertices[6] = -1.0f; vertices[7] = 1.0f; vertices[8] = 4.0f; vertices[9] = -4.0f; vertices[10] = -1.0f; vertices[11] = 1.0f; vertices[12] = 4.0f; vertices[13] = 4.0f; vertices[14] = -1.0f; vertices[15] = 1.0f; //now we put the data into the Vertex Buffer Object for the graphics system to use glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), vertices, GL_STATIC_DRAW); //the square vertices don't need to change, ever, //while the program runs //once the data is loaded, we can delete the float arrays, the data is safely stored with OpenGL //vertices is an array that we created under this scope and stored in the HEAP, so release it if we don't want to use it anymore. delete [] vertices; //again with colors float* colors = new float[12]; colors[0] = 1; colors[1] = 0; colors[2] = 0; colors[3] = 1; colors[4] = 0; colors[5] = 0; colors[6] = 1; colors[7] = 0; colors[8] = 0; colors[9] = 1; colors[10] = 0; colors[11] = 0; glBindBuffer(GL_ARRAY_BUFFER, cbo); //always make sure you are telling OpenGL the right size to make the buffer, color data doesn't have as much data! glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), colors, GL_STREAM_DRAW); //the color is going to change every frame //as it bounces between squares delete [] colors; //once more, this time with normals float* normals = new float[16]; normals[0] = 0; normals[1] = 0; normals[2] = 1; normals[3] = 0; normals[4] = 0; normals[5] = 0; normals[6] = 1; normals[7] = 0; normals[8] = 0; normals[9] = 0; normals[10] = 1; normals[11] = 0; normals[12] = 0; normals[13] = 0; normals[14] = 1; normals[15] = 0; glBindBuffer(GL_ARRAY_BUFFER, nbo); glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), normals, GL_STATIC_DRAW); //the square normals don't need to change, ever, //while the program runs delete [] normals; //activate our three kinds of information glEnableVertexAttribArray(positionLocation); glEnableVertexAttribArray(colorLocation); glEnableVertexAttribArray(normalLocation); //we're using the vertex data first glBindBuffer(GL_ARRAY_BUFFER, vbo); //define how the vertex pointer should work, in our case we're accessing floats 4 at a time with no special pattern glVertexAttribPointer(positionLocation, 4, GL_FLOAT, 0, 0, static_cast<char*>(0)); //now use color data, remember we're not using 4 at a time anymore glBindBuffer(GL_ARRAY_BUFFER, cbo); glVertexAttribPointer(colorLocation, 3, GL_FLOAT, 0, 0, static_cast<char*>(0)); //one more time with the normals glBindBuffer(GL_ARRAY_BUFFER, nbo); glVertexAttribPointer(normalLocation, 4, GL_FLOAT, 0, 0, static_cast<char*>(0)); //the last thing we need to do is setup our indices unsigned short* indices = new unsigned short[6]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 3; indices[4] = 0; indices[5] = 2; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned short), indices, GL_STATIC_DRAW); delete [] indices; //set the modelview uniform glUniformMatrix4fv(u_modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]); //draw the elements glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); //shut off the information since we're done drawing glDisableVertexAttribArray(positionLocation); glDisableVertexAttribArray(colorLocation); glDisableVertexAttribArray(normalLocation); }
/* * Make sure that the hardware is programmed for execution of 'accel' * according to the 'state'. */ void gles2SetState(void *drv, void *dev, GraphicsDeviceFuncs *funcs, CardState *state, DFBAccelerationMask accel) { GLES2DriverData *gdrv = drv; GLES2DeviceData *gdev = dev; StateModificationFlags modified = state->mod_hw; DFBBoolean blend = DFB_FALSE; D_DEBUG_AT(GLES2__2D, "%s(state %p, accel 0x%08x) <- dest %p, modified 0x%08x\n", __FUNCTION__, state, accel, state->destination, modified); /* * 1) Invalidate hardware states * * Each modification to the hw independent state invalidates one or more * hardware states. */ if (modified == SMF_ALL) { GLES2_INVALIDATE(ALL); } else if (modified) { if (modified & SMF_DESTINATION) GLES2_INVALIDATE(DESTINATION); if (modified & SMF_CLIP) GLES2_INVALIDATE(SCISSOR); if (modified & SMF_MATRIX) GLES2_INVALIDATE(MATRIX); if (modified & SMF_RENDER_OPTIONS) GLES2_INVALIDATE(MATRIX | RENDER_OPTS); if (modified & SMF_COLOR) GLES2_INVALIDATE(COLOR_DRAW | COLOR_BLIT); if (modified & SMF_DRAWING_FLAGS) GLES2_INVALIDATE(COLOR_DRAW); if (modified & SMF_BLITTING_FLAGS) GLES2_INVALIDATE(COLOR_BLIT); if (modified & SMF_SOURCE) GLES2_INVALIDATE(SOURCE); if (modified & (SMF_SRC_BLEND | SMF_DST_BLEND)) GLES2_INVALIDATE(BLENDFUNC); if (modified & SMF_SRC_COLORKEY) GLES2_INVALIDATE(COLORKEY); } /* * 2) Validate hardware states * * Each function has its own set of states that need to be validated. */ GLES2_CHECK_VALIDATE(SCISSOR); // GLES2_CHECK_VALIDATE(RENDER_OPTS); switch (accel) { case DFXL_FILLRECTANGLE: case DFXL_DRAWRECTANGLE: case DFXL_DRAWLINE: case DFXL_FILLTRIANGLE: // FIXME: workaround state issue in some drivers? glBlendFunc(GL_ZERO, GL_ZERO); GLES2_INVALIDATE(BLENDFUNC); // If alpha blending is used... if (state->drawingflags & DSDRAW_BLEND) { // ...require valid blend functions. GLES2_CHECK_VALIDATE(BLENDFUNC); glEnable(GL_BLEND); } else { glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); } /* * Validate the current shader program. This can't use the the * GLES2_CHECK_VALIDATE macro since the needed state isn't * tracked by DFB. */ if (state->render_options & DSRO_MATRIX) { if (gdev->prog_index != GLES2_DRAW_MAT) { // switch to program that uses 3x3 2D matrices gdev->prog_index = GLES2_DRAW_MAT; glUseProgram(gdev->progs[gdev->prog_index].obj); } } else { if (gdev->prog_index != GLES2_DRAW) { // switch to program that uses scales and offsets gdev->prog_index = GLES2_DRAW; glUseProgram(gdev->progs[gdev->prog_index].obj); } } // Now that we have a valid program, check destination state. GLES2_CHECK_VALIDATE(DESTINATION); // Check if the DSRO_MATRIX needs to be loaded. GLES2_CHECK_VALIDATE(MATRIX); // Check for valid drawing color. GLES2_CHECK_VALIDATE(COLOR_DRAW); // Enable vertex positions and disable texture coordinates. glEnableVertexAttribArray(GLES2VA_POSITIONS); glDisableVertexAttribArray(GLES2VA_TEXCOORDS); /* * 3) Tell which functions can be called without further * validation, i.e. SetState() * * When the hw independent state is changed, this collection is * reset. */ state->set = GLES2_SUPPORTED_DRAWINGFUNCTIONS; break; case DFXL_BLIT: case DFXL_STRETCHBLIT: // FIXME: workaround state issue in some drivers? glBlendFunc(GL_ZERO, GL_ZERO); GLES2_INVALIDATE(BLENDFUNC); // If alpha blending is used... if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) { // ...require valid blend functions. GLES2_CHECK_VALIDATE(BLENDFUNC); glEnable(GL_BLEND); blend = DFB_TRUE; } else { glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); blend = DFB_FALSE; } /* * Validate the current shader program. This can't use the the * GLES2_CHECK_VALIDATE macro since the needed state isn't * tracked by DFB. */ if (state->render_options & DSRO_MATRIX) { if (state->blittingflags & DSBLIT_SRC_COLORKEY && !blend) { if (gdev->prog_index != GLES2_BLIT_COLORKEY_MAT) { gdev->prog_index = GLES2_BLIT_COLORKEY_MAT; glUseProgram(gdev->progs[gdev->prog_index].obj); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } } else if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { if (gdev->prog_index != GLES2_BLIT_PREMULTIPLY_MAT) { gdev->prog_index = GLES2_BLIT_PREMULTIPLY_MAT; glUseProgram(gdev->progs[gdev->prog_index].obj); } } else if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR)) { if (gdev->prog_index != GLES2_BLIT_COLOR_MAT) { gdev->prog_index = GLES2_BLIT_COLOR_MAT; glUseProgram(gdev->progs[gdev->prog_index].obj); } } else { if (gdev->prog_index != GLES2_BLIT_MAT) { gdev->prog_index = GLES2_BLIT_MAT; glUseProgram(gdev->progs[gdev->prog_index].obj); } } } else { if (state->blittingflags & DSBLIT_SRC_COLORKEY && !blend) { if (gdev->prog_index != GLES2_BLIT_COLORKEY) { gdev->prog_index = GLES2_BLIT_COLORKEY; glUseProgram(gdev->progs[gdev->prog_index].obj); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } } else if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { if (gdev->prog_index != GLES2_BLIT_PREMULTIPLY) { gdev->prog_index = GLES2_BLIT_PREMULTIPLY; glUseProgram(gdev->progs[gdev->prog_index].obj); } } else if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR)) { if (gdev->prog_index != GLES2_BLIT_COLOR) { gdev->prog_index = GLES2_BLIT_COLOR; glUseProgram(gdev->progs[gdev->prog_index].obj); } } else { if (gdev->prog_index != GLES2_BLIT) { gdev->prog_index = GLES2_BLIT; glUseProgram(gdev->progs[gdev->prog_index].obj); } } } // We should have a valid program; check destination and source. GLES2_CHECK_VALIDATE(DESTINATION); GLES2_CHECK_VALIDATE(SOURCE); // If normal blitting or color keying is used... if (accel == DFXL_BLIT || (state->blittingflags & DSBLIT_SRC_COLORKEY)) { // ...don't use filtering glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } else { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // Check if DSRO_MATRIX needs to be loaded. GLES2_CHECK_VALIDATE(MATRIX); if (!blend) { // Check if colorkey needs to be loaded. GLES2_CHECK_VALIDATE(COLORKEY); } /* * To reduce the number of shader programs, the blit fragment * shader always modulates by a color. Validate that color. */ GLES2_CHECK_VALIDATE(COLOR_BLIT); // Enable vertex positions and texture coordinates. glEnableVertexAttribArray(GLES2VA_POSITIONS); glEnableVertexAttribArray(GLES2VA_TEXCOORDS); /* * 3) Tell which functions can be called without further * validation, i.e. SetState(). * * When the hw independent state is changed, this collection is * reset. */ state->set = accel; break; default: D_BUG("unexpected drawing/blitting function"); break; } gdrv->blittingflags = state->blittingflags; /* * prog_last is used by some state setting functions to determine if a * new program has been loaded; reset it now that state has been updated. */ gdev->prog_last = gdev->prog_index; /* * 4) Clear modification flags * * All flags have been evaluated in 1) and remembered for further * validation. If the hw independent state is not modified, this * function won't get called for subsequent rendering functions, unless * they aren't defined by 3). */ state->mod_hw = 0; D_DEBUG_AT(GLES2__2D, "%s(): using shader program \"%s\"\n", __FUNCTION__, gdev->progs[gdev->prog_index].name); }
/*!**************************************************************************** @Function DrawMesh @Input mesh The mesh to draw @Description Draws a SPODMesh after the model view matrix has been set and the meterial prepared. ******************************************************************************/ void OGLES2Fog::DrawMesh(int i32NodeIndex) { int i32MeshIndex = m_Scene.pNode[i32NodeIndex].nIdx; SPODMesh* pMesh = &m_Scene.pMesh[i32MeshIndex]; //// bind the VBO for the mesh glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i32MeshIndex]); //// bind the index buffer, won't hurt if the handle is 0 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i32MeshIndex]); // Enable the vertex attribute arrays glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(NORMAL_ARRAY); glEnableVertexAttribArray(TEXCOORD_ARRAY); glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData); glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData); glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); /* The geometry can be exported in 4 ways: - Indexed Triangle list - Non-Indexed Triangle list - Indexed Triangle strips - Non-Indexed Triangle strips */ if(pMesh->nNumStrips == 0) { if(m_puiIndexVbo[i32MeshIndex]) { // Indexed Triangle list glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0); } else { // Non-Indexed Triangle list glDrawArrays(GL_TRIANGLES, 0, pMesh->nNumFaces*3); } } else { for(int i = 0; i < (int)pMesh->nNumStrips; ++i) { int offset = 0; if(m_puiIndexVbo[i32MeshIndex]) { // Indexed Triangle strips glDrawElements(GL_TRIANGLE_STRIP, pMesh->pnStripLength[i]+2, GL_UNSIGNED_SHORT, (GLshort*)(offset*2)); } else { // Non-Indexed Triangle strips glDrawArrays(GL_TRIANGLE_STRIP, offset, pMesh->pnStripLength[i]+2); } offset += pMesh->pnStripLength[i]+2; } } // Safely disable the vertex attribute arrays glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(NORMAL_ARRAY); glDisableVertexAttribArray(TEXCOORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
void VertexAttribf::restoreState() { glDisableVertexAttribArray(m_location); }
//-------------------------------------------------------------------------------------------------- /// Draw the legend using shader programs //-------------------------------------------------------------------------------------------------- void OverlayScalarMapperLegend::renderLegend(OpenGLContext* oglContext, OverlayColorLegendLayoutInfo* layout, const MatrixState& matrixState) { CVF_CALLSITE_OPENGL(oglContext); CVF_TIGHT_ASSERT(layout); CVF_TIGHT_ASSERT(layout->size.x() > 0); CVF_TIGHT_ASSERT(layout->size.y() > 0); RenderStateDepth depth(false); depth.applyOpenGL(oglContext); RenderStateLine line(static_cast<float>(m_lineWidth)); line.applyOpenGL(oglContext); // All vertices. Initialized here to set Z to zero once and for all. static float vertexArray[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; // Per vector convenience pointers float* v0 = &vertexArray[0]; float* v1 = &vertexArray[3]; float* v2 = &vertexArray[6]; float* v3 = &vertexArray[9]; float* v4 = &vertexArray[12]; // Constant coordinates v0[0] = v3[0] = layout->x0; v1[0] = v4[0] = layout->x1; // Connects static const ushort trianglesConnects[] = { 0, 1, 4, 0, 4, 3 }; ref<ShaderProgram> shaderProgram = oglContext->resourceManager()->getLinkedUnlitColorShaderProgram(oglContext); CVF_TIGHT_ASSERT(shaderProgram.notNull()); if (shaderProgram->useProgram(oglContext)) { shaderProgram->clearUniformApplyTracking(); shaderProgram->applyFixedUniforms(oglContext, matrixState); } glBindBuffer(GL_ARRAY_BUFFER, 0); glEnableVertexAttribArray(ShaderProgram::VERTEX); glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray); // Render color bar as one colored quad per pixel int legendHeightPixelCount = static_cast<int>(layout->tickPixelPos->get(m_tickValues.size()-1) - layout->tickPixelPos->get(0) + 0.01); if (m_scalarMapper.notNull()) { int iPx; for (iPx = 0; iPx < legendHeightPixelCount; iPx++) { const Color3ub& clr = m_scalarMapper->mapToColor(m_scalarMapper->domainValue((iPx+0.5)/legendHeightPixelCount)); float y0 = static_cast<float>(layout->legendRect.min().y() + iPx); float y1 = static_cast<float>(layout->legendRect.min().y() + iPx + 1); // Dynamic coordinates for rectangle v0[1] = v1[1] = y0; v3[1] = v4[1] = y1; // Draw filled rectangle elements { UniformFloat uniformColor("u_color", Color4f(Color3f(clr))); shaderProgram->applyUniform(oglContext, uniformColor); #ifdef CVF_OPENGL_ES glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, trianglesConnects); #else glDrawRangeElements(GL_TRIANGLES, 0, 4, 6, GL_UNSIGNED_SHORT, trianglesConnects); #endif } } } // Render frame // Dynamic coordinates for tickmarks-lines bool isRenderingFrame = true; if (isRenderingFrame) { v0[0] = v2[0] = layout->legendRect.min().x()-0.5f; v1[0] = v3[0] = layout->legendRect.max().x()-0.5f; v0[1] = v1[1] = layout->legendRect.min().y()-0.5f; v2[1] = v3[1] = layout->legendRect.max().y()-0.5f; static const ushort frameConnects[] = { 0, 1, 1, 3, 3, 2, 2, 0}; UniformFloat uniformColor("u_color", Color4f(m_lineColor)); shaderProgram->applyUniform(oglContext, uniformColor); #ifdef CVF_OPENGL_ES glDrawElements(GL_LINES, 8, GL_UNSIGNED_SHORT, frameConnects); #else glDrawRangeElements(GL_LINES, 0, 3, 8, GL_UNSIGNED_SHORT, frameConnects); #endif } // Render tickmarks bool isRenderingTicks = true; if (isRenderingTicks) { // Constant coordinates v0[0] = layout->x0; v1[0] = layout->x1 - 0.5f*(layout->tickX - layout->x1) - 0.5f; v2[0] = layout->x1; v3[0] = layout->tickX - 0.5f*(layout->tickX - layout->x1) - 0.5f; v4[0] = layout->tickX; static const ushort tickLinesWithLabel[] = { 0, 4 }; static const ushort tickLinesWoLabel[] = { 2, 3 }; size_t ic; for (ic = 0; ic < m_tickValues.size(); ic++) { float y0 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic) - 0.5f); // Dynamic coordinates for tickmarks-lines v0[1] = v1[1] = v2[1] = v3[1] = v4[1] = y0; UniformFloat uniformColor("u_color", Color4f(m_lineColor)); shaderProgram->applyUniform(oglContext, uniformColor); const ushort * linesConnects; if ( m_visibleTickLabels[ic]) { linesConnects = tickLinesWithLabel; } else { linesConnects = tickLinesWoLabel; } #ifdef CVF_OPENGL_ES glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, linesConnects); #else glDrawRangeElements(GL_LINES, 0, 4, 2, GL_UNSIGNED_SHORT, linesConnects); #endif } } glDisableVertexAttribArray(ShaderProgram::VERTEX); CVF_TIGHT_ASSERT(shaderProgram.notNull()); shaderProgram->useNoProgram(oglContext); // Reset render states RenderStateDepth resetDepth; resetDepth.applyOpenGL(oglContext); RenderStateLine resetLine; resetLine.applyOpenGL(oglContext); CVF_CHECK_OGL(oglContext); }
void Attribute::disable() { glDisableVertexAttribArray(location); }
void GLSL::DisableVertexAttribute(int shader, const char *name) { GLint id = glGetAttribLocation(shader, name); if (id >= 0) glDisableVertexAttribArray(id); }
static void redraw(void *data, struct wl_callback *callback, uint32_t time) { struct window *window = data; static const GLfloat verts[3][2] = { { -0.5, -0.5 }, { 0.5, -0.5 }, { 0, 0.5 } }; static const GLfloat colors[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; GLfloat angle; GLfloat rotation[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; static const int32_t speed_div = 5; static uint32_t start_time = 0; struct wl_region *region; assert(window->callback == callback); window->callback = NULL; if (callback) wl_callback_destroy(callback); if (!window->configured) return; if (start_time == 0) start_time = time; angle = ((time-start_time) / speed_div) % 360 * M_PI / 180.0; rotation[0][0] = cos(angle); rotation[0][2] = sin(angle); rotation[2][0] = -sin(angle); rotation[2][2] = cos(angle); glViewport(0, 0, window->geometry.width, window->geometry.height); glUniformMatrix4fv(window->gl.rotation_uniform, 1, GL_FALSE, (GLfloat *) rotation); glClearColor(0.0, 0.0, 0.0, 0.5); glClear(GL_COLOR_BUFFER_BIT); glVertexAttribPointer(window->gl.pos, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(window->gl.col, 3, GL_FLOAT, GL_FALSE, 0, colors); glEnableVertexAttribArray(window->gl.pos); glEnableVertexAttribArray(window->gl.col); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(window->gl.pos); glDisableVertexAttribArray(window->gl.col); if (window->opaque || window->fullscreen) { region = wl_compositor_create_region(window->display->compositor); wl_region_add(region, 0, 0, window->geometry.width, window->geometry.height); wl_surface_set_opaque_region(window->surface, region); wl_region_destroy(region); } else { wl_surface_set_opaque_region(window->surface, NULL); } window->callback = wl_surface_frame(window->surface); wl_callback_add_listener(window->callback, &frame_listener, window); eglSwapBuffers(window->display->egl.dpy, window->egl_surface); }
int main(int argc, char *argv[]) { SDL_Init(SDL_INIT_VIDEO); displayWindow = SDL_CreateWindow("My Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 360, SDL_WINDOW_OPENGL); SDL_GLContext context = SDL_GL_CreateContext(displayWindow); SDL_GL_MakeCurrent(displayWindow, context); #ifdef _WINDOWS glewInit(); #endif glViewport(0, 0, 640, 360); ShaderProgram program(RESOURCE_FOLDER"vertex_textured.glsl", RESOURCE_FOLDER"fragment_textured.glsl"); Matrix projectionMatrix; Matrix modelMatrix; Matrix viewMatrix; projectionMatrix.setOrthoProjection(-3.55f, 3.55f, -2.0f, 2.0f, -1.0f, 1.0f); program.setModelMatrix(modelMatrix); program.setProjectionMatrix(projectionMatrix); program.setViewMatrix(viewMatrix); glUseProgram(program.programID); float stevenPos = 0.0; float stevenJump = 0.1; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); SDL_Event event; bool done = false; while (!done) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT || event.type == SDL_WINDOWEVENT_CLOSE) { done = true; } } glClearColor(0.5f, 0.3f, 0.4f, 0.1f); glClear(GL_COLOR_BUFFER_BIT); //Finn the Human GLuint img1 = LoadTexture("finn.png"); float vertices[] = { -0.5f, -1.0f, 0.5f, 1.0f, -0.5f, 1.0f, 0.5f, 1.0f, -0.5f, -1.0f, 0.5f, -1.0f }; glVertexAttribPointer(program.positionAttribute, 2, GL_FLOAT, false, 0, vertices); glEnableVertexAttribArray(program.positionAttribute); float texCoords[] = { 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; glVertexAttribPointer(program.texCoordAttribute, 2, GL_FLOAT, false, 0, texCoords); glEnableVertexAttribArray(program.texCoordAttribute); modelMatrix.identity(); program.setModelMatrix(modelMatrix); glBindTexture(GL_TEXTURE_2D, img1); glDrawArrays(GL_TRIANGLES, 0, 6); glDisableVertexAttribArray(program.positionAttribute); glDisableVertexAttribArray(program.texCoordAttribute); //Rick and Morty GLuint img2 = LoadTexture("RickandMorty.png"); float vertices2[] = { -3.5f, -2.0f, -0.5f, 0.5f, -3.5f, 0.5f, -0.5f, 0.5f, -3.5, -2.0f, -0.5f, -2.0f }; glVertexAttribPointer(program.positionAttribute, 2, GL_FLOAT, false, 0, vertices2); glEnableVertexAttribArray(program.positionAttribute); float texCoords2[] = { 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; glVertexAttribPointer(program.texCoordAttribute, 2, GL_FLOAT, false, 0, texCoords2); glEnableVertexAttribArray(program.texCoordAttribute); modelMatrix.identity(); program.setModelMatrix(modelMatrix); glBindTexture(GL_TEXTURE_2D, img2); glDrawArrays(GL_TRIANGLES, 0, 6); glDisableVertexAttribArray(program.positionAttribute); glDisableVertexAttribArray(program.texCoordAttribute); //Steven GLuint img3 = LoadTexture("steven.png"); float vertices3[] = { 1.0f, -1.0f, 3.0f, 1.0f, 1.0f, 1.0f, 3.0f, 1.0f, 1.0f, -1.0f, 3.0, -1.0f }; glVertexAttribPointer(program.positionAttribute, 2, GL_FLOAT, false, 0, vertices3); glEnableVertexAttribArray(program.positionAttribute); float texCoords3[] = { 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; glVertexAttribPointer(program.texCoordAttribute, 2, GL_FLOAT, false, 0, texCoords3); glEnableVertexAttribArray(program.texCoordAttribute); if (stevenPos >= 1.0) stevenJump = -0.1; else if (stevenPos <= -1.0) stevenJump = 0.1; stevenPos += stevenJump; modelMatrix.identity(); modelMatrix.Translate(0.0, stevenPos, 0.0); program.setModelMatrix(modelMatrix); glBindTexture(GL_TEXTURE_2D, img3); glDrawArrays(GL_TRIANGLES, 0, 6); glDisableVertexAttribArray(program.positionAttribute); glDisableVertexAttribArray(program.texCoordAttribute); SDL_GL_SwapWindow(displayWindow); } SDL_Quit(); return 0; }
void Font::DrawString(const Graphics& g, const Brush& brush, const string& s, int len, int x, int y, int w, int h, int flags){ int xx = x; int yy = y; int rr = x + w; int bb = y + h; //g.DrawRect(Pens::Blue, x, y, w, h); if(len < 0) len = s.length(); vector<int> ws, cs; int wi = 0, c = 0; for (int i = 0; i<len;){ char_type cc; int rs = READ_CHAR(&cc, s.c_str() + i, len-i); if (rs>0) i += rs; else break; bool n = cc == L'\n' || cc == 0x0085 || cc == 0x2028 || cc == 0x2029; //if (!n && cc != L'\r') PutChar(cc); int ww = n ? 0 : map[cc]->width; if ((flags & FontFlag_NoWrap) == 0 && (n || (w >= 0 && wi + ww>w))){ if (c == 0){ ws.push_back(ww); cs.push_back(1); wi = 0; c = 0; } else{ ws.push_back(wi); cs.push_back(c); wi = ww; c = 1; if (n){ wi = 0; } } } else { wi += ww; c++; } } if (c > 0){ ws.push_back(wi); cs.push_back(c); } int rh = cs.size()*face->size->metrics.y_ppem; // real height // vertical alignment switch ((flags >> 2) & 3) { case 1: yy += (h-rh) / 2; break; case 2: yy += h-rh; break; } //bool clip_not_whole = (flags & FontFlag_ClipNotWhole) != 0; glUniform1i(Program::CurrentShader()->useTex2, 1); int line = -1; int row = 0; yy -= face->size->metrics.y_ppem; for (int i = 0; i < len; ){ if (row == 0){ line++; xx = x; yy += face->size->metrics.y_ppem; switch (flags & 0x03) { case 1: xx += (w - ws[line]) / 2; break; case 2: xx += w - ws[line]; break; } } char_type cc; int rs = READ_CHAR(&cc, s.c_str() + i, len - i); if (rs>0) i += rs; else return; if (++row == cs[line]) row = 0; if (cc == L'\r') continue; bool n = cc == L'\n' || cc == 0x0085 || cc == 0x2028 || cc == 0x2029; // new line if (!n){ Char& c = *map[cc]; Rect& r = c.bounds; float ss = TEXTURE_SIZE; float L = r.Left() / ss; float T = ((int)r.Top() % TEXTURE_SIZE) / ss; float R = r.Right() / ss; float B = T + c.height / ss; float ps[] = { L, T, R, T, R, B, L, B }; glEnableVertexAttribArray(TEXCOORD_ATTRIB_LOC); glVertexAttribPointer(TEXCOORD_ATTRIB_LOC, 2, GL_FLOAT, GL_FALSE, 0, ps); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[r.Top() / TEXTURE_SIZE]); glActiveTexture(GL_TEXTURE0); g.FillRect(brush, xx + c.left, yy - c.top, c.width, c.height); glDisableVertexAttribArray(TEXCOORD_ATTRIB_LOC); //glUniform1i(Program::CurrentShader()->useTex2, 0); //g.DrawRect(Pens::Green, xx + c.left, yy - c.top, c.width, c.height); //glUniform1i(Program::CurrentShader()->useTex2, 1); xx += c.width; } } glUniform1i(Program::CurrentShader()->useTex2, 0); }
//-------------------------------------------------------------- void ofVbo::VertexAttribute::disable() const{ glDisableVertexAttribArray(location); }
void TMD5Renderer::Render() { glUseProgram(shaderProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); assert( glGetError() ==GL_NO_ERROR ); diffuseLocation = glGetUniformLocation(shaderProgram, "diffuse"); assert( glGetError() ==GL_NO_ERROR ); glUniform1i(diffuseLocation, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, normalTexture); assert( glGetError() ==GL_NO_ERROR ); int normalMapLocation = glGetUniformLocation(shaderProgram, "normalMap"); assert( glGetError() ==GL_NO_ERROR ); glUniform1i(normalMapLocation, 1); //glActiveTexture(GL_TEXTURE0); glBindAttribLocation(shaderProgram, 0, "vertex"); glBindAttribLocation(shaderProgram, 1, "uv"); assert( glGetError() ==GL_NO_ERROR ); #ifdef GL_ES_VERSION_2_0 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices); assert( glGetError() == GL_NO_ERROR); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, uvs); assert( glGetError() == GL_NO_ERROR); glDrawArrays (GL_TRIANGLES, 0, vertexCount); assert( glGetError() == GL_NO_ERROR); #else bonesLocation = glGetUniformLocation(shaderProgram, "bones"); assert( bonesLocation!=-1); assert( glGetError() ==GL_NO_ERROR ); int count = md5Model->GetJointCount(); float matrices[count * 16]; memset(matrices, 0, sizeof(float)*count*16); float* ptr = matrices; for(int j=0;j<count;++j) { TMD5Joint* joint = md5Model->GetJoint(j); Matrix4 transform = joint->transform * joint->inverseBindPose; *ptr ++ = transform.m[0][0]; *ptr ++ = transform.m[1][0]; *ptr ++ = transform.m[2][0]; *ptr ++ = transform.m[3][0]; *ptr ++ = transform.m[0][1]; *ptr ++ = transform.m[1][1]; *ptr ++ = transform.m[2][1]; *ptr ++ = transform.m[3][1]; *ptr ++ = transform.m[0][2]; *ptr ++ = transform.m[1][2]; *ptr ++ = transform.m[2][2]; *ptr ++ = transform.m[3][2]; *ptr ++ = transform.m[0][3]; *ptr ++ = transform.m[1][3]; *ptr ++ = transform.m[2][3]; *ptr ++ = transform.m[3][3]; } //glUniform1i(boneCountLocation, count); assert( glGetError() == GL_NO_ERROR ); glUniformMatrix4fv(bonesLocation, count, GL_FALSE, matrices); assert( glGetError() == GL_NO_ERROR ); for(int m=0;m<md5Model->meshes.size();++m) { if( md5Model->meshes[m]->IsVisible() ) { TMD5Mesh* mesh = md5Model->meshes[m]; glBindVertexArray(vertexArrayObject[m]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); glEnableVertexAttribArray(5); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO[m]); int indexCount = 3 * (int)mesh->mTriangles.size(); // Draw the triangles ! glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)0); assert( glGetError() == GL_NO_ERROR); } } #endif glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glDisableVertexAttribArray(3); glDisableVertexAttribArray(4); glDisableVertexAttribArray(5); glUseProgram(0); glBindVertexArray(0); }
void Billboard::Clean() { glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); }
bool AppCore::render() { #if !DISCARD_SKYBOX // Try to load textures if not already completed if (_staticTextureCompleteCount <= 6) loadStaticTextureIfAvailable(); #endif APIFactory::GetInstance().lock(OPENGL_LOCK); double timestamp = APIFactory::GetInstance().getTimeInMS(); #if !(RENDER_OCTREE_DEBUG_VOXELS || USE_STATIC_POINT_CLOUD) if ( !(_currentCameraParameterRequest & 1) && (timestamp - _lastCameraParameterChangeTimestamp > WVS_RELOAD_DELAY[0])) { // Request 1/4 of screen resolution from WVS requestPointCloudForCurrentView(4); _currentCameraParameterRequest |= 1; } else if ( !(_currentCameraParameterRequest & 2) && (timestamp - _lastCameraParameterChangeTimestamp > WVS_RELOAD_DELAY[1])) { // Request full screen resolution from WVS requestPointCloudForCurrentView(1); _currentCameraParameterRequest |= 3; } #endif if (_isUserInputMode) _renderingRequired = true; if (_renderQuality < 1.0f) _renderingRequired = true; #if !(RENDER_OCTREE_DEBUG_VOXELS || USE_STATIC_POINT_CLOUD) if (_isNewDataAvialable) { _renderingRequired = true; _isNewDataAvialable = false; } #endif if (!_renderingRequired) { APIFactory::GetInstance().unlock(OPENGL_LOCK); APIFactory::GetInstance().processUserInterfaceEvents(); return false; } _renderingRequired = false; // Updates the view frustum that is used for culling etc. based on the current // camera parameters _viewFrustum->updateCameraViewParameterCache(); // Clear context glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #if !DISCARD_SKYBOX // Render Skybox and ground plane if (_staticTextureCompleteCount > 0) { glUseProgram(_textureShaderProgram.handle); glUniformMatrix4fv( _textureShaderProgram.uniforms[SHADER_UNIFORM_VIEW_PROJECTION_MATRIX], 1, GL_FALSE, _viewFrustum->getViewProjectionMatrixCachePtr()->f); MATRIX model; MatrixTranslation(model, _viewFrustum->getCameraPostionCachePtr()->x, _viewFrustum->getCameraPostionCachePtr()->y, _viewFrustum->getCameraPostionCachePtr()->z); glUniformMatrix4fv( _textureShaderProgram.uniforms[SHADER_UNIFORM_MODEL_MATRIX], 1, GL_FALSE, model.f); _skybox->render(); } #endif // Render points glUseProgram(_pointShaderProgram.handle); glUniform3fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_REGION_ORIGIN], OCTREE_LEAF_LEVEL + 1, _octree->getRegionOrginArray()); glUniform1fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VOXEL_INCIRCLE_DIAMETER], OCTREE_LEAF_LEVEL + 1, _octree->getVoxelIncircleDiameterArray()); glUniform1fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_NODE_INCIRCLE_DIAMETER], OCTREE_LEAF_LEVEL + 1, _octree->getNodeIncircleDiameterArray()); glUniform1fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VOXEL_SCREENSIZE_CIRCUMCIRCLE_RADIUS], OCTREE_LEAF_LEVEL + 1, _voxelScreensizeCircumcircleRadius); // Set camera position (necessary for backface culling) glUniform3fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_CAMERA_POSITION], 1, (GLfloat*)(_viewFrustum->getCameraPostionCachePtr())); glUniformMatrix4fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_PROJECTION_MATRIX], 1, GL_FALSE, _viewFrustum->getProjectionMatrixCachePtr()->f); glUniformMatrix4fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VIEW_MATRIX], 1, GL_FALSE, _viewFrustum->getViewMatrixCachePtr()->f); #if COMPACT_NODE_REGION_ENCODING const uint32_t regionVoxelFactor = 1; const uint8_t regionLevelStride = 4; const uint32_t regionLevelDataType = GL_UNSIGNED_BYTE; #else const uint32_t regionVoxelFactor = 2; const uint8_t regionLevelStride = 8; const uint32_t regionLevelDataType = GL_UNSIGNED_SHORT; #endif #if DIRECT_VBO #if DIRECT_VBO_DOUBLE_BUFFERED if (bufferID == 0) bufferID = 1; else bufferID = 0; #endif glBindBuffer(GL_ARRAY_BUFFER, _dataVBO[bufferID]); uint32_t* const gpuBuffer = (uint32_t*)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); uint32_t* const regionLevelBuffer = gpuBuffer; uint32_t* const voxelBuffer = gpuBuffer + GPU_MAX_POINTS * regionVoxelFactor; glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA1, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, (void *)(GPU_MAX_POINTS * regionLevelStride)); glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA2, 4, regionLevelDataType, GL_FALSE, 0, 0); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); // Traverse octree, copy points into buffer and call rendering callback _octree->copyPointsToBuffer( _renderQuality, !_isInteractiveMode, regionLevelBuffer, voxelBuffer, &_pointsToRenderCount, &_renderingRequired); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); glUnmapBufferOES(GL_ARRAY_BUFFER); #elif NO_VBO uint32_t* const regionLevelBuffer = _gpuBuffer; uint32_t* const voxelBuffer = _gpuBuffer + GPU_MAX_POINTS * regionVoxelFactor; glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA1, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4, voxelBuffer); glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA2, 4, regionLevelDataType, GL_FALSE, regionLevelStride, regionLevelBuffer); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); // Traverse octree, copy points into buffer and call rendering callback _octree->copyPointsToBuffer( _renderQuality, !_isInteractiveMode, regionLevelBuffer, voxelBuffer, &_pointsToRenderCount, &_renderingRequired); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); #endif #ifdef OPENGL_ES const GLenum discard_attachments[] = { GL_DEPTH_ATTACHMENT }; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discard_attachments); #endif if (_renderingRequired & Octree::OCTREE_RENDERING_CANCELED) { APIFactory::GetInstance().unlock(OPENGL_LOCK); //TODO: In case we overestimate the render quality by far this becomes a stupid loop _octree->estimateInteractiveRenderQuality(&_renderQuality, OCTREE_INTERACTIVE_RENDERING_POINT_THRESHOLD); return false; } #if BENCHMARK_1_MILLION if (_pointsToRenderCount >= 1000000) { _renderingRequired = true; double time = APIFactory::GetInstance().getTimeInMS(); printf("%f\n", time - _lastFrame); _lastFrame = time; } #endif if (_isUserInputMode || ((timestamp - _lastCameraParameterChangeTimestamp) < 500)) { // Within 500ms we consider any input as movement double_t renderingTimeInMS = APIFactory::GetInstance().getTimeInMS() - timestamp; if (renderingTimeInMS > (1000.0 / MINIMUM_FRAMERATE)) { // Time to render last frame took longer than target framerate. // Lower render quality to speed up framerate. _renderQuality -= RENDER_QUALITY_FINE_ADJUSTMENT; _nodeRestoreQuota = 0; } else if (renderingTimeInMS < (1000.0 / MAXIMUM_FRAMERATE)) { _renderQuality += RENDER_QUALITY_FINE_ADJUSTMENT; _nodeRestoreQuota = 32; } _renderingRequired = true; } else { // No movement with in the last 500ms. Increase render quality _renderQuality += RENDER_QUALITY_COARSE_ADJUSTMENT; _isInteractiveMode = false; } // Check range of render quality if (_renderQuality > 1.0f) _renderQuality = 1.0f; else if (_renderQuality < RENDER_QUALITY_FINE_ADJUSTMENT) _renderQuality = RENDER_QUALITY_FINE_ADJUSTMENT; APIFactory::GetInstance().unlock(OPENGL_LOCK); return true; }
void Radiosity::drawVBOs() { // ===================== // DRAW ALL THE POLYGONS assert ((int)mesh_tri_indices.size() + (int)mesh_textured_tri_indices.size() == num_faces*4); // render with Phong lighting? if (args->render_mode == RENDER_MATERIALS) { // yes glUniform1i(GLCanvas::colormodeID, 1); } else { // no glUniform1i(GLCanvas::colormodeID, 0); } // render untextured faces glBindBuffer(GL_ARRAY_BUFFER,mesh_tri_verts_VBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,mesh_tri_indices_VBO); glEnableVertexAttribArray(0); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor),(void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor),(void*)sizeof(glm::vec3) ); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor), (void*)(sizeof(glm::vec3)*2)); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor), (void*)(sizeof(glm::vec3)*2 + sizeof(glm::vec4))); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 3, GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor), (void*)(sizeof(glm::vec3)*2 + sizeof(glm::vec4)*2)); glDrawElements(GL_TRIANGLES, mesh_tri_indices.size()*3,GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glDisableVertexAttribArray(3); glDisableVertexAttribArray(4); // render faces with textures if (mesh_textured_tri_indices.size() > 0) { // FIXME: there is something buggy with textures still //glUniform1i(GLCanvas::colormodeID, 2); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GLCanvas::textureID); GLCanvas::mytexture = glGetUniformLocation(GLCanvas::programID, "mytexture"); glUniform1i(GLCanvas::mytexture, /*GL_TEXTURE*/0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,mesh_textured_tri_indices_VBO); glEnableVertexAttribArray(0); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor),(void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor),(void*)sizeof(glm::vec3) ); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor), (void*)(sizeof(glm::vec3)*2)); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor), (void*)(sizeof(glm::vec3)*2 + sizeof(glm::vec4))); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 3, GL_FLOAT,GL_FALSE,sizeof(VBOPosNormalColor), (void*)(sizeof(glm::vec3)*2 + sizeof(glm::vec4)*2)); glDrawElements(GL_TRIANGLES, mesh_textured_tri_indices.size()*3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glDisableVertexAttribArray(3); glDisableVertexAttribArray(4); //glUniform1i(GLCanvas::colormodeID, 1); } HandleGLError(); }
void Text::update() { if(charHeight && font && text != "") { font->setCharacterSize(charHeight); //Create texture for rendering characters GLuint charTex = 0; glGenTextures(1, &charTex); glBindTexture(GL_TEXTURE_2D, charTex); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); textSP->setUniform1i("tex", 0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbID); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); //Draw text to texture Vec3f strDims = font->getStringSize(text);//Vec2i(text.length()*30, 30);//font->getStringSize(text); AVec strSize(strDims.x, strDims.y); origin_y = strDims.z; tex.create(strSize); glClearColor(0.0, 0.0, 0.0, 0); tex.setActive(true); textSP->setActive(); glBindTexture(GL_TEXTURE_2D, charTex); glDisable(GL_BLEND); Point2i cursor(0, origin_y); for(int i = 0; i < text.size(); i++) { FT_GlyphSlot g = font->getCharacter(text[i]); Point2f glCursor = toGlPoint(cursor + Vec2i(g->bitmap_left, -g->bitmap_top), strSize); Vec2i glyphSize = Vec2i(g->bitmap.width, g->bitmap.rows); Vec2f glSize = toGlVec(glyphSize, strSize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, g->bitmap.width, g->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, g->bitmap.buffer); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); float data[4][4] = { {glCursor.x, glCursor.y, 0.0f, 0.0f}, {glCursor.x + glSize.x, glCursor.y, 1.0f, 0.0f}, {glCursor.x, glCursor.y + glSize.y, 0.0f, 1.0f}, {glCursor.x + glSize.x, glCursor.y + glSize.y, 1.0f, 1.0f}, }; glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4, data, GL_DYNAMIC_DRAW); glColor3f(1.0f, 1.0f, 1.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); cursor.x += g->advance.x >> 6; cursor.y += g->advance.y >> 6; } glEnable(GL_BLEND); glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, NULL); glDeleteTextures(1, &charTex); glBindTexture(GL_TEXTURE_2D, NULL); glDisable(GL_TEXTURE_2D); glUseProgram(0); tex.setActive(false); glClearColor(0.15, 0.15, 0.15, 1.0); }
void CGUITextureGLES::DrawQuad(const CRect &rect, color_t color, CBaseTexture *texture, const CRect *texCoords) { if (texture) { glActiveTexture(GL_TEXTURE0); texture->LoadToGPU(); glBindTexture(GL_TEXTURE_2D, texture->GetTextureObject()); glEnable(GL_TEXTURE_2D); } else glDisable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); // Turn Blending On VerifyGLState(); GLfloat col[4][4]; GLfloat ver[4][3]; GLfloat tex[4][2]; GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip g_Windowing.EnableGUIShader(SM_TEXTURE); GLint posLoc = g_Windowing.GUIShaderGetPos(); GLint colLoc = g_Windowing.GUIShaderGetCol(); GLint tex0Loc = g_Windowing.GUIShaderGetCoord0(); glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, 0, ver); glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, col); glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, 0, tex); glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(tex0Loc); glEnableVertexAttribArray(colLoc); for (int i=0; i<4; i++) { // Setup Colour Values col[i][0] = (GLubyte)GET_R(color); col[i][1] = (GLubyte)GET_G(color); col[i][2] = (GLubyte)GET_B(color); col[i][3] = (GLubyte)GET_A(color); } // Setup vertex position values // ver[0][3] = ver[1][3] = ver[2][3] = ver[3][3] = 0.0f; // FIXME, ver has only 3 elements - this is not correct ver[0][0] = ver[3][0] = rect.x1; ver[0][1] = ver[1][1] = rect.y1; ver[1][0] = ver[2][0] = rect.x2; ver[2][1] = ver[3][1] = rect.y2; // Setup texture coordinates CRect coords = texCoords ? *texCoords : CRect(0.0f, 0.0f, 1.0f, 1.0f); tex[0][0] = tex[3][0] = coords.x1; tex[0][1] = tex[1][1] = coords.y1; tex[1][0] = tex[2][0] = coords.x2; tex[2][1] = tex[3][1] = coords.y2; glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx); glDisableVertexAttribArray(posLoc); glDisableVertexAttribArray(colLoc); glDisableVertexAttribArray(tex0Loc); g_Windowing.DisableGUIShader(); if (texture) glDisable(GL_TEXTURE_2D); }
void NTextInput::Draw(NCamera* View) { GenerateBuffers(); if (Texture == NULL || GetColor().w == 0) { return; } if (Shader == NULL) { glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER,Buffers[0]); glVertexPointer(2,GL_FLOAT,0,NULL); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER,Buffers[1]); glTexCoordPointer(2,GL_FLOAT,0,NULL); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (Texture != NULL) { glBindTexture(GL_TEXTURE_2D,Texture->GetID()); } glMatrixMode(GL_PROJECTION); glLoadMatrixf(&View->GetOrthoMatrix()[0][0]); glMatrixMode(GL_MODELVIEW); glm::mat4 MVP = View->GetViewMatrix()*GetModelMatrix(); glLoadMatrixf(&MVP[0][0]); glColor4fv(&(GetColor()[0])); glDrawArrays(GL_QUADS,0,Verts.size()); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); return; } glUseProgram(Shader->GetID()); glActiveTexture(GL_TEXTURE0); if (Texture != NULL) { glBindTexture(GL_TEXTURE_2D,Texture->GetID()); } glUniform1i(TextureLoc,0); glm::mat4 MVP = View->GetOrthoMatrix()*View->GetViewMatrix()*GetModelMatrix(); glUniformMatrix4fv(MatrixLoc,1,GL_FALSE,&MVP[0][0]); glUniform4fv(ColorLoc,1,&(GetColor()[0])); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER,Buffers[0]); glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,NULL); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER,Buffers[1]); glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,NULL); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); glDrawArrays(GL_QUADS,0,Verts.size()); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glUseProgram(0); }
static void gub_copy_texture_egl(GUBGraphicContextEGL *gcontext, GstVideoInfo *video_info, GstBuffer *buffer, void *native_texture_ptr) { if (!gcontext) return; if (native_texture_ptr) { GLint previous_vp[4]; GLint previous_prog; GLint previous_fbo; GLint previous_tex; GLint previous_ab; GLint previous_rbo; GLint previous_vaenabled[2]; GLenum status; GLuint unity_tex = (GLuint)(size_t)(native_texture_ptr); GstVideoFrame video_frame; GLuint gst_tex; gst_video_frame_map(&video_frame, video_info, buffer, GST_MAP_READ | GST_MAP_GL); gst_tex = *(guint *)GST_VIDEO_FRAME_PLANE_DATA(&video_frame, 0); glGetIntegerv(GL_VIEWPORT, previous_vp); glGetIntegerv(GL_CURRENT_PROGRAM, &previous_prog); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previous_fbo); glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous_tex); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &previous_ab); glGetIntegerv(GL_RENDERBUFFER_BINDING, &previous_rbo); glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &previous_vaenabled[0]); glGetVertexAttribiv(1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &previous_vaenabled[1]); glBindFramebuffer(GL_FRAMEBUFFER, gcontext->fbo); glViewport( -video_info->width * gcontext->crop_left, -video_info->height * gcontext->crop_top, video_info->width, video_info->height); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, unity_tex, 0); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { gub_log("Frame buffer not complete, status 0x%x, unity_tex %d", status, unity_tex); } glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glPolygonOffset(0.0f, 0.0f); glDisable(GL_POLYGON_OFFSET_FILL); glUseProgram(gcontext->po); if (gcontext->gl->gl_vtable->BindVertexArray) gcontext->gl->gl_vtable->BindVertexArray(gcontext->vao); glBindBuffer(GL_ARRAY_BUFFER, gcontext->vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (const GLvoid *)(0)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (const GLvoid *)(2 * sizeof(GLfloat))); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gst_tex); glUniform1i(gcontext->samplerLoc, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, previous_fbo); glViewport(previous_vp[0], previous_vp[1], previous_vp[2], previous_vp[3]); if (gcontext->gl->gl_vtable->BindVertexArray) gcontext->gl->gl_vtable->BindVertexArray(0); glUseProgram(previous_prog); glBindBuffer(GL_ARRAY_BUFFER, previous_ab); glBindRenderbuffer(GL_RENDERBUFFER, previous_rbo); if (!previous_vaenabled[0]) glDisableVertexAttribArray(0); if (!previous_vaenabled[1]) glDisableVertexAttribArray(1); glBindTexture(GL_TEXTURE_2D, previous_tex); gst_video_frame_unmap(&video_frame); } }
void outPut::drawTerrain(bool reinit) { static bool lastwfStatus(!_reg.WIREFRAME); if(lastwfStatus != _reg.WIREFRAME) { if(_reg.WIREFRAME) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(1); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); }} lastwfStatus = _reg.WIREFRAME; static bool init(true); static VA terrain; static GLuint buf_pos, buf_norm, buf_cost, buf_index; unsigned int nbVertices = _dimensions.x*_dimensions.y; unsigned int nbIndex = (_dimensions.x-1)*(_dimensions.y-1)*6; //nbIndex = nbVertices; /*Chaque vertex est associé à une maille qui 'coûte' 6 indices en mémoire : _ |\| -> deux triangles, avec 3 indices par triangle. On enlève une ligne et une colonne parce que ceux sur les côtés n'entrainent pas une maille. +- */ if(init || reinit) { gen_verticesMap(); drawNormals(true); glDeleteBuffers(1,&buf_pos); glDeleteBuffers(1,&buf_norm); glDeleteBuffers(1,&buf_cost); glDeleteBuffers(1,&buf_index); delete terrain.verticesA; delete terrain.normalsA; delete terrain.costsA; delete terrain.indexA; terrain.verticesA = new float[nbVertices*P_SIZE]; terrain.normalsA = new float[nbVertices*N_SIZE]; terrain.costsA = new int[nbVertices*C_SIZE]; terrain.indexA = new unsigned int[nbIndex]; ///Remplissage des tableaux de sommets et de coûts for(unsigned int i = 0; i < _dimensions.x; i++) { for(unsigned int j = 0; j < _dimensions.y; j++) { coords3d<float> vertex(0,0,0), normal(0,0,0); vertex = getVertex<float>(i,j); normal = _scene3d.normalMap[i][j]; int vertexPos = (i*_dimensions.y+j); terrain.verticesA[vertexPos*P_SIZE] = vertex.x; terrain.verticesA[vertexPos*P_SIZE+1] = vertex.y; terrain.verticesA[vertexPos*P_SIZE+2] = vertex.z; terrain.normalsA[vertexPos*P_SIZE] = normal.x; terrain.normalsA[vertexPos*P_SIZE+1] = normal.y; terrain.normalsA[vertexPos*P_SIZE+2] = normal.z; terrain.costsA[vertexPos*C_SIZE] = -1; } } ///Remplissage de l'index for(unsigned int i = 0; i < _dimensions.x-1; i++) { for(unsigned int j = 0; j < _dimensions.y-1; j++) { terrain.indexA[((i*(_dimensions.y-1))+j)*6] = i*_dimensions.y+j; terrain.indexA[((i*(_dimensions.y-1))+j)*6+2] = i*_dimensions.y+j+1; terrain.indexA[((i*(_dimensions.y-1))+j)*6+1] = (i+1)*_dimensions.y+j; terrain.indexA[((i*(_dimensions.y-1))+j)*6+3] = i*_dimensions.y+j+1; terrain.indexA[((i*(_dimensions.y-1))+j)*6+4] = (i+1)*_dimensions.y+j; terrain.indexA[((i*(_dimensions.y-1))+j)*6+5] = (i+1)*_dimensions.y+j+1; //cout << "\nindice max : " << ((i*(_dimensions.y-1))+j)*6+5 << " / " << nbIndex; } } /* creation de nos VBO+IBO */ glGenBuffers(1, &buf_pos); glGenBuffers(1, &buf_cost); glGenBuffers(1, &buf_norm); glGenBuffers(1, &buf_index); /* construction du VBO de positions */ glBindBuffer(GL_ARRAY_BUFFER, buf_pos); glBufferData(GL_ARRAY_BUFFER, (nbVertices*P_SIZE*sizeof *terrain.verticesA), NULL, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, (nbVertices*P_SIZE*sizeof *terrain.verticesA), terrain.verticesA); /* construction du VBO de normales */ glBindBuffer(GL_ARRAY_BUFFER, buf_norm); glBufferData(GL_ARRAY_BUFFER, (nbVertices*N_SIZE*sizeof *terrain.normalsA), NULL, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, (nbVertices*N_SIZE*sizeof *terrain.normalsA), terrain.normalsA); /* construction du VBO de coûts */ glBindBuffer(GL_ARRAY_BUFFER, buf_cost); glBufferData(GL_ARRAY_BUFFER, (nbVertices*C_SIZE*sizeof *terrain.costsA), NULL, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, (nbVertices*C_SIZE*sizeof *terrain.costsA), terrain.costsA); /* construction du IBO */ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf_index); glBufferData(GL_ELEMENT_ARRAY_BUFFER, nbIndex * sizeof *terrain.indexA, NULL, GL_STREAM_DRAW); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, nbIndex * sizeof *terrain.indexA, terrain.indexA); //On debind les VBO+IBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); _maxValue = 1; // cout<<"\n(re)initialisation de l'affichage du terrain reussie\n"; init = false; _valueChanges.clear(); } drawAxis(); glBindBuffer(GL_ARRAY_BUFFER, buf_cost); for(unsigned int i = 0; i < _valueChanges.size(); ++i) { int newCost = _valueChanges[i].value; //newCost = 2; //std::cout << newCost << "/" << _maxValue << std::endl; glBufferSubData(GL_ARRAY_BUFFER, (_valueChanges[i].x*_dimensions.y + _valueChanges[i].y)*(sizeof newCost)*C_SIZE, (sizeof newCost), &newCost); //terrain.costsA[_valueChanges[i].x*_dimensions.y + _valueChanges[i].y] = newCost; } /* glBufferSubData(GL_ARRAY_BUFFER, 0, (nbVertices*C_SIZE*sizeof *terrain.costsA), terrain.costsA);*/ catchError("application de changements de couleur"); _valueChanges.clear(); glEnable(GL_DEPTH_TEST); if(_reg.DRAW_NORMALS) drawNormals(); glUseProgram(_sLight.getProgramID()); //Envoi des uniforms glUniform1i(uid_maxCost, _maxValue); catchError("Envoi de la valeur max"); glUniform3f(uid_defaultColor, _reg.UNIFORM_COLOR[0],_reg.UNIFORM_COLOR[1],_reg.UNIFORM_COLOR[2]); /* specification du buffer des positions de sommets */ glEnableVertexAttribArray(aID_position); glBindBuffer(GL_ARRAY_BUFFER, buf_pos); glVertexAttribPointer(aID_position, P_SIZE , GL_FLOAT, 0, 0, BUFFER_OFFSET(0) ); /* specification du buffer des normales de sommets */ glEnableVertexAttribArray(aID_normal); glBindBuffer(GL_ARRAY_BUFFER, buf_norm); glVertexAttribPointer(aID_normal, N_SIZE , GL_FLOAT, 0, 0, BUFFER_OFFSET(0) ); /* specification du buffer des coûts de sommets */ glEnableVertexAttribArray(aID_cost); glBindBuffer(GL_ARRAY_BUFFER, buf_cost); glVertexAttribIPointer(aID_cost, C_SIZE, GL_INT, 0, BUFFER_OFFSET(0)); /*Spécification de l'index*/ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf_index); glEnableClientState(GL_VERTEX_ARRAY); glDrawElements(GL_TRIANGLES, nbIndex, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); glDisableVertexAttribArray(aID_position); glDisableVertexAttribArray(aID_normal); glDisableVertexAttribArray(aID_cost); //On debind les VBO+IBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(aID_position); glDisableVertexAttribArray(aID_normal); glDisableVertexAttribArray(aID_cost); glUseProgram(0); }
void draw_fullscreen_quad(GLuint quad) { glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, quad); glDrawArrays(GL_TRIANGLES, 0, 6); glDisableVertexAttribArray(0); }
void IndexMap::synthesizeInfo(const Eigen::Matrix4f & pose, const std::pair<GLuint, GLuint> & model, const float depthCutoff, const float confThreshold) { glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); infoFrameBuffer.Bind(); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0, 0, infoRenderBuffer.width, infoRenderBuffer.height); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); combinedProgram->Bind(); Eigen::Matrix4f t_inv = pose.inverse(); Eigen::Vector4f cam(Intrinsics::getInstance().cx(), Intrinsics::getInstance().cy(), Intrinsics::getInstance().fx(), Intrinsics::getInstance().fy()); combinedProgram->setUniform(Uniform("t_inv", t_inv)); combinedProgram->setUniform(Uniform("cam", cam)); combinedProgram->setUniform(Uniform("maxDepth", depthCutoff)); combinedProgram->setUniform(Uniform("confThreshold", confThreshold)); combinedProgram->setUniform(Uniform("cols", (float)Resolution::getInstance().cols())); combinedProgram->setUniform(Uniform("rows", (float)Resolution::getInstance().rows())); combinedProgram->setUniform(Uniform("time", 0)); combinedProgram->setUniform(Uniform("maxTime", std::numeric_limits<int>::max())); combinedProgram->setUniform(Uniform("timeDelta", std::numeric_limits<int>::max())); glBindBuffer(GL_ARRAY_BUFFER, model.first); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, Vertex::SIZE, 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, Vertex::SIZE, reinterpret_cast<GLvoid*>(sizeof(Eigen::Vector4f) * 1)); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, Vertex::SIZE, reinterpret_cast<GLvoid*>(sizeof(Eigen::Vector4f) * 2)); glDrawTransformFeedback(GL_POINTS, model.second); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, 0); infoFrameBuffer.Unbind(); combinedProgram->Unbind(); glDisable(GL_PROGRAM_POINT_SIZE); glDisable(GL_POINT_SPRITE); glPopAttrib(); glFinish(); }
void drawLeafBezier(GLfloat t[]) { // 1. generate leaf_vertices and leaf_indices using bezier curves int n = 20; // number of segments per half Vertex a, b, c, r; a.x = leaf_bezier_root[0]; // 0 a.y = leaf_bezier_root[1]; b.x = leaf_bezier_root[5]; // 1 b.y = leaf_bezier_root[6]; c.x = leaf_bezier_root[10]; // 2 c.y = leaf_bezier_root[11]; GLfloat *leaf_bezier = new GLfloat[(n+1) * 5 * 2]; GLubyte *leaf_indicies_bezier =new GLubyte[(n) * 3 * 2]; int i; for(i = 0; i < n; i++) { double percent = (double)i/n; r.x = (1-percent*percent)*a.x + 2*percent*(1-percent)*b.x + percent*percent*c.x; r.y = (1-percent*percent)*a.y + 2*percent*(1-percent)*b.y + percent*percent*c.y; leaf_bezier[i * 5] = r.x; leaf_bezier[i * 5 + 1] = r.y; // rgb leaf_bezier[i * 5 + 2] = 0.5; leaf_bezier[i * 5 + 3] = 0.8; leaf_bezier[i * 5 + 4] = 0.3; } // ===================================== // the OTHER side of the leaf a.x = leaf_bezier_root[0]; // 0 a.y = leaf_bezier_root[1]; b.x = leaf_bezier_root[15]; // 2 b.y = leaf_bezier_root[16]; c.x = leaf_bezier_root[10]; // 3 c.y = leaf_bezier_root[11]; for(i = i; i < 2*n; i++) { double percent = 1 - (double)(i - n)/(n); r.x = (1-percent*percent)*a.x + 2*percent*(1-percent)*b.x + percent*percent*c.x; r.y = (1-percent*percent)*a.y + 2*percent*(1-percent)*b.y + percent*percent*c.y; leaf_bezier[i * 5] = r.x; leaf_bezier[i * 5 + 1] = r.y; // rgb leaf_bezier[i * 5 + 2] = 0.5; leaf_bezier[i * 5 + 3] = percent; // nice gradient effect leaf_bezier[i * 5 + 4] = 0.3; } for(int i = 0; i < (n-1) * 2; i++) { leaf_indicies_bezier[i * 3] = 0; leaf_indicies_bezier[i * 3 + 1] = i + 1; leaf_indicies_bezier[i * 3 + 2] = i + 2; } // t will be a transformation from the origin 0,0 to the current location. // Send the program to the GPU glUseProgram(program); // Now hook up input data to program. // Two attributes for the vertex, position and color. // Let OpenGL know we'll use both of them. glEnableVertexAttribArray(attribute_coord2d); glEnableVertexAttribArray(attribute_color); // Describe the position attribute and where the data is in the array glVertexAttribPointer( attribute_coord2d, // attribute ID 2, // number of elements per vertex, here (x,y) GL_FLOAT, // the type of each element GL_FALSE, // take our values as-is, don't normalize 5*sizeof(float), // stride between one position and the next leaf_bezier // pointer to first position in the C array ); // Describe the position attribute and where the data is in the array glVertexAttribPointer( attribute_color, // attribute ID 3, // number of elements per vertex, here (r,g,b) GL_FLOAT, // the type of each element GL_FALSE, // take our values as-is, don't normalize 5*sizeof(float), // stride between one position and the next leaf_bezier+2 // pointer to first position index of a color in the C array ); // give the matrix a value glUniformMatrix3fv(uniform_matrix, 1, GL_FALSE, t); // Send the triangle vertices to the GPU - actually draw! // NOTE: It's not exactly n*3*2 b/c the "right" side has (n-1)*3 triangles, // whereas the "left side" has n*3 triangles b/c it repeat the middle twice glDrawElements(GL_TRIANGLES, (n-1)*3 * 2, GL_UNSIGNED_BYTE, leaf_indicies_bezier); // Done with the attributes glDisableVertexAttribArray(attribute_coord2d); glDisableVertexAttribArray(attribute_color); free(leaf_indicies_bezier); free(leaf_bezier); }
// shade a mesh void shade_mesh(Mesh* mesh, int time) { // bind material kd, ks, n glUniform3fv(glGetUniformLocation(gl_program_id,"material_kd"), 1,&mesh->mat->kd.x); glUniform3fv(glGetUniformLocation(gl_program_id,"material_ks"), 1,&mesh->mat->ks.x); glUniform1f(glGetUniformLocation(gl_program_id,"material_n"), mesh->mat->n); glUniform1i(glGetUniformLocation(gl_program_id,"material_is_lines"), GL_FALSE); glUniform1i(glGetUniformLocation(gl_program_id,"material_double_sided"), (mesh->mat->double_sided)?GL_TRUE:GL_FALSE); // bind texture params (txt_on, sampler) _bind_texture("material_kd_txt", "material_kd_txt_on", mesh->mat->kd_txt, 0); _bind_texture("material_ks_txt", "material_ks_txt_on", mesh->mat->ks_txt, 1); _bind_texture("material_norm_txt", "material_norm_txt_on", mesh->mat->norm_txt, 2); // bind mesh frame - use frame_to_matrix glUniformMatrix4fv(glGetUniformLocation(gl_program_id,"mesh_frame"), 1,true,&frame_to_matrix(mesh->frame)[0][0]); // enable vertex attributes arrays and set up pointers to the mesh data auto vertex_pos_location = glGetAttribLocation(gl_program_id, "vertex_pos"); auto vertex_norm_location = glGetAttribLocation(gl_program_id, "vertex_norm"); auto vertex_texcoord_location = glGetAttribLocation(gl_program_id, "vertex_texcoord"); auto vertex_skin_bone_ids_location = glGetAttribLocation(gl_program_id, "vertex_skin_bone_ids"); auto vertex_skin_bone_weights_location = glGetAttribLocation(gl_program_id, "vertex_skin_bone_weights"); glEnableVertexAttribArray(vertex_pos_location); glVertexAttribPointer(vertex_pos_location, 3, GL_FLOAT, GL_FALSE, 0, &mesh->pos[0].x); glEnableVertexAttribArray(vertex_norm_location); glVertexAttribPointer(vertex_norm_location, 3, GL_FLOAT, GL_FALSE, 0, &mesh->norm[0].x); if(not mesh->texcoord.empty()) { glEnableVertexAttribArray(vertex_texcoord_location); glVertexAttribPointer(vertex_texcoord_location, 2, GL_FLOAT, GL_FALSE, 0, &mesh->texcoord[0].x); } else glVertexAttrib2f(vertex_texcoord_location, 0, 0); if (mesh->skinning and skinning_gpu) { glUniform1i(glGetUniformLocation(gl_program_id,"skinning->enabled"),GL_TRUE); glUniformMatrix4fv(glGetUniformLocation(gl_program_id,"skinning->bone_xforms"), mesh->skinning->bone_xforms[time].size(), GL_TRUE, &mesh->skinning->bone_xforms[time][0].x.x); glEnableVertexAttribArray(vertex_skin_bone_ids_location); glEnableVertexAttribArray(vertex_skin_bone_weights_location); glVertexAttribPointer(vertex_skin_bone_ids_location, 4, GL_INT, GL_FALSE, 0, mesh->skinning->bone_ids.data()); glVertexAttribPointer(vertex_skin_bone_weights_location, 4, GL_FLOAT, GL_FALSE, 0, mesh->skinning->bone_weights.data()); } else { glUniform1i(glGetUniformLocation(gl_program_id,"skinning->enabled"),GL_FALSE); } // draw triangles and quads if(draw_faces) { if(mesh->triangle.size()) glDrawElements(GL_TRIANGLES, mesh->triangle.size()*3, GL_UNSIGNED_INT, &mesh->triangle[0].x); if(mesh->quad.size()) glDrawElements(GL_QUADS, mesh->quad.size()*4, GL_UNSIGNED_INT, &mesh->quad[0].x); } if(draw_points) { if(mesh->point.size()) glDrawElements(GL_POINTS, mesh->point.size(), GL_UNSIGNED_INT, &mesh->point[0]); } if(draw_lines) { if(mesh->line.size()) glDrawElements(GL_LINES, mesh->line.size(), GL_UNSIGNED_INT, &mesh->line[0].x); for(auto segment : mesh->spline) glDrawElements(GL_LINE_STRIP, 4, GL_UNSIGNED_INT, &segment); } if(draw_edges) { auto edges = EdgeMap(mesh->triangle, mesh->quad).edges(); glDrawElements(GL_LINES, edges.size()*2, GL_UNSIGNED_INT, &edges[0].x); } // disable vertex attribute arrays glDisableVertexAttribArray(vertex_pos_location); glDisableVertexAttribArray(vertex_norm_location); if(not mesh->texcoord.empty()) glDisableVertexAttribArray(vertex_texcoord_location); if(mesh->skinning) { glDisableVertexAttribArray(vertex_skin_bone_ids_location); glDisableVertexAttribArray(vertex_skin_bone_weights_location); } // draw normals if needed if(draw_normals) { glUniform3fv(glGetUniformLocation(gl_program_id,"material_kd"), 1,&zero3f.x); glUniform3fv(glGetUniformLocation(gl_program_id,"material_ks"), 1,&zero3f.x); glBegin(GL_LINES); for(auto i : range(mesh->pos.size())) { auto p0 = mesh->pos[i]; auto p1 = mesh->pos[i] + mesh->norm[i]*0.1; glVertexAttrib3fv(0,&p0.x); glVertexAttrib3fv(0,&p1.x); if(mesh->mat->double_sided) { auto p2 = mesh->pos[i] - mesh->norm[i]*0.1; glVertexAttrib3fv(0,&p0.x); glVertexAttrib3fv(0,&p2.x); } } glEnd(); } }