OpenGLModelData *labelSetup(float x, float y, float width, float height, float red, float green, float blue, GdkPixbuf *image) { OpenGLModelData *label; int tmp; float modelData[] = { -width/2 + x, height/2 + y, 0, // 1 width/2 + x, height/2 + y, 0, // 2 -width/2 + x, -height/2 + y, 0, // 3 width/2 + x, -height/2 + y, 0, // 4 -width/2 + x, -height/2 + y, 0, // 5 width/2 + x, height/2 + y, 0, // 6 }; float textureCoordinates[] = { 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, }; tmp = makeProgram(textVertexShaderSource, textFragmentShaderSource); if (tmp == 0) { return NULL; } label = malloc(sizeof(OpenGLModelData)); memset(label, 0, sizeof(OpenGLModelData)); label->program = (GLuint) tmp; // 2 triangles // 3 vertices per triangle // 3 vertex coordinates per vertex // 2 texture coordinates per vertex label->vboLen = 2 * 3 * 3; label->vao = drawModelSetup(modelData, label->vboLen, textureCoordinates, label->vboLen/3 * 2); label->tex = textureSetup(gdk_pixbuf_get_width(image), gdk_pixbuf_get_height(image), gdk_pixbuf_get_pixels(image)); label->uniformCount = 1; label->uniforms = malloc(label->uniformCount * sizeof(uniformVec4f)); label->uniforms[0].index = dGL.glGetUniformLocation(label->program, "textColor"); label->uniforms[0].data[0] = red; label->uniforms[0].data[1] = green; label->uniforms[0].data[2] = blue; label->uniforms[0].data[3] = 0; return label; }
static int initShaders(void){ vertex_shader = makeShader( GL_VERTEX_SHADER, "noop.v.glsl"); if (vertex_shader == 0) return 0; fragment_shader = makeShader( GL_FRAGMENT_SHADER, "noop.f.glsl"); if (fragment_shader == 0) return 0; program = makeProgram(vertex_shader, fragment_shader); if (program == 0) return 0; glUseProgram(program); }
int myprogrammer::makeAndManageProgram(char* vpath, char* fpath) { unsigned int program; shaderInfo info; info.v = makeVertexShader(vpath,NULL); info.f = makeFragmentShader(fpath,NULL); program = makeProgram(info.v, info.f); char eyeposname[] = "eyepos"; info.leyepos = glGetUniformLocation (program, eyeposname); char texname[] = "tex"; info.ltex = glGetUniformLocation(program, texname); if(program > 0) programs[program] = info; return program; }
ParticlesPainter::ParticlesPainter(FluidSolver* solver, float ptSize) : _ptSize(ptSize), _particles(&solver->_particles) { MAX_PARTICLES = (unsigned int) _particles->size(); // compile shaders GLuint particleVert = compileShader(particle_vert, GL_VERTEX_SHADER); GLuint particleFrag = compileShader(particle_frag, GL_FRAGMENT_SHADER); std::vector<GLuint> programs = {particleVert, particleFrag}; prog = makeProgram(programs); // setup shader locations unifViewProj = glGetUniformLocation(prog, "u_viewProj"); attrPos = glGetAttribLocation(prog, "v_pos"); attrVel = glGetAttribLocation(prog, "v_vel"); attrCol = glGetAttribLocation(prog, "v_col"); // make a buffer for the particles glGenBuffers(1, &particle_buffer); glBindBuffer(GL_ARRAY_BUFFER, particle_buffer); glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES * sizeof(FluidParticle), NULL, GL_STREAM_DRAW); }
void setup(RenderData *rd) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_Init(SDL_INIT_EVERYTHING); SDL_Renderer* displayRenderer; SDL_RendererInfo displayRendererInfo; SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, SDL_WINDOW_OPENGL, &window, &displayRenderer); SDL_GetRendererInfo(displayRenderer, &displayRendererInfo); glEnable(GL_DEPTH_TEST); glClearColor( 0.1, 0.1, 0.1, 1.0 ); glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, WIDTH, HEIGHT); makeProgram(rd); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); rd->vSync = SDL_GL_SetSwapInterval(1); }
int main(int argc, char ** argv) { auto pathToRom = std::string(); if (argc == 2) { pathToRom = argv[1]; } else { printf("Chip8 Error: Wrong number of arguments\n"); return -1; } sf::SoundBuffer beepSnd; if (! beepSnd.loadFromFile("data/sounds/beep.wav")) { printf("Chip8 Error: Can't load the beeping sound.\n"); return -1; } sf::Sound sndSrc; sndSrc.setBuffer(beepSnd); sndSrc.setLoop(false); auto window = setupWindow(WIDTH, HEIGHT, TITLE); cee::Chip8 chip; chip.loadProgram(readAllBytes(pathToRom.c_str())); constexpr GLfloat pxVerts[] = { -1.0f, 1.0f, 0.0f, // Top Left 1.0f, 1.0f, 0.0f, // Top Right -1.0f, -1.0f, 0.0f, // Bottom Left 1.0f, -1.0f, 0.0f // Bottom Right }; constexpr GLuint pxIndices[] = { 0, 1, 2, 2, 1, 3 }; // Initialize the VAO and other buffers associated // with drawing an emulated pixel. GLuint vao, vbo, ibo; glGenVertexArrays(1, &vao); glBindVertexArray(vao); { glGenBuffers(1, &vbo); glGenBuffers(1, &ibo); // VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(pxVerts), &pxVerts, GL_STATIC_DRAW); // IBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(pxIndices), &pxIndices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); } glBindVertexArray(0); // Current Vertex Shader const auto pxVertexSrc = readAllChars("data/shaders/px_vertex.glsl"); const auto pxVertex = makeShader(GL_VERTEX_SHADER, pxVertexSrc); // Current Fragment Shader const auto pxFragmentSrc = readAllChars("data/shaders/px_fragment.glsl"); const auto pxFragment = makeShader(GL_FRAGMENT_SHADER, pxFragmentSrc); // Current Shader Program const auto pxProgram = makeProgram({pxVertex, pxFragment}); glUseProgram(pxProgram); glfwShowWindow(window); while (! glfwWindowShouldClose(window)) { chip.updateKeys(getKeyStates(window)); chip.updateCycle(); if (chip.isBeeping() && sndSrc.getStatus() != sf::SoundSource::Playing) sndSrc.play(); // Clear back buffer and background color. glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glBindVertexArray(vao); const auto gfx = chip.getGfx(); for (int i = 0; i < 32; ++i) { // Maps the width resolution [0-HEIGHT] to [-1.0-1.0] auto y = - mapRangeHeight(i); auto l = i * 64; for (int j = 0; j < 64; ++j) { if (gfx[l + j] == 1) { // Maps the width resolution [0-WIDTH] to [-1.0-1.0] auto x = mapRangeWidth(j); auto ident = glGetUniformLocation(pxProgram, "PxModel"); auto model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(x, y, 0.0f)); model = glm::scale(model, glm::vec3(PX_WIDTH, PX_HEIGHT, 1.0f)); glUniformMatrix4fv(ident, 1, GL_FALSE, glm::value_ptr(model)); glDrawElements(GL_TRIANGLES, sizeof(pxIndices), GL_UNSIGNED_INT, nullptr); } } } glBindVertexArray(0); glfwSwapBuffers(window); glfwPollEvents(); } // Cleanup resources glDeleteProgram(pxProgram); glDeleteShader(pxVertex); glDeleteShader(pxFragment); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &ibo); glDeleteBuffers(1, &vbo); glfwTerminate(); return 0; }
void atInitialize_02_cube(void** ppAppData, const char* const args) { GLuint texture = 0; GLenum target; GLenum glerror; GLboolean isMipmapped; GLuint gnDecalFs, gnVs; GLsizeiptr offset; KTX_error_code ktxerror; CubeTextured* pData = (CubeTextured*)atMalloc(sizeof(CubeTextured), 0); atAssert(pData); atAssert(ppAppData); *ppAppData = pData; pData->bInitialized = GL_FALSE; pData->gnTexture = 0; ktxerror = ktxLoadTextureN(args, &texture, &target, NULL, &isMipmapped, &glerror, 0, NULL); if (KTX_SUCCESS == ktxerror) { if (target != GL_TEXTURE_2D) { /* Can only draw 2D textures */ glDeleteTextures(1, &texture); return; } if (isMipmapped) /* Enable bilinear mipmapping */ /* TO DO: application can consider inserting a key,value pair in the KTX * file that indicates what type of filtering to use. */ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); atAssert(GL_NO_ERROR == glGetError()); } else { char message[1024]; int maxchars = sizeof(message)/sizeof(char); int nchars; nchars = snprintf(message, maxchars, "Load of texture \"%s\" failed: %s.", args, ktxErrorString(ktxerror)); if (ktxerror == KTX_GL_ERROR) { maxchars -= nchars; nchars += snprintf(&message[nchars], maxchars, " GL error is %#x.", glerror); } atMessageBox(message, "Texture load failed", AT_MB_OK|AT_MB_ICONERROR); } /* By default dithering is enabled. Dithering does not provide visual improvement * in this sample so disable it to improve performance. */ glDisable(GL_DITHER); glEnable(GL_CULL_FACE); glClearColor(0.2f,0.3f,0.4f,1.0f); // Create a VAO and bind it. glGenVertexArrays(1, &pData->gnVao); glBindVertexArray(pData->gnVao); // Must have vertex data in buffer objects to use VAO's on ES3/GL Core glGenBuffers(1, &pData->gnVbo); glBindBuffer(GL_ARRAY_BUFFER, pData->gnVbo); // Must be done after the VAO is bound // Use the same buffer for vertex attributes and element indices. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pData->gnVbo); // Create the buffer data store. glBufferData(GL_ARRAY_BUFFER, sizeof(cube_face) + sizeof(cube_color) + sizeof(cube_texture) + sizeof(cube_normal) + sizeof(cube_index_buffer), NULL, GL_STATIC_DRAW); // Interleave data copying and attrib pointer setup so offset is only computed once. glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_face), cube_face); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_face); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_color), cube_color); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_color); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_texture), cube_texture); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_texture); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_normal), cube_normal); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_normal); pData->iIndicesOffset = offset; // Either of the following can be used to buffer the data. glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_index_buffer), cube_index_buffer); //glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, sizeof(cube_index_buffer), cube_index_buffer); if (makeShader(GL_VERTEX_SHADER, pszVs, &gnVs)) { if (makeShader(GL_FRAGMENT_SHADER, pszDecalFs, &gnDecalFs)) { if (makeProgram(gnVs, gnDecalFs, &pData->gnTexProg)) { pData->gulMvMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "mvmatrix"); pData->gulPMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "pmatrix"); pData->gulSamplerLocTP = glGetUniformLocation(pData->gnTexProg, "sampler"); glUseProgram(pData->gnTexProg); // We're using the default texture unit 0 glUniform1i(pData->gulSamplerLocTP, 0); } } glDeleteShader(gnVs); glDeleteShader(gnDecalFs); } atAssert(GL_NO_ERROR == glGetError()); pData->bInitialized = GL_TRUE; }
void SetupRC() { SpriteManager *sprites = SpriteManager::instance(); Vector p(0.0f,0.0f,-1.0f); player = new Player("resources/Models/cube.ogl", p); sprites->AddSprite( player); std::string filename="resources/Models/cube.ogl"; test = new Model(filename); /* Vector v((GLfloat)(0), (GLfloat)(0), (GLfloat) (5) ); sprites->AddSprite( new Sprite("resources/Models/cube.ogl", v) ); */ for (int i=0; i<30; i++) { Vector v((GLfloat)(0), (GLfloat)(i *3 ), (GLfloat) (10) ); sprites->AddSprite( new Sprite("resources/Models/cube.ogl", v, i*8, i*2, i*5) ); } glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); shader.vertexShader = makeShader( GL_VERTEX_SHADER, "resources/Shaders/identity.vs"); if(shader.vertexShader == 0){ printf("failed to make vertex shader"); exit(0); } shader.fragmentShader = makeShader(GL_FRAGMENT_SHADER, "resources/Shaders/identity.fs"); if(shader.fragmentShader == 0){ printf("failed to make fragment shader"); exit(0); } shader.program = makeProgram(shader.vertexShader, shader.fragmentShader); if(shader.program == 0){ printf("failed to make program"); exit(0); } shader.uniforms.colour = glGetUniformLocation( shader.program, "colour"); if( shader.uniforms.colour == -1){ printf( "failed to locate uniform colour location"); exit(0); } shader.uniforms.modelViewProjectionMatrix = glGetUniformLocation(shader.program, "modelViewProjectionMatrix"); if( shader.uniforms.modelViewProjectionMatrix == -1){ printf("failed to locate uniform modelViewProjectionMatrix"); exit(0); } shader.attributes.pos = glGetAttribLocation( shader.program, "position"); }
DrawTexture::DrawTexture(uint32_t width, uint32_t height, const char* const szArgs, const std::string sBasePath) : GL3LoadTestSample(width, height, szArgs, sBasePath) { std::string filename; GLfloat* pfQuadTexCoords = quad_texture; GLfloat fTmpTexCoords[sizeof(quad_texture)/sizeof(GLfloat)]; GLenum target; GLboolean isMipmapped; GLenum glerror; GLubyte* pKvData; GLuint kvDataLen; GLint sign_s = 1, sign_t = 1; GLint i; GLuint gnColorFs, gnDecalFs, gnVs; GLsizeiptr offset; KTX_dimensions dimensions; KTX_error_code ktxresult; KTX_hash_table kvtable; bInitialized = false; gnTexture = 0; filename = getAssetPath() + szArgs; ktxresult = ktxLoadTextureN(filename.c_str(), &gnTexture, &target, &dimensions, &isMipmapped, &glerror, &kvDataLen, &pKvData); if (KTX_SUCCESS == ktxresult) { ktxresult = ktxHashTable_Deserialize(kvDataLen, pKvData, &kvtable); if (KTX_SUCCESS == ktxresult) { GLchar* pValue; GLuint valueLen; if (KTX_SUCCESS == ktxHashTable_FindValue(kvtable, KTX_ORIENTATION_KEY, &valueLen, (void**)&pValue)) { char s, t; if (sscanf(pValue, /*valueLen,*/ KTX_ORIENTATION2_FMT, &s, &t) == 2) { if (s == 'l') sign_s = -1; if (t == 'd') sign_t = -1; } } ktxHashTable_Destroy(kvtable); free(pKvData); } if (sign_s < 0 || sign_t < 0) { // Transform the texture coordinates to get correct image // orientation. int iNumCoords = sizeof(quad_texture) / sizeof(float); for (i = 0; i < iNumCoords; i++) { fTmpTexCoords[i] = quad_texture[i]; if (i & 1) { // odd, i.e. a y coordinate if (sign_t < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } else { // an x coordinate if (sign_s < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } } pfQuadTexCoords = fTmpTexCoords; } uTexWidth = dimensions.width; uTexHeight = dimensions.height; if (isMipmapped) // Enable bilinear mipmapping. // TO DO: application can consider inserting a key,value pair in // the KTX file that indicates what type of filtering to use. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); assert(GL_NO_ERROR == glGetError()); } else { std::stringstream message; message << "Load of texture from \"" << filename << "\" failed: "; if (ktxresult == KTX_GL_ERROR) { message << std::showbase << "GL error " << std::hex << glerror << " occurred."; } else { message << ktxErrorString(ktxresult); } throw std::runtime_error(message.str()); } glClearColor(0.4f, 0.4f, 0.5f, 1.0f); // Must have vertex data in buffer objects to use VAO's on ES3/GL Core glGenBuffers(1, &gnVbo); glBindBuffer(GL_ARRAY_BUFFER, gnVbo); // Create the buffer data store glBufferData(GL_ARRAY_BUFFER, sizeof(frame_position) + sizeof(frame_color) + sizeof(quad_position) + sizeof(quad_color) + sizeof(quad_texture), NULL, GL_STATIC_DRAW); glGenVertexArrays(2, gnVaos); // Interleave data copying and attrib pointer setup so offset is only // computed once. // Setup VAO and buffer the data for frame glBindVertexArray(gnVaos[FRAME]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_position), frame_position); glVertexAttribPointer(0, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_color), frame_color); glVertexAttribPointer(1, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_color); // Setup VAO for quad glBindVertexArray(gnVaos[QUAD]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_position), quad_position); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_color), quad_color); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_color); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_texture), pfQuadTexCoords); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); glBindVertexArray(0); try { makeShader(GL_VERTEX_SHADER, pszVs, &gnVs); makeShader(GL_FRAGMENT_SHADER, pszColorFs, &gnColorFs); makeProgram(gnVs, gnColorFs, &gnColProg); gulMvMatrixLocCP = glGetUniformLocation(gnColProg, "mvmatrix"); gulPMatrixLocCP = glGetUniformLocation(gnColProg, "pmatrix"); makeShader(GL_FRAGMENT_SHADER, pszDecalFs, &gnDecalFs); makeProgram(gnVs, gnDecalFs, &gnTexProg); } catch (std::exception& e) { (void)e; // To quiet unused variable warnings from some compilers. throw; } gulMvMatrixLocTP = glGetUniformLocation(gnTexProg, "mvmatrix"); gulPMatrixLocTP = glGetUniformLocation(gnTexProg, "pmatrix"); gulSamplerLocTP = glGetUniformLocation(gnTexProg, "sampler"); glUseProgram(gnTexProg); // We're using the default texture unit 0 glUniform1i(gulSamplerLocTP, 0); glDeleteShader(gnVs); glDeleteShader(gnColorFs); glDeleteShader(gnDecalFs); // Set the quad's mv matrix to scale by the texture size. // With the pixel-mapping ortho projection set below, the texture will // be rendered at actual size just like DrawTex*OES. quadMvMatrix = glm::scale(glm::mat4(), glm::vec3((float)uTexWidth / 2, (float)uTexHeight / 2, 1)); assert(GL_NO_ERROR == glGetError()); bInitialized = true; }
OpenGLModelData *cubeSetup(GdkPixbuf *image) { OpenGLModelData *cube; float d = 1; int tmp; float modelData[] = { -d / 2, d / 2, -d / 2, // 1 d / 2, d / 2, -d / 2, // 2 -d / 2, -d / 2, -d / 2, // 3 d / 2, -d / 2, -d / 2, // 4 -d / 2, -d / 2, -d / 2, // 5 d / 2, d / 2, -d / 2, // 6 -d / 2, d / 2, d / 2, // 7 -d / 2, d / 2, -d / 2, // 8 -d / 2, -d / 2, d / 2, // 9 -d / 2, -d / 2, -d / 2, // 10 -d / 2, -d / 2, d / 2, // 11 -d / 2, d / 2, -d / 2, // 12 -d / 2, d / 2, d / 2, // 13 d / 2, d / 2, d / 2, // 14 -d / 2, d / 2, -d / 2, // 15 d / 2, d / 2, -d / 2, // 16 -d / 2, d / 2, -d / 2, // 17 d / 2, d / 2, d / 2, // 18 d / 2, d / 2, -d / 2, // 19 d / 2, d / 2, d / 2, // 20 d / 2, -d / 2, -d / 2, // 21 d / 2, -d / 2, d / 2, // 22 d / 2, -d / 2, -d / 2, // 23 d / 2, d / 2, d / 2, // 24 -d / 2, -d / 2, -d / 2, // 25 d / 2, -d / 2, -d / 2, // 26 -d / 2, -d / 2, d / 2, // 27 d / 2, -d / 2, d / 2, // 28 -d / 2, -d / 2, d / 2, // 29 d / 2, -d / 2, -d / 2, // 30 d / 2, d / 2, d / 2, // 31 -d / 2, d / 2, d / 2, // 32 d / 2, -d / 2, d / 2, // 33 -d / 2, -d / 2, d / 2, // 34 d / 2, -d / 2, d / 2, // 35 -d / 2, d / 2, d / 2, // 36 }; float textureCoordinates[] = { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, }; tmp = makeProgram(cubeVertexShaderSource, cubeFragmentShaderSource); if (tmp == 0) { return NULL; } cube = malloc(sizeof(OpenGLModelData)); memset(cube, 0, sizeof(OpenGLModelData)); cube->program = (GLuint) tmp; // 6 sides in a cube // 2 triangles per side // 3 vertices per triangle // 3 vertex coordinates per vertex // 2 texture coordinates per vertex cube->vboLen = 6 * 2 * 3 * 3; cube->vao = drawModelSetup(modelData, cube->vboLen, textureCoordinates, cube->vboLen / 3 * 2); cube->tex = textureSetup(gdk_pixbuf_get_width(image), gdk_pixbuf_get_height(image), gdk_pixbuf_get_pixels(image)); cube->mvp = malloc(16 * sizeof(float)); genIdentityMatrix(cube->mvp); return cube; }
void atInitialize_01_draw_texture(void** ppAppData, const char* const szArgs, const char* const szBasePath) { const char* filename; GLfloat* pfQuadTexCoords = quad_texture; GLfloat fTmpTexCoords[sizeof(quad_texture)/sizeof(GLfloat)]; GLuint texture = 0; GLenum target; GLboolean isMipmapped; GLenum glerror; GLubyte* pKvData; GLuint kvDataLen; GLint sign_s = 1, sign_t = 1; GLint i; GLuint gnColorFs, gnDecalFs, gnVs; GLsizeiptr offset; KTX_dimensions dimensions; KTX_error_code ktxerror; KTX_hash_table kvtable; DrawTexture* pData = (DrawTexture*)atMalloc(sizeof(DrawTexture), 0); atAssert(pData); atAssert(ppAppData); *ppAppData = pData; pData->bInitialized = GL_FALSE; pData->gnTexture = 0; filename = atStrCat(szBasePath, szArgs); if (filename != NULL) { ktxerror = ktxLoadTextureN(filename, &pData->gnTexture, &target, &dimensions, &isMipmapped, &glerror, &kvDataLen, &pKvData); if (KTX_SUCCESS == ktxerror) { ktxerror = ktxHashTable_Deserialize(kvDataLen, pKvData, &kvtable); if (KTX_SUCCESS == ktxerror) { GLchar* pValue; GLuint valueLen; if (KTX_SUCCESS == ktxHashTable_FindValue(kvtable, KTX_ORIENTATION_KEY, &valueLen, (void**)&pValue)) { char s, t; if (sscanf(pValue, /*valueLen,*/ KTX_ORIENTATION2_FMT, &s, &t) == 2) { if (s == 'l') sign_s = -1; if (t == 'd') sign_t = -1; } } ktxHashTable_Destroy(kvtable); free(pKvData); } if (sign_s < 0 || sign_t < 0) { // Transform the texture coordinates to get correct image orientation. int iNumCoords = sizeof(quad_texture) / sizeof(float); for (i = 0; i < iNumCoords; i++) { fTmpTexCoords[i] = quad_texture[i]; if (i & 1) { // odd, i.e. a y coordinate if (sign_t < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } else { // an x coordinate if (sign_s < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } } pfQuadTexCoords = fTmpTexCoords; } pData->iTexWidth = dimensions.width; pData->iTexHeight = dimensions.height; if (isMipmapped) /* Enable bilinear mipmapping */ /* TO DO: application can consider inserting a key,value pair in the KTX * that indicates what type of filtering to use. */ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); atAssert(GL_NO_ERROR == glGetError()); } else { char message[1024]; int maxchars = sizeof(message)/sizeof(char); int nchars; nchars = snprintf(message, maxchars, "Load of texture \"%s\" failed: ", filename); maxchars -= nchars; if (ktxerror == KTX_GL_ERROR) { nchars += snprintf(&message[nchars], maxchars, "GL error %#x occurred.", glerror); } else { nchars += snprintf(&message[nchars], maxchars, "%s.", ktxErrorString(ktxerror)); } atMessageBox(message, "Texture load failed", AT_MB_OK|AT_MB_ICONERROR); pData->iTexWidth = pData->iTexHeight = 50; pData->gnTexture = 0; } atFree((void*)filename, NULL); } /* else Out of memory. In which case, a message box is unlikely to work. */ glClearColor(0.4f, 0.4f, 0.5f, 1.0f); // Must have vertex data in buffer objects to use VAO's on ES3/GL Core glGenBuffers(1, &pData->gnVbo); glBindBuffer(GL_ARRAY_BUFFER, pData->gnVbo); // Create the buffer data store glBufferData(GL_ARRAY_BUFFER, sizeof(frame_position) + sizeof(frame_color) + sizeof(quad_position) + sizeof(quad_color) + sizeof(quad_texture), NULL, GL_STATIC_DRAW); glGenVertexArrays(2, pData->gnVaos); // Interleave data copying and attrib pointer setup so offset is only computed once. // Setup VAO and buffer the data for frame glBindVertexArray(pData->gnVaos[FRAME]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_position), frame_position); glVertexAttribPointer(0, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_color), frame_color); glVertexAttribPointer(1, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_color); // Setup VAO for quad glBindVertexArray(pData->gnVaos[QUAD]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_position), quad_position); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_color), quad_color); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_color); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_texture), pfQuadTexCoords); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); glBindVertexArray(0); if (makeShader(GL_VERTEX_SHADER, pszVs, &gnVs)) { if (makeShader(GL_FRAGMENT_SHADER, pszColorFs, &gnColorFs)) { if (makeProgram(gnVs, gnColorFs, &pData->gnColProg)) { pData->gulMvMatrixLocCP = glGetUniformLocation(pData->gnColProg, "mvmatrix"); pData->gulPMatrixLocCP = glGetUniformLocation(pData->gnColProg, "pmatrix"); } } if (makeShader(GL_FRAGMENT_SHADER, pszDecalFs, &gnDecalFs)) { if (makeProgram(gnVs, gnDecalFs, &pData->gnTexProg)) { pData->gulMvMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "mvmatrix"); pData->gulPMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "pmatrix"); pData->gulSamplerLocTP = glGetUniformLocation(pData->gnTexProg, "sampler"); glUseProgram(pData->gnTexProg); // We're using the default texture unit 0 glUniform1i(pData->gulSamplerLocTP, 0); } } glDeleteShader(gnVs); glDeleteShader(gnColorFs); glDeleteShader(gnDecalFs); } // Set the quad's mv matrix to scale by the texture size. // With the pixel-mapping ortho projection set below, the texture will // be rendered at actual size just like DrawTex*OES. for (i = 0; i < 16; i++) { pData->fQuadMvMatrix[i] = atIdentity[i]; pData->fFrameMvMatrix[i] = atIdentity[i]; } pData->fQuadMvMatrix[0*4 + 0] = (float)pData->iTexWidth / 2; pData->fQuadMvMatrix[1*4 + 1] = (float)pData->iTexHeight / 2; atAssert(GL_NO_ERROR == glGetError()); pData->bInitialized = GL_TRUE; }