#ifndef NO_OPENGL3 #include "opengl_fontstashcallbacks.h" #include "../OpenGLWindow/GLPrimitiveRenderer.h" #include "../OpenGLWindow/GLPrimInternalData.h" #include "fontstash.h" #include "../OpenGLWindow/OpenGLInclude.h" #include #include #include #include #include "stb_image/stb_image_write.h" static unsigned int s_indexData[INDEX_COUNT]; static GLuint s_indexArrayObject, s_indexBuffer; static GLuint s_vertexArrayObject, s_vertexBuffer; OpenGL2RenderCallbacks::OpenGL2RenderCallbacks(GLPrimitiveRenderer* primRender) : m_primRender2(primRender) { } OpenGL2RenderCallbacks::~OpenGL2RenderCallbacks() { } PrimInternalData* OpenGL2RenderCallbacks::getData() { return m_primRender2->getData(); } InternalOpenGL2RenderCallbacks::~InternalOpenGL2RenderCallbacks() { } void InternalOpenGL2RenderCallbacks::display2() { assert(glGetError() == GL_NO_ERROR); // glViewport(0,0,10,10); //const float timeScale = 0.008f; PrimInternalData* data = getData(); glUseProgram(data->m_shaderProg); glBindBuffer(GL_ARRAY_BUFFER, s_vertexBuffer); glBindVertexArray(s_vertexArrayObject); assert(glGetError() == GL_NO_ERROR); // glBindTexture(GL_TEXTURE_2D,m_texturehandle); assert(glGetError() == GL_NO_ERROR); float identity[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; glUniformMatrix4fv(data->m_viewmatUniform, 1, false, identity); glUniformMatrix4fv(data->m_projMatUniform, 1, false, identity); vec2 p(0.f, 0.f); //?b?0.5f * sinf(timeValue), 0.5f * cosf(timeValue) ); glUniform2fv(data->m_positionUniform, 1, (const GLfloat*)&p); assert(glGetError() == GL_NO_ERROR); glEnableVertexAttribArray(data->m_positionAttribute); assert(glGetError() == GL_NO_ERROR); glEnableVertexAttribArray(data->m_colourAttribute); assert(glGetError() == GL_NO_ERROR); glEnableVertexAttribArray(data->m_textureAttribute); glVertexAttribPointer(data->m_positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)0); glVertexAttribPointer(data->m_colourAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)sizeof(vec4)); glVertexAttribPointer(data->m_textureAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(sizeof(vec4) + sizeof(vec4))); assert(glGetError() == GL_NO_ERROR); /* glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer); //glDrawArrays(GL_TRIANGLE_FAN, 0, 4); int indexCount = 6; err = glGetError(); assert(err==GL_NO_ERROR); glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0); err = glGetError(); assert(err==GL_NO_ERROR); */ // glutSwapBuffers(); } void InternalOpenGL2RenderCallbacks::updateTexture(sth_texture* texture, sth_glyph* glyph, int textureWidth, int textureHeight) { assert(glGetError() == GL_NO_ERROR); if (glyph) { // Update texture (entire texture, could use glyph to update partial texture using glTexSubImage2D) GLuint* gltexture = (GLuint*)texture->m_userData; glBindTexture(GL_TEXTURE_2D, *gltexture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); assert(glGetError() == GL_NO_ERROR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, textureWidth, textureHeight, 0, GL_RED, GL_UNSIGNED_BYTE, texture->m_texels); assert(glGetError() == GL_NO_ERROR); } else { if (textureWidth && textureHeight) { GLuint* texId = new GLuint; texture->m_userData = texId; //create new texture glGenTextures(1, texId); assert(glGetError() == GL_NO_ERROR); glBindTexture(GL_TEXTURE_2D, *texId); texture->m_texels = (unsigned char*)malloc(textureWidth * textureHeight); memset(texture->m_texels, 0, textureWidth * textureHeight); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, textureWidth, textureHeight, 0, GL_RED, GL_UNSIGNED_BYTE, texture->m_texels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); assert(glGetError() == GL_NO_ERROR); //////////////////////////// //create the other data { glGenVertexArrays(1, &s_vertexArrayObject); glBindVertexArray(s_vertexArrayObject); glGenBuffers(1, &s_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, s_vertexBuffer); glBufferData(GL_ARRAY_BUFFER, VERT_COUNT * sizeof(Vertex), texture->newverts, GL_DYNAMIC_DRAW); assert(glGetError() == GL_NO_ERROR); for (int i = 0; i < INDEX_COUNT; i++) { s_indexData[i] = i; } glGenBuffers(1, &s_indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDEX_COUNT * sizeof(int), s_indexData, GL_STATIC_DRAW); assert(glGetError() == GL_NO_ERROR); } } else { //delete texture if (texture->m_userData) { GLuint* id = (GLuint*)texture->m_userData; glDeleteTextures(1, id); //delete id; delete id; //texture->m_userData; texture->m_userData = 0; } } } } void InternalOpenGL2RenderCallbacks::render(sth_texture* texture) { display2(); GLuint* texId = (GLuint*)texture->m_userData; assert(glGetError() == GL_NO_ERROR); glActiveTexture(GL_TEXTURE0); assert(glGetError() == GL_NO_ERROR); glBindTexture(GL_TEXTURE_2D, *texId); bool useFiltering = false; if (useFiltering) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } assert(glGetError() == GL_NO_ERROR); glBindBuffer(GL_ARRAY_BUFFER, s_vertexBuffer); glBindVertexArray(s_vertexArrayObject); glBufferData(GL_ARRAY_BUFFER, texture->nverts * sizeof(Vertex), &texture->newverts[0].position.p[0], GL_DYNAMIC_DRAW); assert(glGetError() == GL_NO_ERROR); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_indexBuffer); //glDrawArrays(GL_TRIANGLE_FAN, 0, 4); int indexCount = texture->nverts; assert(glGetError() == GL_NO_ERROR); glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0); assert(glGetError() == GL_NO_ERROR); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // glDisableVertexAttribArray(m_textureAttribute); glUseProgram(0); } void dumpTextureToPng(int textureWidth, int textureHeight, const char* fileName) { glPixelStorei(GL_PACK_ALIGNMENT, 1); unsigned char* pixels = (unsigned char*)malloc(textureWidth * textureHeight); glReadPixels(0, 0, textureWidth, textureHeight, GL_RED, GL_UNSIGNED_BYTE, pixels); //swap the pixels unsigned char* tmp = (unsigned char*)malloc(textureWidth); for (int j = 0; j < textureHeight; j++) { pixels[j * textureWidth + j] = 255; } if (0) { for (int j = 0; j < textureHeight / 2; j++) { for (int i = 0; i < textureWidth; i++) { tmp[i] = pixels[j * textureWidth + i]; pixels[j * textureWidth + i] = pixels[(textureHeight - j - 1) * textureWidth + i]; pixels[(textureHeight - j - 1) * textureWidth + i] = tmp[i]; } } } int comp = 1; //1=Y stbi_write_png(fileName, textureWidth, textureHeight, comp, pixels, textureWidth); free(pixels); } #endif