Loading embedded textures with SOIL - c

I am using this answer to embed my image in the .exe:
Embedding resources in executable using GCC
Here are the relevant bits of my code:
GLuint grass_DTexture;
extern char binary_grass_D_bmp_start[];
extern char binary_grass_D_bmp_size[];
short loadTexture(char *imageData[], GLuint *texture) {
*texture = SOIL_load_OGL_texture_from_memory(imageData, sizeof(*imageData), SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
return 1;
}
loadTexture(&binary_grass_D_bmp_start, &grass_DTexture);
However the texture does not load and I just get a whitish grey surface.
EDIT: I know this was not my original question, however I am having difficulty using mipmaps. I modified my loadTexture function to this:
short loadTexture(char *imageData[], GLuint *texture, int width, int height) {
glEnable(GL_TEXTURE_2D);
glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
*texture = SOIL_load_OGL_texture_from_memory(imageData, sizeof(*imageData), SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_MIPMAPS);
//gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, imageData);
//glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, width, height);
//glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, imageData);
//glGenerateMipmap(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_2D);
return 1;
}
This time, the exe crashes as soon as it is run. I am also greeted with the following warning, which could be the cause of this (probably missing an * or an & somewhere):
init.c:76:2: warning: passing argument 1 of 'loadTexture' from incompatible poin
ter type [enabled by default]
loadTexture.h:1:7: note: expected 'char **' but argument is of type 'char (*)[]'
I have managed to narrow the crash to the SOIL_load_OGL_texture_from_memory call.

GL_TEXTURE_MIN_FILTER defaults to GL_NEAREST_MIPMAP_LINEAR​.
Upload some mipmaps or switch to GL_NEAREST or GL_LINEAR.

Related

Open GL ES 2 - glFramebufferTexture2D with Incomplete Missing Attachment error

I'm new to OpenGL/GLES, I got Incomplete Missing Attachment error when generate framebuffer from EGLImageKHR with below code:
GLuint texture;
GLuint framebuffer;
EGLImageKHR image = eglCreateImageKHR(display,
EGL_NO_CONTEXT,
EGL_NATIVE_PIXMAP_KHR,
(EGLClientBuffer)&pixmap,
NULL);
assert(image != EGL_NO_IMAGE_KHR);
glGenTextures(1, &texture);
glGenTextures(1, &framebuffer);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_EXTERNAL_OES,
texture,
0);
glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
eglDestroyImageKHR(display,image);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
I got GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT when using:
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_EXTERNAL_OES,
texture,
0);
and GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT when changing texture to GL_TEXTURE_2D:
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
texture,
0);
The image and texture is correct as I can display correctly. I don't know what I'm missing here.
I just found the answer, as it is explained in Raspi forum:
Can't render to render buffer
We have to use GL_TEXTURE_2D in this function:
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
texture,
0);
and have to create an empty texture GL_TEXTURE_2D to bind our framebuffer to that texture before rendering. GL_TEXTURE_EXTERNAL_OES and GL_TEXTURE_2D are different textures, cannot mix them together.

GLSL Shader going black when I try to sample a texture

I render a triangle strip this way, and with basic bypass shaders all is working fine:
EDIT:
I added TextCoords and modified the shaders , I keep getting the same result, my 3d objects are going black!
UPDATED CODE:
// Dibuixem tots els prismes
glBegin(GL_TRIANGLE_STRIP);
for(i=0;i<num_elems;i++) {
for(j=0;j<num_vertices;j++) {
glNormal3fv((GLfloat *)(a+j*2));
glTexCoord2f(0.0f, 0.0f);
glVertex3fv((GLfloat *)(a+j*2+1));
glTexCoord2f(1.0f, 0.0f);
glNormal3fv((GLfloat *)(b+j*2));
glTexCoord2f(1.0f, 1.0f);
glVertex3fv((GLfloat *)(b+j*2+1));
}
glNormal3fv((GLfloat *)(a));
glTexCoord2f(0.0f, 1.0f);
glVertex3fv((GLfloat *)(a+1));
glNormal3fv((GLfloat *)(b));
glTexCoord2f(0.0f, 0.0f);
glVertex3fv((GLfloat *)(b+1));
a+=face_size;
b+=face_size;
}
glEnd();
And I am trying to attach a texture to my shaders, but I can't figure out how to pass the texture.
I create and add the texture to my program this way. Texture data is verified
array with format unsigned char data[imageSize];:
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glActiveTexture(GL_TEXTURE0); // Texture unit 0
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0,GL_BGR, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
This is what I read in another posts with the same issue and I added to my code after compiling my shaders and generating my program without errors.
Tutorials tend to dismiss this information (how you say to your shader the name and location of your binded texture).
GLuint t1Location = glGetUniformLocation(programID, "tex1");
glUniform1i(t1Location, 0);
And my shaders UPDATED CODE:
#define GLSL(version, shader) "#version " #version "\n" #shader
const char* vert = GLSL
(
110,
varying vec4 position;
varying vec3 normal;
varying out vec4 texCoord;
varying vec2 coord;
void main()
{
position = gl_ModelViewMatrix * gl_Vertex;
normal = normalize( gl_NormalMatrix * gl_Normal.xyz );
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
coord = vec2(gl_MultiTexCoord0);
}
);
const char* frag = GLSL
(
110,
uniform sampler2D tex1;
varying vec4 position;
varying vec3 normal;
varying vec2 coord;
void main()
{
gl_FragColor = texture2D(tex1, coord);
}
);
EDIT2:
I am setting up gl this way:(maybe something is conflicting with my texture shader, but I don't think so!
/* set up depth-buffering */
glEnable(GL_DEPTH_TEST);
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
/* set up lights */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glShadeModel(GL_SMOOTH);
GLfloat lightpos[] = { 3.0, 0.0, 1.0, 0.0 };
GLfloat lightcolor[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat ambcolor[] = { 0.5, 0.5, 0.5, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambcolor);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable (GL_COLOR_MATERIAL);
glLightfv (GL_LIGHT0,GL_POSITION,lightpos);
glLightfv (GL_LIGHT0,GL_AMBIENT,ambcolor);
glLightfv (GL_LIGHT0,GL_DIFFUSE,lightcolor);
glLightfv (GL_LIGHT0,GL_SPECULAR,lightcolor);
glLightf (GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.2);
glLightf (GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0);
glLightf (GL_LIGHT0,GL_QUADRATIC_ATTENUATION,1.0);
glEnable (GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
Replacing gl_FragColor by a flat color is working fine.
I know maybe is related to coord parameter but I am trying all the stuff I found and nothing is working for me.
The internal texture format GL_BGR is not valid. GL_BGR is a valid for the format of the source texture, but the internal representation has to be GL_RGB.
See glTexImage2D.
Adapt your code like this:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
See the Khronos reference page GLAPI/glTexImage2D which says:
To define texture images, call glTexImage2D. The arguments describe the parameters of the texture image, such as height, width, width of the border, level-of-detail number (see glTexParameter), and number of color components provided. The last three arguments describe how the image is represented in memory.
format​ determines the composition of each element in data​. It can assume one of these symbolic values:
GL_BGR:
Each element is an RGB triple. The GL converts it to floating point and assembles it into an RGBA element by attaching 1 for alpha. Each component is clamped to the range [0,1].

Cannot show texture in OpenGL 4.3 using VertexArrayObject

I'm knocking my head on this code since two days ago. It seems that there's no error of any sort creating buffers or textures, but the texture doesn't show.
Here is my code for the texture load:
struct image2d texImage = loadBMPImage(filePath);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texImage.width, texImage.height, 0, GL_RGB, GL_UNSIGNED_BYTE, texImage.pixels);
free(texImage.pixels);
The image2d structure is this one
struct image2d{
unsigned int width, height;
unsigned char* pixels;
};
Yes, I'm enabling GL_TEXTURE_2D via glEnable()
Then my mesh is drawn wiith this code
void MeshDraw(Mesh m, int renderType)
{
glBindVertexArray(m.external->vao);
glBindBuffer(GL_ARRAY_BUFFER, m.external->vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, (void*)12);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.external->ibo);
glDrawElements(GL_TRIANGLES, m.external->sizeFc * 3, GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
return;
}
And finally here is my vertex shader
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 inTexCoord;
uniform mat4 transform;
out vec2 texCoord;
out vec3 outPos;
void main(void)
{
outPos = position;
gl_Position = transform * vec4(position, 1.0);
texCoord = inTexCoord;
}
And here is my fragment shader
#version 430 core
out vec4 drawColor;
in vec2 texCoord;
in vec3 outPos;
uniform sampler2D sampler;
void main(void)
{
drawColor = texture(sampler, texCoord);
//drawColor = vec4(clamp(outPos, 0.0, 1.0), 1.0);
}
If you need to look at the whole project I'm posting it here
I'll appreciate any kind of help :)
Additional code (which is also in download if anyone wants to see it)
void initOpenGL()
{
printf("OpenGL version: %s\n",glGetString(GL_VERSION));
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_FRAMEBUFFER_SRGB);
return;
}
This is called right after making the context and initializing glew.
void RenderGame(Game g)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderBind(g.external->sh);
setUniformmat4(g.external->sh, "transform", TransformGetProjectedTransformation(g.external->transf));
TextureBind(g.external->texture);
MeshDraw(g.external->msh, GL_TRIANGLES);
glFlush();
glfwSwapBuffers(WindowGetHandler(g.external->window));
return;
}
And this is my render method.
Your texture is not mipmap-complete, but you are still using the default GL_NEAREST_MIPMAP_LINEAR minification filter, so sampling the texture will fail.
You try to set it to GL_NEAREST, but this sqeuence of operations is wrong:
glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);
In the GL, the texture sampler state is part of the texture object itself (there are also separate sampler objects available nowadays which override that state, but you don't seem to use them either), and glTexParameteri() affects the currently bound texture object at the time of the call. I don't know if some texture is bound at that time, or none at all - but certainly, the new texture is not, so it will stick with the inital default of GL_NEAREST_MIPMAP_LINEAR...
SOLUTION It seems that #peppe was right all the time. Just to be meticulous i set the sampler to 0 with the setuniform call and it workef. The problem is that it didn't work as expected, and it was because the function that loads the bitmap file that was wrong. Now it works like a charm :) Thank you guys!

Geometry Image Creation and general handling

I would like some entry level information about the OpenGI library which converts a 3D mesh to a 2D texture map.
http://opengi.sourceforge.net/doc/index.html
At this point i have implemented an example on a specific mesh and it seems to work perfectly. I would like to process this image further and i need to export it as a bmp file.
I have imported a mesh and created:
texture with the parameterized geometry
texture with the normals
At this point i am confused how to handle them. They are stored as OpenGL textures.
Here's the source code:
glBindTexture(GL_TEXTURE_2D, uiTex[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
giGenImages(3, gim);
giBindImage(gim[0]);
giImageGLTextureData(res, res, 4, GL_FLOAT, uiTex[0]);
giAttribImage(0, gim[0]);
giAttribSamplerParameteri(0, GI_SAMPLING_MODE, GI_SAMPLE_DEFAULT);
giSample();
How can I export the texture?

GLSL Texture Mapping Results in a Solid Color

I'm trying to write some basic shaders to map a ppm file to my shapes. Unfortunately, instead of a nice multicoloured texture (I'm using a stone brick pattern), I get a solid shade of dark purple.
Here's my code:
Init:
printf("Using %d: Texture shading\n", shaderType);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &textName);
int w, h;
texture = glmReadPPM("brick.ppm", &w, &h);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
printf("W%dH%d\n", w, h);
glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textName);
programID = LoadShaders("text.vert", "text.frag");
Render:
glClearColor( 0.6f, 0.85f, 1.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
/*Unrelated code here*/
glUseProgram(programID);
varloc = glGetUniformLocation(programID,"texture1");
glUniform1i(varloc, textName);
glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, &cutOff);
gluLookAt (posx, posy, zoom,
lookx,looky,0,
0,1,0);
glRotatef(anglex,0.0f,1.0f,0.0f);
glRotatef(angley,1.0f,0.0f,0.0f);
renderTriangles(); //Renders mountains from a list using intermediate mode
// Yes, I know it's deprecated
glutSwapBuffers();
glui->sync_live();
glUseProgram(0);
Vertex Shader:
varying vec2 uv;
void main() {
uv = vec2(gl_MultiTexCoord0.st);
gl_Position = ftransform();
}
Fragment Shader:
uniform sampler2D texture1;
varying vec2 uv;
void main() {
gl_FragColor = texture2D(texture1, uv);
}
Does anyone see any problems here? I can't seem to figure it out.
I tried with a basic White and Read 2x2 float, but again, I got one colour. It was a light red.
If you're getting a single colour for the whole object, there might be something wrong with the texture coordinates. I would try looking at them and see if they're correct. You can do that by modifying your fragment shader like this:
gl_FragColor = vec3(uv.xy, 0);
If your whole image is still rendered using one colour, there is something wrong with the way you're sending texture coordinates across. You're using some deprecated functionality (immediate mode, gl_MultiTexCoord0), maybe it's not working together as you would expect:
"Keep in mind that for GLSL 1.30, you should define your own vertex attribute." http://www.opengl.org/wiki/GLSL_:_common_mistakes
It looks like you are binding the texture after you have all of the other texture functions. You should put the call to glBindTexture right after the call to glGenTextures because you have to bind a texture before you can upload the image into it. The other problem is that instead of setting the uniform variable for your sampler to textName in the call to glUniform1i(varloc, textName) you should set it to 0 because that variable represents the active texture unit and you used glActiveTexture(GL_TEXTURE0);

Resources