mirror of https://github.com/encounter/SDL.git
GLES2: Get sin/cos out of vertex shader
The only place angle is activated and causes effect is RenderCopyEx. All other methods which use vertex shader, leave angle disabled and cause useless sin/cos calculation in shader. To get around shader's interface is changed to a vector that contains results of sin and cos. To behave properly when disabled, cos value is set with offset -1.0 making 0.0 default when deactivated. As nice side effect it simplifies GLES2_UpdateVertexBuffer: All attributes are vectors now. Additional background: * On RaspberryPi it gives a performace win for operations. Tested with [1] numbers go down for 5-10% (not easy to estimate due to huge variation). * SDL_RenderCopyEx was tested with [2] * It works around left rotated display caused by low accuracy sin implemetation in RaspberryPi/VC4 [3] [1] https://github.com/schnitzeltony/sdl2box [2] https://github.com/schnitzeltony/sdl2rendercopyex [3] https://github.com/anholt/mesa/issues/110 Signed-off-by: Andreas M?ller <schnitzeltony@gmail.com>
This commit is contained in:
parent
044b00dcae
commit
87bc1fb552
|
@ -1534,7 +1534,7 @@ GLES2_UpdateVertexBuffer(SDL_Renderer *renderer, GLES2_Attribute attr,
|
||||||
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
||||||
|
|
||||||
#if !SDL_GLES2_USE_VBOS
|
#if !SDL_GLES2_USE_VBOS
|
||||||
data->glVertexAttribPointer(attr, attr == GLES2_ATTRIBUTE_ANGLE ? 1 : 2, GL_FLOAT, GL_FALSE, 0, vertexData);
|
data->glVertexAttribPointer(attr, 2, GL_FLOAT, GL_FALSE, 0, vertexData);
|
||||||
#else
|
#else
|
||||||
if (!data->vertex_buffers[attr]) {
|
if (!data->vertex_buffers[attr]) {
|
||||||
data->glGenBuffers(1, &data->vertex_buffers[attr]);
|
data->glGenBuffers(1, &data->vertex_buffers[attr]);
|
||||||
|
@ -1549,7 +1549,7 @@ GLES2_UpdateVertexBuffer(SDL_Renderer *renderer, GLES2_Attribute attr,
|
||||||
data->glBufferSubData(GL_ARRAY_BUFFER, 0, dataSizeInBytes, vertexData);
|
data->glBufferSubData(GL_ARRAY_BUFFER, 0, dataSizeInBytes, vertexData);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->glVertexAttribPointer(attr, attr == GLES2_ATTRIBUTE_ANGLE ? 1 : 2, GL_FLOAT, GL_FALSE, 0, 0);
|
data->glVertexAttribPointer(attr, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1857,6 +1857,8 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
|
||||||
return GL_CheckError("", renderer);
|
return GL_CheckError("", renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PI 3.14159265f
|
||||||
|
|
||||||
static int
|
static int
|
||||||
GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
|
GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
|
||||||
const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||||
|
@ -1865,8 +1867,9 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
|
||||||
GLfloat vertices[8];
|
GLfloat vertices[8];
|
||||||
GLfloat texCoords[8];
|
GLfloat texCoords[8];
|
||||||
GLfloat translate[8];
|
GLfloat translate[8];
|
||||||
GLfloat fAngle[4];
|
GLfloat fAngle[8];
|
||||||
GLfloat tmp;
|
GLfloat tmp;
|
||||||
|
float radian_angle;
|
||||||
|
|
||||||
GLES2_ActivateRenderer(renderer);
|
GLES2_ActivateRenderer(renderer);
|
||||||
|
|
||||||
|
@ -1876,7 +1879,11 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
|
||||||
|
|
||||||
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
|
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
|
||||||
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
|
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
|
||||||
fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (GLfloat)(360.0f - angle);
|
|
||||||
|
radian_angle = PI * (360.0f - angle) / 180.f;
|
||||||
|
fAngle[0] = fAngle[2] = fAngle[4] = fAngle[6] = (GLfloat)sin(radian_angle);
|
||||||
|
/* render expects cos value - 1 (see GLES2_VertexSrc_Default_) */
|
||||||
|
fAngle[1] = fAngle[3] = fAngle[5] = fAngle[7] = (GLfloat)cos(radian_angle) - 1.0f;
|
||||||
/* Calculate the center of rotation */
|
/* Calculate the center of rotation */
|
||||||
translate[0] = translate[2] = translate[4] = translate[6] = (center->x + dstrect->x);
|
translate[0] = translate[2] = translate[4] = translate[6] = (center->x + dstrect->x);
|
||||||
translate[1] = translate[3] = translate[5] = translate[7] = (center->y + dstrect->y);
|
translate[1] = translate[3] = translate[5] = translate[7] = (center->y + dstrect->y);
|
||||||
|
@ -1905,7 +1912,7 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
|
||||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, translate);
|
data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, translate);
|
||||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);*/
|
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);*/
|
||||||
|
|
||||||
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_ANGLE, fAngle, 4 * sizeof(GLfloat));
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_ANGLE, fAngle, 8 * sizeof(GLfloat));
|
||||||
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_CENTER, translate, 8 * sizeof(GLfloat));
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_CENTER, translate, 8 * sizeof(GLfloat));
|
||||||
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 * sizeof(GLfloat));
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 * sizeof(GLfloat));
|
||||||
|
|
||||||
|
|
|
@ -30,20 +30,24 @@
|
||||||
/*************************************************************************************************
|
/*************************************************************************************************
|
||||||
* Vertex/fragment shader source *
|
* Vertex/fragment shader source *
|
||||||
*************************************************************************************************/
|
*************************************************************************************************/
|
||||||
|
/* Notes on a_angle:
|
||||||
|
* It is a vector containing sin and cos for rotation matrix
|
||||||
|
* To get correct rotation for most cases when a_angle is disabled cos
|
||||||
|
value is decremented by 1.0 to get proper output with 0.0 which is
|
||||||
|
default value
|
||||||
|
*/
|
||||||
static const Uint8 GLES2_VertexSrc_Default_[] = " \
|
static const Uint8 GLES2_VertexSrc_Default_[] = " \
|
||||||
uniform mat4 u_projection; \
|
uniform mat4 u_projection; \
|
||||||
attribute vec2 a_position; \
|
attribute vec2 a_position; \
|
||||||
attribute vec2 a_texCoord; \
|
attribute vec2 a_texCoord; \
|
||||||
attribute float a_angle; \
|
attribute vec2 a_angle; \
|
||||||
attribute vec2 a_center; \
|
attribute vec2 a_center; \
|
||||||
varying vec2 v_texCoord; \
|
varying vec2 v_texCoord; \
|
||||||
\
|
\
|
||||||
void main() \
|
void main() \
|
||||||
{ \
|
{ \
|
||||||
float angle = radians(a_angle); \
|
float s = a_angle[0]; \
|
||||||
float c = cos(angle); \
|
float c = a_angle[1] + 1.0; \
|
||||||
float s = sin(angle); \
|
|
||||||
mat2 rotationMatrix = mat2(c, -s, s, c); \
|
mat2 rotationMatrix = mat2(c, -s, s, c); \
|
||||||
vec2 position = rotationMatrix * (a_position - a_center) + a_center; \
|
vec2 position = rotationMatrix * (a_position - a_center) + a_center; \
|
||||||
v_texCoord = a_texCoord; \
|
v_texCoord = a_texCoord; \
|
||||||
|
|
Loading…
Reference in New Issue