mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-14 22:00:05 +00:00
33d9603e16
Use trilinear filtering instead of bilinear
255 lines
7.0 KiB
C++
255 lines
7.0 KiB
C++
#ifndef NO_OPENGL3
|
|
#include "opengl_fontstashcallbacks.h"
|
|
#include "../OpenGLWindow/GLPrimitiveRenderer.h"
|
|
#include "../OpenGLWindow/GLPrimInternalData.h"
|
|
|
|
#include "fontstash.h"
|
|
#include "../OpenGLWindow/OpenGLInclude.h"
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
|
#include "stb_image_write.h"
|
|
|
|
|
|
static unsigned int s_indexData[INDEX_COUNT];
|
|
GLuint s_indexArrayObject, s_indexBuffer;
|
|
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);
|
|
|
|
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
|
|
|