Cześć! Uczę się openGLa od niedawna i przyszło mi się zmierzyć z renderem tekstury. Postanowiłem użyć do tego biblioteki SDL2. Problem polega na tym, że IDE nie pokazuje żadnych błędów związanych z kompilacją, kolor oraz kwadrat również się renderuje. Jedyne czego brakuje to obrazka, który został przeze mnie wybrany.
Do zrobienia VBO, kolorów oraz UV wykorzystałem struktury
struct GLTexture
{
GLuint textureID;
float width, height;
};
struct UV
{
float u, v;
};
struct Position
{
float x;
float y;
};
struct ColorRGBA8
{
ColorRGBA8() : r(0), g(0), b(0), a(0) { }
ColorRGBA8(GLubyte R, GLubyte G, GLubyte B, GLubyte A) :
r(R), g(G), b(B), a(A) { }
GLubyte r;
GLubyte g;
GLubyte b;
GLubyte a;
};
struct Vertex
{
Position position;
ColorRGBA8 color;
UV uv;
void setUV(float u, float v)
{
uv.u = u;
uv.v = v;
}
void setPosition(float x, float y)
{
position.x = x;
position.y = y;
}
void setColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a)
{
color.r = r;
color.g = g;
color.b = b;
color.a = a;
}
};
w mainie ustawiłem wszystkie niezbędne rzeczy
int main(int arg, char*args[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Window* window = SDL_CreateWindow("window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
SDL_GLContext context = SDL_GL_CreateContext(window);
SDL_GL_SetSwapInterval(1);
glewExperimental = true;
GLenum result = glewInit();
std::string vertex = loadFromFile("shader.vert.glsl");
std::string frag = loadFromFile("shader.frag.glsl");
GLuint shaderProgram = CreateShaderProgram(vertex.c_str(), frag.c_str());
GLint uniformUV = glGetUniformLocation(shaderProgram, "mySampler");
glUseProgram(shaderProgram);
//Inicjuje kwadrat na pozycji x y i o szerokościach w i h
InitVBO(1.0, 1.0, -2.0, -2.0);
// Ładuje teksturę o nazwie ...
GLTexture texture = LoadTexture("tekstura");
std::cout << "IN MAIN ID :" << texture.textureID << std::endl;
SDL_Event *event = new SDL_Event;
bool quit = false;
while (!quit && event->type != SDL_QUIT)
{
SDL_PollEvent(event);
glClearDepthf(1.0);
glUniform1i(uniformUV, 0);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture.textureID);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindTexture(GL_TEXTURE_2D, 0);
SDL_GL_SwapWindow(window);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &vao);
return 0;
}
I metodą ładuje teksturę
GLTexture LoadTexture(std::string textureName)
{
textureName = textureName + ".png";
GLTexture texture{};
SDL_Surface *surface = IMG_Load(textureName.c_str());
texture.width = surface->w;
texture.height = surface->h;
glGenTextures(1, &texture.textureID);
glBindTexture(GL_TEXTURE_2D, texture.textureID);
int Format = GL_RGB;
if (surface->format->BytesPerPixel == 4) {
Format = GL_RGBA;
}
std::cout << "IN LOADTEXTURE ID :" << texture.textureID << std::endl;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0, Format, GL_UNSIGNED_BYTE, surface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
return texture;
}
Inicjacja VBO
void InitVBO(float x, float y, float w, float h)
{
Vertex vertex[6];
vertex[0].setPosition(x + w, y + h);
vertex[0].setUV(1.0f, 1.0f);
vertex[1].setPosition(x, y + h);
vertex[1].setUV(0.0f, 1.0f);
vertex[2].setPosition(x, y);
vertex[2].setUV(0.0f, 0.0f);
vertex[3].setPosition(x, y);
vertex[3].setUV(0.0f, 0.0f);
vertex[4].setPosition(x + w, y);
vertex[4].setUV(1.0f, 0.0f);
vertex[5].setPosition(x + w, y + h);
vertex[5].setUV(1.0f, 1.0f);
for (int i = 0; i < 6; ++i)
{
vertex[i].setColor(255, 0, 255, 255);
}
vertex[1].setColor(0, 0, 255, 255);
vertex[4].setColor(0, 255, 0, 255);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
}
Tak wyglądają shadery
Fragment
#version 330 core
out vec4 outColor;
in vec4 vertexColor;
in vec2 vertexPos;
in vec2 vertexUV;
uniform sampler2D mySampler;
void main()
{
vec4 txt = texture(mySampler, vertexUV);
outColor = txt * vertexColor;
}
I vertex
#version 330 core
layout (location = 0) in vec2 pos;
layout (location = 1) in vec4 col;
layout (location = 2) in vec2 uv;
out vec2 vertexPos;
out vec4 vertexColor;
out vec2 vertexUV;
void main()
{
gl_Position = vec4(pos.xy, 0.0, 1.0);
vertexColor = col;
vertexPos = pos;
vertexUV = uv;
}
Efekt końcowy
obrazek który chciałbym załadować
Próbowałem załatować jeszcze taki
to efekt końcowy wyglądał tak, że w ogóle się nic nie pokazywało.
- screenshot-20171223193416.png (3 KB) - ściągnięć: 114
- screenshot-20171223193335.png (157 KB) - ściągnięć: 144