comparison src/video/SDL_renderer_gl.c @ 3536:0267b8b1595c

Added interfaces for batch drawing of points, lines and rects: SDL_DrawPoints() SDL_BlendPoints() SDL_BlendLines() SDL_DrawLines() SDL_FillRects() SDL_BlendRects() SDL_RenderPoints() SDL_RenderLines() SDL_RenderRects() Renamed SDL_RenderFill() to SDL_RenderRect()
author Sam Lantinga <slouken@libsdl.org>
date Wed, 09 Dec 2009 15:56:56 +0000
parents 40b9b0177e9a
children f638ded38b8a
comparison
equal deleted inserted replaced
3535:b403f790df65 3536:0267b8b1595c
94 const SDL_Rect * rect, int markDirty, void **pixels, 94 const SDL_Rect * rect, int markDirty, void **pixels,
95 int *pitch); 95 int *pitch);
96 static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); 96 static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
97 static void GL_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, 97 static void GL_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
98 int numrects, const SDL_Rect * rects); 98 int numrects, const SDL_Rect * rects);
99 static int GL_RenderPoint(SDL_Renderer * renderer, int x, int y); 99 static int GL_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points,
100 static int GL_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, 100 int count);
101 int y2); 101 static int GL_RenderLines(SDL_Renderer * renderer, const SDL_Point * points,
102 static int GL_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect); 102 int count);
103 static int GL_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
104 int count);
103 static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 105 static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
104 const SDL_Rect * srcrect, const SDL_Rect * dstrect); 106 const SDL_Rect * srcrect, const SDL_Rect * dstrect);
105 static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, 107 static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
106 Uint32 pixel_format, void * pixels, int pitch); 108 Uint32 pixel_format, void * pixels, int pitch);
107 static int GL_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, 109 static int GL_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
302 renderer->SetTextureScaleMode = GL_SetTextureScaleMode; 304 renderer->SetTextureScaleMode = GL_SetTextureScaleMode;
303 renderer->UpdateTexture = GL_UpdateTexture; 305 renderer->UpdateTexture = GL_UpdateTexture;
304 renderer->LockTexture = GL_LockTexture; 306 renderer->LockTexture = GL_LockTexture;
305 renderer->UnlockTexture = GL_UnlockTexture; 307 renderer->UnlockTexture = GL_UnlockTexture;
306 renderer->DirtyTexture = GL_DirtyTexture; 308 renderer->DirtyTexture = GL_DirtyTexture;
307 renderer->RenderPoint = GL_RenderPoint; 309 renderer->RenderPoints = GL_RenderPoints;
308 renderer->RenderLine = GL_RenderLine; 310 renderer->RenderLines = GL_RenderLines;
309 renderer->RenderFill = GL_RenderFill; 311 renderer->RenderRects = GL_RenderRects;
310 renderer->RenderCopy = GL_RenderCopy; 312 renderer->RenderCopy = GL_RenderCopy;
311 renderer->RenderReadPixels = GL_RenderReadPixels; 313 renderer->RenderReadPixels = GL_RenderReadPixels;
312 renderer->RenderWritePixels = GL_RenderWritePixels; 314 renderer->RenderWritePixels = GL_RenderWritePixels;
313 renderer->RenderPresent = GL_RenderPresent; 315 renderer->RenderPresent = GL_RenderPresent;
314 renderer->DestroyTexture = GL_DestroyTexture; 316 renderer->DestroyTexture = GL_DestroyTexture;
1110 data->blendMode = blendMode; 1112 data->blendMode = blendMode;
1111 } 1113 }
1112 } 1114 }
1113 1115
1114 static int 1116 static int
1115 GL_RenderPoint(SDL_Renderer * renderer, int x, int y) 1117 GL_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count)
1116 { 1118 {
1117 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; 1119 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1120 int i;
1118 1121
1119 GL_SetBlendMode(data, renderer->blendMode, 1); 1122 GL_SetBlendMode(data, renderer->blendMode, 1);
1120 1123
1121 data->glColor4f((GLfloat) renderer->r * inv255f, 1124 data->glColor4f((GLfloat) renderer->r * inv255f,
1122 (GLfloat) renderer->g * inv255f, 1125 (GLfloat) renderer->g * inv255f,
1123 (GLfloat) renderer->b * inv255f, 1126 (GLfloat) renderer->b * inv255f,
1124 (GLfloat) renderer->a * inv255f); 1127 (GLfloat) renderer->a * inv255f);
1125 1128
1126 data->glBegin(GL_POINTS); 1129 data->glBegin(GL_POINTS);
1127 data->glVertex2f(0.5f + x, 0.5f + y); 1130 for (i = 0; i < count; ++i) {
1131 data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1132 }
1128 data->glEnd(); 1133 data->glEnd();
1129 1134
1130 return 0; 1135 return 0;
1131 } 1136 }
1132 1137
1133 static int 1138 static int
1134 GL_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) 1139 GL_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count)
1135 { 1140 {
1136 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; 1141 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1142 int i;
1137 1143
1138 GL_SetBlendMode(data, renderer->blendMode, 1); 1144 GL_SetBlendMode(data, renderer->blendMode, 1);
1139 1145
1140 data->glColor4f((GLfloat) renderer->r * inv255f, 1146 data->glColor4f((GLfloat) renderer->r * inv255f,
1141 (GLfloat) renderer->g * inv255f, 1147 (GLfloat) renderer->g * inv255f,
1142 (GLfloat) renderer->b * inv255f, 1148 (GLfloat) renderer->b * inv255f,
1143 (GLfloat) renderer->a * inv255f); 1149 (GLfloat) renderer->a * inv255f);
1144 1150
1145 data->glBegin(GL_LINES); 1151 if (count > 2 &&
1146 data->glVertex2f(0.5f + x1, 0.5f + y1); 1152 points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
1147 data->glVertex2f(0.5f + x2, 0.5f + y2); 1153 data->glBegin(GL_LINE_LOOP);
1148 data->glEnd(); 1154 /* GL_LINE_LOOP takes care of the final segment */
1149 1155 --count;
1150 /* The line is half open, so we need one more point to complete the line. 1156 for (i = 0; i < count; ++i) {
1151 * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html 1157 data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1152 * If we have to, we can use vertical line and horizontal line textures 1158 }
1153 * for vertical and horizontal lines, and then create custom textures 1159 data->glEnd();
1154 * for diagonal lines and software render those. It's terrible, but at 1160 } else {
1155 * least it would be pixel perfect. 1161 data->glBegin(GL_LINE_STRIP);
1156 */ 1162 for (i = 0; i < count; ++i) {
1157 data->glBegin(GL_POINTS); 1163 data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1164 }
1165 data->glEnd();
1166
1167 /* The line is half open, so we need one more point to complete it.
1168 * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
1169 * If we have to, we can use vertical line and horizontal line textures
1170 * for vertical and horizontal lines, and then create custom textures
1171 * for diagonal lines and software render those. It's terrible, but at
1172 * least it would be pixel perfect.
1173 */
1174 data->glBegin(GL_POINTS);
1158 #if defined(__APPLE__) || defined(__WIN32__) 1175 #if defined(__APPLE__) || defined(__WIN32__)
1159 /* Mac OS X and Windows seem to always leave the second point open */ 1176 /* Mac OS X and Windows seem to always leave the second point open */
1160 data->glVertex2f(0.5f + x2, 0.5f + y2); 1177 data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
1161 #else 1178 #else
1162 /* Linux seems to leave the right-most or bottom-most point open */ 1179 /* Linux seems to leave the right-most or bottom-most point open */
1163 if (x1 > x2) { 1180 int x1 = points[0].x;
1164 data->glVertex2f(0.5f + x1, 0.5f + y1); 1181 int y1 = points[0].y;
1165 } else if (x2 > x1) { 1182 int x2 = points[count-1].x;
1166 data->glVertex2f(0.5f + x2, 0.5f + y2); 1183 int y2 = points[count-1].y;
1167 } else if (y1 > y2) { 1184
1168 data->glVertex2f(0.5f + x1, 0.5f + y1); 1185 if (x1 > x2) {
1169 } else if (y2 > y1) { 1186 data->glVertex2f(0.5f + x1, 0.5f + y1);
1170 data->glVertex2f(0.5f + x2, 0.5f + y2); 1187 } else if (x2 > x1) {
1171 } 1188 data->glVertex2f(0.5f + x2, 0.5f + y2);
1172 #endif 1189 } else if (y1 > y2) {
1173 data->glEnd(); 1190 data->glVertex2f(0.5f + x1, 0.5f + y1);
1174 1191 } else if (y2 > y1) {
1175 return 0; 1192 data->glVertex2f(0.5f + x2, 0.5f + y2);
1176 } 1193 }
1177 1194 #endif
1178 static int 1195 data->glEnd();
1179 GL_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) 1196 }
1197
1198 return 0;
1199 }
1200
1201 static int
1202 GL_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
1180 { 1203 {
1181 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; 1204 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1205 int i;
1182 1206
1183 GL_SetBlendMode(data, renderer->blendMode, 1); 1207 GL_SetBlendMode(data, renderer->blendMode, 1);
1184 1208
1185 data->glColor4f((GLfloat) renderer->r * inv255f, 1209 data->glColor4f((GLfloat) renderer->r * inv255f,
1186 (GLfloat) renderer->g * inv255f, 1210 (GLfloat) renderer->g * inv255f,
1187 (GLfloat) renderer->b * inv255f, 1211 (GLfloat) renderer->b * inv255f,
1188 (GLfloat) renderer->a * inv255f); 1212 (GLfloat) renderer->a * inv255f);
1189 1213
1190 data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); 1214 for (i = 0; i < count; ++i) {
1215 const SDL_Rect *rect = rects[i];
1216
1217 data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
1218 }
1191 1219
1192 return 0; 1220 return 0;
1193 } 1221 }
1194 1222
1195 static int 1223 static int