Serwis Edukacyjny Nauczycieli w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy
Wałaszek |
©2025 mgr Jerzy Wałaszek
|
SDL_GL_BindTexture
SPIS TREŚCI |
Rozdział jest tłumaczeniem oryginalnej instrukcji dla biblioteki SDL2.
Użyj tej funkcji, aby związać teksturę OpenGL/ES/ES2 z bieżącym kontekstem w celu użycia jej z instrukcjami OpenGL, gdy obiekty pierwotne OpenGL są rysowane bezpośrednio.
int SDL_GL_BindTexture(SDL_Texture* texture, float* texw, float* texh) |
texture | tekstura do związania z bieżącym kontekstem OpenGL/ES/ES2. |
texw | wskaźnik do wartości typu float, która zostanie wypełniona szerokością tekstury, lub NULL, jeśli nie potrzebujesz tej wartości. |
texh | wskaźnik do wartości typu float, która zostanie wypełniona wysokością tekstury, lub NULL, jeśli nie potrzebujesz tej wartości. |
Poniższe trzy przykłady zostały wydobyte z Ignifuga Game Engine i pokazują sposób połączenia biblioteki libRocket (która używa OpenGL do rysowania) z SDL2.
void RocketSDLRenderInterfaceOpenGL::RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, const Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation) { // SDL używa shaderów, które potrzebujemy tu wyłączyć render_data.glUseProgramObjectARB(0); render_data.glPushMatrix(); render_data.glTranslatef(translation.x, translation.y, 0); std::vector<Rocket::Core::Vector2f> Positions(num_vertices); std::vector<Rocket::Core::Colourb> Colors(num_vertices); std::vector<Rocket::Core::Vector2f> TexCoords(num_vertices); float texw, texh; SDL_Texture* sdl_texture = NULL; if(texture) { render_data.glEnableClientState(GL_TEXTURE_COORD_ARRAY); sdl_texture = (SDL_Texture *) texture; SDL_GL_BindTexture(sdl_texture, &texw, &texh); } for (int i = 0; i < num_vertices; i++) { Positions[i] = vertices[i].position; Colors[i] = vertices[i].colour; if (sdl_texture) { TexCoords[i].x = vertices[i].tex_coord.x * texw; TexCoords[i].y = vertices[i].tex_coord.y * texh; } else { TexCoords[i] = vertices[i].tex_coord; } } render_data.glEnableClientState(GL_VERTEX_ARRAY); render_data.glEnableClientState(GL_COLOR_ARRAY); render_data.glVertexPointer(2, GL_FLOAT, 0, &Positions[0]); render_data.glColorPointer(4, GL_UNSIGNED_BYTE, 0, &Colors[0]); render_data.glTexCoordPointer(2, GL_FLOAT, 0, &TexCoords[0]); render_data.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); render_data.glEnable(GL_BLEND); render_data.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); render_data.glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, indices); render_data.glDisableClientState(GL_VERTEX_ARRAY); render_data.glDisableClientState(GL_COLOR_ARRAY); if (sdl_texture) { SDL_GL_UnbindTexture(sdl_texture); render_data.glDisableClientState(GL_TEXTURE_COORD_ARRAY); } render_data.glColor4f(1.0, 1.0, 1.0, 1.0); render_data.glPopMatrix(); } |
void RocketSDLRenderInterfaceOpenGLES::RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, const Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation) { render_data.glPushMatrix(); render_data.glTranslatef(translation.x, translation.y, 0); std::vector<Rocket::Core::Vector2f> Positions(num_vertices); std::vector<Rocket::Core::Colourb> Colors(num_vertices); std::vector<Rocket::Core::Vector2f> TexCoords(num_vertices); float texw, texh; SDL_Texture* sdl_texture = NULL; if(texture) { render_data.glEnableClientState(GL_TEXTURE_COORD_ARRAY); sdl_texture = (SDL_Texture *) texture; SDL_GL_BindTexture(sdl_texture, &texw, &texh); } for (int i = 0; i < num_vertices; i++) { Positions[i] = vertices[i].position; Colors[i] = vertices[i].colour; if (sdl_texture) { TexCoords[i].x = vertices[i].tex_coord.x * texw; TexCoords[i].y = vertices[i].tex_coord.y * texh; } else { TexCoords[i] = vertices[i].tex_coord; } } unsigned short newIndicies[num_indices]; for (int i = 0; i < num_indices; i++) { newIndicies[i] = (unsigned short) indices[i]; } render_data.glEnableClientState(GL_VERTEX_ARRAY); render_data.glEnableClientState(GL_COLOR_ARRAY); render_data.glVertexPointer(2, GL_FLOAT, 0, &Positions[0]); render_data.glColorPointer(4, GL_UNSIGNED_BYTE, 0, &Colors[0]); render_data.glTexCoordPointer(2, GL_FLOAT, 0, &TexCoords[0]); render_data.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); render_data.glEnable(GL_BLEND); render_data.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); render_data.glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, newIndicies); render_data.glDisableClientState(GL_VERTEX_ARRAY); render_data.glDisableClientState(GL_COLOR_ARRAY); render_data.glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (sdl_texture) { SDL_GL_UnbindTexture(sdl_texture); render_data.glDisableClientState(GL_TEXTURE_COORD_ARRAY); } render_data.glColor4f(1.0, 1.0, 1.0, 1.0); render_data.glPopMatrix(); } |
SDL_Texture* sdl_texture = NULL; if(texture) render_data.glUseProgram(program_texture_id); else render_data.glUseProgram(program_color_id); int width, height; SDL_Rect rvp; SDL_RenderGetViewport(renderer, &rvp); GLfloat projection[4][4]; // Przygotuj rzut prostokątny projection[0][0] = 2.0f / rvp.w; projection[0][1] = 0.0f; projection[0][2] = 0.0f; projection[0][3] = 0.0f; projection[1][0] = 0.0f; //if (renderer->target) { // projection[1][1] = 2.0f / height; //} else { projection[1][1] = -2.0f / rvp.h; //} projection[1][2] = 0.0f; projection[1][3] = 0.0f; projection[2][0] = 0.0f; projection[2][1] = 0.0f; projection[2][2] = 0.0f; projection[2][3] = 0.0f; projection[3][0] = -1.0f; //if (renderer->target) { // projection[3][1] = -1.0f; //} else { projection[3][1] = 1.0f; //} projection[3][2] = 0.0f; projection[3][3] = 1.0f; // Ustaw macierz rzutu if (texture) { render_data.glUniformMatrix4fv(u_texture_projection, 1, GL_FALSE, (GLfloat *)projection); render_data.glUniform2f(u_texture_translation, translation.x, translation.y); } else { render_data.glUniformMatrix4fv(u_color_projection, 1, GL_FALSE, (GLfloat *)projection); render_data.glUniform2f(u_color_translation, translation.x, translation.y); } render_data.glEnable(GL_BLEND); render_data.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float texw, texh; unsigned short newIndicies[num_indices]; for (int i = 0; i < num_indices; i++) { newIndicies[i] = (unsigned short) indices[i]; } glVertexAttribPointer(ROCKETGLUE_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(Rocket::Core::Vertex), &vertices[0].position); glVertexAttribPointer(ROCKETGLUE_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Rocket::Core::Vertex), &vertices[0].colour); render_data.glEnableVertexAttribArray(ROCKETGLUE_ATTRIBUTE_POSITION); render_data.glEnableVertexAttribArray(ROCKETGLUE_ATTRIBUTE_TEXCOORD); render_data.glEnableVertexAttribArray(ROCKETGLUE_ATTRIBUTE_COLOR); if (texture) { sdl_texture = (SDL_Texture *) texture; SDL_GL_BindTexture(sdl_texture, &texw, &texh); render_data.glUniform1i(u_texture, 0); glVertexAttribPointer(ROCKETGLUE_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Rocket::Core::Vertex), &vertices[0].tex_coord); } else { render_data.glActiveTexture(GL_TEXTURE0); render_data.glDisable(GL_TEXTURE_2D); render_data.glDisableVertexAttribArray(ROCKETGLUE_ATTRIBUTE_TEXCOORD); } render_data.glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, newIndicies); /* Możemy bezpiecznie wyłączyć ROCKETGLUE_ATTRIBUTE_COLOR (2), ponieważ SDL ponownie uaktywni vertex attrib 2, jeśli jest to konieczne */ render_data.glDisableVertexAttribArray(ROCKETGLUE_ATTRIBUTE_COLOR); /* Pozostaw ROCKETGLUE_ATTRIBUTE_POSITION (0) i ROCKETGLUE_ATTRIBUTE_TEXCOORD (1) włączone dla kompatybilności z SDL, ponieważ SDL nie uaktywnia ich ponownie, gdy wywołujesz RenderCopy/Ex */ if(sdl_texture) SDL_GL_UnbindTexture(sdl_texture); else render_data.glEnableVertexAttribArray(ROCKETGLUE_ATTRIBUTE_TEXCOORD); /* Resetuj wtapianie i narysuj fałszywy punkt tuż poza ekranem, aby dać znać SDL, że musi zresetować swój stan, gdyby miała być rysowana tekstura */ render_data.glDisable(GL_BLEND); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); SDL_RenderDrawPoint(renderer, -1, -1); |
Potrzebujesz kontekstu graficznego do utworzenia SDL_Texture, dlatego możesz używać tej funkcji jedynie z jawnym kontekstem OpenGL z SDL_CreateRenderer(), nie ze swoim własnym kontekstem OpenGL.Jeśli potrzebna ci jest kontrola nad swoim kontekstem OpenGL, to będziesz potrzebował napisać swoje własne metody ładowania tekstur.
Również zwróć uwagę, że SDL może załadować tekstury RGB jako BGR (lub na odwrót) oraz zmienić kolejność kanałów kolorów w fazie shaderów, zatem załadowana tekstura może mieć zamienione kanały kolorów.
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2025 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.