OpenGL - funkcja

0

Mam pytanko odnośnie jednej z funkcjonalności OpenGL, a dokładniej o jedną z funkcji.
Mianowicie - funkcja glBufferData pozwala nam na przesłanie tablicy do pamięci gpu. A co jeśli chcemy przesłać teksturę? Jakiej funkcji należy użyć? Mógłby ktoś podać przykładową składnię?

0

wrzuce kawalek kodu z http://4programmers.net/Forum/Edukacja/232269-age_of_demons ;)

 #pragma once
#include <string>
#include "SpriteTypes.h"
#include "SDL2\include\SDL.h"

namespace Graphics
{
	class Sprite
	{
	public:
		Sprite(const std::string& path, int priority, SDL_Rect rect);
		Sprite(const std::string& path, int priority, int x, int y, int w, int h);
		Sprite(int priority, SDL_Rect rect, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
		Sprite(const std::string& text, const std::string& path, int priority, int x, int y, int w, int h);
		~Sprite();

		Common::SpriteType type;
		const std::string path;
		const std::string text;
		int priority;
		SDL_Rect rect;
		Uint8 r, g, b, a;
	};
} 
void Engine::addSprite(Sprite sprite)
{
	std::list<Sprite>::iterator it;
	if(sprite.type == SPRITE)
	{
		if(!(texturesInMemory.count(sprite.path)))
		{
			texturesInMemory[sprite.path] = loadTexture(sprite.path);
		}
	}
	else if (sprite.type == TEXT)
	{
		if (!(texturesInMemory.count(sprite.text)))
		{
			texturesInMemory[sprite.text] = loadText(sprite.text, sprite.path);
		}
	}
	for(it = sprites.begin(); it != sprites.end(); ++it)
	{
		if(it->priority >= sprite.priority)
		{
			break;
		}
	}
	sprites.insert(it, sprite);
} 
 int Common::loadTexture(const std::string& path)
{
	std::shared_ptr<SDL_Surface> texture(
		IMG_Load(path.c_str()), 
		[](SDL_Surface* surface){SDL_FreeSurface(surface);});
	GLuint object = 0;
	glGenTextures(1, &object);
	glBindTexture(GL_TEXTURE_2D, object);
	int mode = GL_RGB;
	if (texture->format->BytesPerPixel == 4)
	{
		mode = GL_RGBA;
	}
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, mode, texture->w, texture->h, 0, mode, GL_UNSIGNED_BYTE, texture->pixels);
	return object;
}

int Common::loadTexture(std::shared_ptr<SDL_Surface> texture)
{
	GLuint object = 0;
	glGenTextures(1, &object);
	glBindTexture(GL_TEXTURE_2D, object);
	int mode = GL_RGB;
	if (texture->format->BytesPerPixel == 4)
	{
		mode = GL_RGBA;
	}
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, mode, texture->w, texture->h, 0, mode, GL_UNSIGNED_BYTE, texture->pixels);
	return object;
}

int Common::loadText(const std::string& text, const std::string& path)
{
	std::shared_ptr<TTF_Font> font(
		TTF_OpenFont(path.c_str(), 32), 
		[](TTF_Font* f){TTF_CloseFont(f); });
	SDL_Color color = { 0, 0, 0, 255 };
	std::shared_ptr<SDL_Surface> textSurface(
		TTF_RenderText_Blended(font.get(), text.c_str(), color),
		[](SDL_Surface* s){SDL_FreeSurface(s);});
	return loadTexture(textSurface);
}
 void Engine::draw(Uint32 ticks)
{
	glClearColor(0, 0, 0, 1);
	glClear(GL_COLOR_BUFFER_BIT);

	for(Sprite sprite : sprites)
	{
		float x = static_cast<float>(sprite.rect.x) / (windowWidth / 2),
			y = static_cast<float>(sprite.rect.y) / (windowHeight / 2),
			w = static_cast<float>(sprite.rect.w) / (windowWidth / 2),
			h = static_cast<float>(sprite.rect.h) / (windowHeight / 2);
		float x1 = x,
			x2 = x + w,
			y1 = -y,
			y2 = -h-y;
		glLoadIdentity();
		glTranslatef(-1.0f, 1.0f, 0);
		if(sprite.type == SPRITE || sprite.type == TEXT)
		{
			if (sprite.type == SPRITE)
				glBindTexture(GL_TEXTURE_2D, texturesInMemory[sprite.path]);
			else
				glBindTexture(GL_TEXTURE_2D, texturesInMemory[sprite.text]);
			glBegin(GL_QUADS);
				glTexCoord2f(0, 0);
				glVertex3f(x1, y1, 0);
				glTexCoord2f(1, 0);
				glVertex3f(x2, y1, 0);
				glTexCoord2f(1, 1);
				glVertex3f(x2, y2, 0);
				glTexCoord2f(0, 1);
				glVertex3f(x1, y2, 0);
			glEnd();
		}
		else if (sprite.type == RECTANGLE)
		{
			glDisable(GL_BLEND);
			glPushAttrib(GL_CURRENT_BIT);
			glColor4ub(sprite.r, sprite.g, sprite.b, sprite.a);
			glBegin(GL_QUADS);
				glVertex3f(x1, y1, 0);
				glVertex3f(x2, y1, 0);
				glVertex3f(x2, y2, 0);
				glVertex3f(x1, y2, 0);
			glEnd();
			glPopAttrib();
			glEnable(GL_BLEND);
		}
	}
	SDL_GL_SwapWindow(mainWindow.get());
}

przeanalizuj i powinienes wiedziec jak napisac to co chcesz ;)

0

@fasadin nie że sie czepiam czy coś, ale co byś zrobił jakby różnych typów Spritów było 10? Albo 100? Też na bazie enuma i ifów? :D Czemu te różne rodzaje to nie są klasy dziedziczące ze Sprite? I czemu logika "malowania" danego Sprite nie jest zamknięta w jego własnej implemetnacji? Chciałbym zobaczyć to draw() jak będzie 100 typów Sprita :D

0

To co podał @fasadin to jest OpenGL z ubiegłego wieku ;). @greedy624 weź dowolny tutorial, który omawia ładowanie tekstur w nowym OGL, o którego zapewne ci chodzi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1