PDA

View Full Version : black texture in opengl 330 core



blubee
12-02-2015, 10:33 AM
I am trying to get texturing to work on this quad but now all I am getting is a black quad.

This is the code to load the image


GLuint create_texture(const char* filename) {
SDL_Surface* surface;
GLenum tex_format;
GLint num_colors;
GLuint tex_id;
char* file_path;

file_path = get_resource(filename);
surface = IMG_Load(file_path);
if (!surface) {
SDL_Log("failed to create surface\n");
SDL_Quit();
return -1;
} else {
if ((surface->w & (surface->w - 1)) != 0) {
SDL_Log("image { %s } width is not power of 2\n", filename);
}
if ((surface->h & (surface->h - 1)) != 0) {
SDL_Log("image { %s } height is not power of 2\n", filename);
}

num_colors = surface->format->BytesPerPixel;
if (num_colors == 4) {
if (surface->format->Rmask == 0x000000ff)
tex_format = GL_RGBA;
else
tex_format = GL_BGRA;
}
if (num_colors == 3) {
if (surface->format->Rmask == 0x000000ff)
tex_format = GL_RGB;
else
tex_format = GL_BGR;

} else {
SDL_Log("pixel image format shouldn't get here! Quitting\n");
SDL_Quit();
};

glGenTextures(1, &tex_id);
glBindTexture(GL_TEXTURE_2D, tex_id);

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, tex_format, surface->w, surface->h, 0,
tex_format, GL_UNSIGNED_BYTE, surface->pixels);
}
if (surface) SDL_FreeSurface(surface);
free(file_path);

return tex_id;
}


vertex shader


#version 330 core

layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec4 a_col;
layout (location = 2) in vec2 a_tex;

uniform mat4 u_mvp_mat;
uniform mat4 u_mod_mat;
uniform mat4 u_view_mat;
uniform mat4 u_proj_mat;

out vec4 f_color;
out vec2 f_tex;

void main()
{
gl_Position = u_mvp_mat * vec4(a_pos, 1.0);
f_tex = a_tex;
f_color = a_col;
}


fragment shader


#version 330 core

in vec4 f_color;
out vec4 o_color;

in vec2 f_tex;
uniform sampler2D u_sprite_tex;

void main (void)
{
o_color = f_color;
o_color = texture(u_sprite_tex, f_tex);
}


setup vbo

quad = ren2d_new(); //just a wrapper around a quad or two tri.
ren2d_set_tint(quad, 0, 1, 0, 1); //setting the color to green

pos_loc = get_attrib_location(ce_get_default_shader(), "a_pos");
col_loc = get_attrib_location(ce_get_default_shader(), "a_col");
mvp_matrix_loc = get_uniform_location(ce_get_default_shader(), "u_mvp_mat");
model_mat_loc = get_uniform_location(ce_get_default_shader(), "u_mod_mat");
view_mat_loc = get_uniform_location(ce_get_default_shader(), "u_view_mat");
proj_matrix_loc =
get_uniform_location(ce_get_default_shader(), "u_proj_mat");

tex_loc = get_uniform_location(ce_get_default_shader(), "u_sprite_tex");

camera = cam_2d_new(ce_get_width(), ce_get_height());

model_mat = mat4_identity();
mat4_scale(model_mat, 128, 128, 1);

tex_id = create_texture("test.png");

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vert_buff);
glBindBuffer(GL_ARRAY_BUFFER, vert_buff);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad->vertices), quad->vertices,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &col_buff);
glBindBuffer(GL_ARRAY_BUFFER, col_buff);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad->colors), quad->colors,
GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);

glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(quad->tex_coords),
quad->tex_coords);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &ind_buff);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ind_buff);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad->indices), quad->indices,
GL_STATIC_DRAW);

glBindVertexArray(0);


rendering function


glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

//could my texturing problems be here?
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_id);
glUniform1i(tex_loc, 0);

glUseProgram(ce_get_default_shader()->shader_program);
glBindVertexArray(vao);

//excuse the silly names
ce_get_view_matrices(&vview_mat, &pproj_mat, &mmvp_mat);

mat4_multi(&mmvp_mat, &vview_mat, model_mat);
mat4_multi(&mmvp_mat, &pproj_mat, &mmvp_mat);
glUniformMatrix4fv(mvp_matrix_loc, 1, GL_FALSE, mat4_get_data(&mmvp_mat));

glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, mat4_get_data(model_mat));
glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, mat4_get_data(&vview_mat));
glUniformMatrix4fv(proj_matrix_loc, 1, GL_FALSE, mat4_get_data(&pproj_mat));

glDrawElements(GL_TRIANGLES, quad->vertex_count, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);


the last piece is the quad structure


#include "headers/renderable_2D.h"
#include <stdlib.h>



static void init_vertices(struct renderable_2D* out) {
//2, 0, 1 - 3, 0, 2
out->vertices[0] = 1.0f;
out->vertices[1] = 1.0f;
out->vertices[2] = 0.0f;

out->vertices[3] = -1.0f;
out->vertices[4] = 1.0f;
out->vertices[5] = 0.0f;

out->vertices[6] = -1.0f;
out->vertices[7] = -1.0f;
out->vertices[8] = 0.0f;

out->vertices[9] = 1.0f;
out->vertices[10] = -1.0f;
out->vertices[11] = 0.0f;
}

static void init_colors(struct renderable_2D* out) {
out->colors[0] = 1.0f;
out->colors[1] = 1.0f;
out->colors[2] = 1.0f;
out->colors[3] = 1.0f;

out->colors[4] = 1.0f;
out->colors[5] = 1.0f;
out->colors[6] = 1.0f;
out->colors[7] = 1.0f;

out->colors[8] = 1.0f;
out->colors[9] = 1.0f;
out->colors[10] = 1.0f;
out->colors[11] = 1.0f;

out->colors[12] = 1.0f;
out->colors[13] = 1.0f;
out->colors[14] = 1.0f;
out->colors[15] = 1.0f;
}

static void init_texture_coords(struct renderable_2D* out) {
out->tex_coords[0] = 0.0f; // u1
out->tex_coords[1] = 0.0f; // v1

out->tex_coords[2] = 1.0f; // u2
out->tex_coords[3] = 0.0f; // v2

out->tex_coords[4] = 1.0f; // u3
out->tex_coords[5] = 1.0f; // v3

out->tex_coords[6] = 0.0f; // u4
out->tex_coords[7] = 1.0f; // v4
}

static void init_indices(struct renderable_2D* out) {
out->indices[0] = 2;
out->indices[1] = 0;
out->indices[2] = 1;

out->indices[3] = 3;
out->indices[4] = 0;
out->indices[5] = 2;
}

struct renderable_2D* ren2d_new(void) {
struct renderable_2D* m_ren =
(struct renderable_2D*)calloc(1, sizeof(struct renderable_2D));
init_vertices(m_ren);
init_indices(m_ren);
init_texture_coords(m_ren);
init_colors(m_ren);
m_ren->vertex_count = 6;
return m_ren;
}
struct renderable_2D* ren2d_set_uv(struct renderable_2D* out,
const float uv[]) {
out->tex_coords[0] = uv[0]; // u1
out->tex_coords[1] = uv[1]; // v1

out->tex_coords[2] = uv[2]; // u2
out->tex_coords[3] = uv[3]; // v2

out->tex_coords[4] = uv[4]; // u3
out->tex_coords[5] = uv[5]; // v3

out->tex_coords[6] = uv[6]; // u4
out->tex_coords[7] = uv[7]; // v4

return out;
}
struct renderable_2D* ren2d_set_tint(struct renderable_2D* out, const float r,
const float g, const float b,
const float a) {
out->colors[0] = r;
out->colors[1] = g;
out->colors[2] = b;
out->colors[3] = a;

out->colors[4] = r;
out->colors[5] = g;
out->colors[6] = b;
out->colors[7] = a;

out->colors[8] = r;
out->colors[9] = g;
out->colors[10] = b;
out->colors[11] = a;

out->colors[12] = r;
out->colors[13] = g;
out->colors[14] = b;
out->colors[15] = a;

return out;
}
struct renderable_2D* ren2d_set_alpha(struct renderable_2D* out,
const float a) {
out->colors[3] = a;
out->colors[7] = a;
out->colors[11] = a;
out->colors[15] = a;

return out;
}
struct renderable_2D* rend2d_set_z_index(struct renderable_2D* out,
const int index) {
out->vertices[2] = index;
out->vertices[5] = index;
out->vertices[8] = index;
out->vertices[11] = index;

return out;
}
struct renderable_2D* rend2d_set_rotation(struct renderable_2D* out,
const float angle) {
out->rotation = angle;

return out;
}


doing some basic testing in the fragment shader like this


#version 330 core

in vec4 f_color;
out vec4 o_color;

in vec2 f_tex;
uniform sampler2D u_sprite_tex;

void main (void)
{
//o_color = f_color;
vec4 c;
if(f_tex.y == 1.0) { c = vec4(1.0, 0.0, 0.0, 1.0); }
if(f_tex.y == 0.0) { c = vec4(0.0, 0.0, 1.0, 1.0); }
o_color = c;
o_color = texture(u_sprite_tex, f_tex);
}


the quad turns out blue, so it seems that I am not passing in the correct information to the shader but I am not exactly sure where I am making my mistake?

Anyone can see what am I doing wrong here?

initially the function to create texture was this


glTexImage2D( GL_TEXTURE_2D, 0, num_colors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );


but changed that to this


glTexImage2D( GL_TEXTURE_2D, 0, texture_format, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );

because of this article on the opengl documentation: https://www.khronos.org/opengles/sdk/1.1/docs/man/glTexImage2D.xml
where it says that the 3rd 7th elements should be the same but still I get a black texture.

eugeneyche
12-03-2015, 05:01 PM
Apologies for not testing this, but from looking at your code, I think the problem is this line:


glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(quad->tex_coords),
quad->tex_coords);

I think the second parameter should be 2.

blubee
12-05-2015, 11:17 AM
this was a really bad oversight on my part



glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vert_buff);
glBindBuffer(GL_ARRAY_BUFFER, vert_buff);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad->vertices), quad->vertices,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &col_buff);
glBindBuffer(GL_ARRAY_BUFFER, col_buff);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad->colors), quad->colors,
GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);

glGenBuffers(1, &tex_coord_buff); //first mistake I didn't generate a texture coordinate buffer
glBindBuffer(GL_ARRAY_BUFFER, &tex_coord_loc); //after making the buffer actually bind it
glBufferData(GL_ARRAY_BUFFER, sizeof(quad->tex), quad->tex, //third mistake I didn't send any data to the GPU!
GL_STATIC_DRAW);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(quad->tex_coords), //fourth mistake, the second variable should be 2 as I am only passing in 2 floats not 4
quad->tex_coords);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &ind_buff);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ind_buff);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad->indices), quad->indices,
GL_STATIC_DRAW);

glBindVertexArray(0);


I'm surprised it rendered and just didn't plain out explode my video card.