mirror of https://github.com/libsdl-org/SDL
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;
|
||||
|
||||
#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
|
||||
if (!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->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
|
||||
|
||||
return 0;
|
||||
|
@ -1857,6 +1857,8 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
|
|||
return GL_CheckError("", renderer);
|
||||
}
|
||||
|
||||
#define PI 3.14159265f
|
||||
|
||||
static int
|
||||
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)
|
||||
|
@ -1865,8 +1867,9 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
|
|||
GLfloat vertices[8];
|
||||
GLfloat texCoords[8];
|
||||
GLfloat translate[8];
|
||||
GLfloat fAngle[4];
|
||||
GLfloat fAngle[8];
|
||||
GLfloat tmp;
|
||||
float radian_angle;
|
||||
|
||||
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_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 */
|
||||
translate[0] = translate[2] = translate[4] = translate[6] = (center->x + dstrect->x);
|
||||
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_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_POSITION, vertices, 8 * sizeof(GLfloat));
|
||||
|
||||
|
|
|
@ -30,20 +30,24 @@
|
|||
/*************************************************************************************************
|
||||
* 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_[] = " \
|
||||
uniform mat4 u_projection; \
|
||||
attribute vec2 a_position; \
|
||||
attribute vec2 a_texCoord; \
|
||||
attribute float a_angle; \
|
||||
attribute vec2 a_angle; \
|
||||
attribute vec2 a_center; \
|
||||
varying vec2 v_texCoord; \
|
||||
\
|
||||
void main() \
|
||||
{ \
|
||||
float angle = radians(a_angle); \
|
||||
float c = cos(angle); \
|
||||
float s = sin(angle); \
|
||||
float s = a_angle[0]; \
|
||||
float c = a_angle[1] + 1.0; \
|
||||
mat2 rotationMatrix = mat2(c, -s, s, c); \
|
||||
vec2 position = rotationMatrix * (a_position - a_center) + a_center; \
|
||||
v_texCoord = a_texCoord; \
|
||||
|
|
Loading…
Reference in New Issue