I am trying to implement shadow mapping in my OpenGL engine using this tutorial : http://www.fabiensanglard.net/shadowmapping/index.php
I don't have any problems while making the shadow map (i think ). But using it the scene is totally shadowed.
The way I am rendering my scene is as follows:
Set up the depth FBO
GLuint sdepthtex;
GLuint sframebuffer ;
glGenTextures(1, &sdepthtex);
glBindTexture(GL_TEXTURE_2D, sdepthtex);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, sdepthtex, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
displayMessage("Error loading the Depth Framebuffer");
return;
}
Make the ModelViewProjection matrix from light's perspective and store it in a shadowMatrix variable.
The function i use :
Matrix getMVPmatrix(vector3 position,vector3 lookat )
{
glPushMatrix();
double projection[16];
double modelView[16];
SDL_Surface*screen = SDL_GetVideoSurface();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(FOVY,screen->w/screen->h,NEAR,FAR);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
gluLookAt(position.x,position.y,position.z,lookat.x,lookat.y,lookat.z,0,1,0);
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
Matrix m1(projection);
Matrix m2(modelView);
glPopMatrix();
return m1*m2;
}
Render the scene in the depth framebuffer. The shaders :
Vertex Shader:
uniform mat4 shadowMatrix;
void main()
{
gl_Position = shadowMatrix*gl_Vertex;
}
Fragment Shader:
void main(void)
{
gl_FragDepth = gl_FragCoord.z;
}
For my 3 boxes scene, the linearized depth look like this :
http://www.2shared.com/photo/IExy9aUo/Depth.html
So i think the shadowMatrix and the depth rendering are right.
The last pass is just about drawing the scene with the shadow map
Vertex Shader:
varying vec4 ShadowCoord;
uniform mat4 shadowMatrix;
mat4 biasMatrix = mat4(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);
void main (void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
gl_Position = ftransform();
ShadowCoord = biasMatrix*shadowMatrix *vec4(gl_Vertex.xyz,1.0);
}
Fragment Shader:
uniform sampler2D tex;
uniform sampler2D shadowtex;//the non linearized depth texture we made in the 3rd step.
varying vec4 ShadowCoord;
float getShadowFactor(void)
{
vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;
shadowCoordinateWdivide.z += 0.0005;
float distanceFromLight = texture2D(shadowtex,shadowCoordinateWdivide.st).z;
float shadow = 1.0;
if (ShadowCoord.w > 0.0)
shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 :1.0 ;
return shadow ;
}
void main (void)
{
gl_FragColor =texture2D(tex, gl_TexCoord[0].st);
gl_FragColor.rgb *= getShadowFactor() ;//add shadows Here
}
The result ? all my scene is shadowed !
It looks like your code has an inconsistency between the texture setup and the shader. In the texture setup code, you have this:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
When GL_TEXTURE_COMPARE_FUNC is not GL_NONE, you need to use a shadow texture sampler in your shader code. But in your fragment shader, you use a regular sampler for this texture:
uniform sampler2D shadowtex;
This needs to be changed to this to be compatible with the texture settings:
uniform sampler2DShadow shadowtex;
To match the type, shadow2D() is then used instead of texture2D() to sample the texture.
The other option is that you keep GL_TEXTURE_COMPARE_FUNC at its default value of GL_NONE. This is then consistent with using a sampler2D for sampling.
Related
I cannot get sampler3D value in my GLSL fragment shader.
I am writing a shader in GLSL and want to take sampler3D (3d texture) as volume data and do volume rendering. However, seems I cannot bind 3d texture to my shader's sampler3D. texture3D() always returns (0,0,0,0) on shader side. But on my application side, I can use glGetTexImage to get the data.
Application Side (dS is a Shader class object):
dS.use();
dS.setInt("volumeData", 0);
uint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, texture);
float data[64];
for (int i = 0; i < 64; ++i) data[i] = 1.0f;
glTexImage3D(GL_TEXTURE_3D, 0, GL_R16F, 4, 4, 4, 0, GL_RED, GL_FLOAT, data);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_3D, 0);
float read[64];
glBindTexture(GL_TEXTURE_3D, texture);
glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_FLOAT, read);
std::cout << read[0] << "," << read[63] << std::endl; // 1,1
glBindTexture(GL_TEXTURE_3D, 0);
// When drawing.
dS.use();
dS.setMat4("model", glm::mat4(1.0f));
dS.setMat4("view", view);
dS.setMat4("projection", projection);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, texture);
cube.draw();
Vertex Shader
#version 330 core
// for snow rendering
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
Fragment Shader
#version 330
out vec4 FragColor;
uniform sampler3D volumeData;
void main()
{
ivec3 size = textureSize(volumeData, 0);
float c = texture3D(volumeData, vec3(0)).x;
if (size.x == 1)
FragColor = vec4(1.0, 0.0, c, 1.0);
else if (size.x > 2)
FragColor = vec4(0.0, 1.0, 0.0, 1.0);
else if (size.x == 0)
FragColor = vec4(0.0, 0.0, 1.0, 1.0);
else
FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
I only got a red cube, which means size.x == 1 and texture3D returns 0, which is expected to be size.x == 4 and texture3D returns 1.0
I used similar method for 2d texture and it works. So I guess my Shader class is right. And I also tried to add glEnable(GL_TEXTURE_3D) before I did any 3d texture operation.
And I am not sure if this helps: I used glfw-3.2.1 WIN64 and glad.
I solved it.
It's a really stupid typo.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
should use GL_TEXTURE_3D instead of GL_TEXTURE_2D.
And since GL_TEXTURE_MIN_FILTER default state is GL_NEAREST_MIPMAP_LINEAR. It leads to mipmap incompleteness.
I'm having a problem with post processing in my deferred renderer.
When I'm applying an effect like bloom on top of my scene, the bottom of the bloom effect texture leaks into the top of my screen, the top of the texture leaks into the bottom of the screen, the left into the right of the screen and so on.
Looks like the uv coords don't get clamped correctly, although I thought I'd have set that all correctly.
The bloom effect in this case is created in a lower resolution and the gets upsampled using linear filtering.
This image that shows the problem:
I render the postprocessing effects using a simple quad:
glm::vec3(-1.f, -1.f, 0.f),
glm::vec3(1.f, -1.f, 0.f),
glm::vec3(1.f, 1.f, 0.f),
glm::vec3(-1.f, 1.f, 0.f)
This is the vertex shader I use to render the quad:
#version 430 core
layout(location = 0) in vec3 POSITION;
noperspective out vec2 tex_coord;
void main(void)
{
tex_coord = POSITION.xy * 0.5 + 0.5;
gl_Position = vec4(POSITION.xy, 0.0, 1.0);
}
And if course in the fragment shader I'm doing something like this:
#version 430 core
uniform sampler2D uTexture;
noperspective in vec2 tex_coord;
out vec4 frag_color;
void main(void)
{
frag_color = texture(uTexture, tex_coord);
}
The effect got rendered into a frame buffer object which got set up like this:
glGenFramebuffers(1, &_filterFbo);
glBindFramebuffer(GL_FRAMEBUFFER, _filterFbo);
// filter texture
glGenTextures(1, &_filterTexture);
glBindTexture(GL_TEXTURE_2D, _filterTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, _effectWidth, _effectHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _filterTexture, 0);
I really don't know what's the problem here, I hope anyone got an idea.
I can't get shadow mapping to work in my application. I try to render a quad bike and view its shadow on a floor beneath it.
Here's some of my code.
Texture creation:
// Create a depth texture
glGenTextures(1, &depth_texture);
glBindTexture(GL_TEXTURE_2D, depth_texture);
// Allocate storage for the texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32 ,1600, 900, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// Set the default filtering modes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Set up wrapping modes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
// Create FBO to render depth into
glGenFramebuffers(1, &depth_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
// Attach the depth texture to it
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
depth_texture, 0);
// Disable color rendering as there are no color attachments
glDrawBuffer(GL_NONE);
//check fbo status
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(result != GL_FRAMEBUFFER_COMPLETE)
throw std::runtime_error("shadow mapping framebuffer error");
//bind default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
render to depth texture:
progShadow.Use();
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
glClear(GL_DEPTH_BUFFER_BIT);
glm::mat4 shadowProjection = glm::frustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 100.0f);
glm::mat4 shadowView = glm::lookAt(light.position, glm::vec3(0,0,0), glm::vec3(0,1,0));
glm::mat4 shadowModel(1);
if(g_rotate)
shadowModel = glm::rotate((float)clock() / (float)CLOCKS_PER_SEC, glm::vec3(0,1,0));
glm::mat4 shadowMVP = shadowProjection * shadowView * shadowModel;
progShadow.SetUniform("MVPMatrix", shadowMVP);
quadBike.Draw();
I also use a "test" shader program that renders my depth texture. Here's what it looks like.
So I guess I'm good until now.
Now I render the scene normally.
glBindTexture(GL_TEXTURE_2D, depth_texture);
prog.Use();//main program
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 shadowBias = glm::mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
glm::mat4 ShadowBiasMVP = shadowBias * shadowMVP;
prog.SetUniform("ShadowBiasMVP", ShadowBiasMVP);
//draw quadBike and floor
...
Relevant parts of my vertex shader:
#version 430
...
out vec4 shadowCoord;
void main()
{
gl_Position = ProjectionMatrix * CameraMatrix * ModelMatrix * vec4(vertex, 1.0);
shadowCoord = ShadowBiasMVP * vec4(vertex, 1.0);
...
}
Relevant parts of my fragment shader:
#version 430
...
uniform sampler2D shadowMap;
in vec4 shadowCoord;
void main()
{
...
float visibility = 1.0;
if ( texture(shadowMap, shadowCoord.xy).z < shadowCoord.z)
visibility = 0.0;
...
}
Now the problem is that I get a scene that is fully dark as if it was all covered by shadow. Only when the light is really close to the quad bike, it renders it normally. (the depth texture is visible on the right side because it's rendered with a different program. I use it for testing)
What am I doing wrong?
You should read a grayscale depthtexture at the first component.
texture(shadowMap, shadowCoord.xy).r or
texture(shadowMap, shadowCoord.xy).x
The Shadow Coordinates should be dehomogenized (divided by w) after interpolation.
-> in fragment shader: shadowPos = shadowPos/shadowPos.w;
If no other techniques like polygon offset is used you need to substract a bias from the shadow depth value to prevent self shadowing.
Here is an example function to calculate shadows in fragment shader. Note: It is part of a deferred renderer, that is why matrix multiplication is done in the fragment shader.
float calculateShadow(vec3 position){
vec4 shadowPos = depthBiasMV * vec4(position,1);
shadowPos = shadowPos/shadowPos.w;
float bias = 0.0012;
float visibility = 1.0f;
if ((shadowPos.x < 0 || shadowPos.x > 1 || shadowPos.y < 0 || shadowPos.y > 1 || shadowPos.z < 0 || shadowPos.z > 1)){
visibility = 1.0f;
}else{
float shadowDepth = texture(depthTex, shadowPos.xy).r;
if(shadowDepth<shadowPos.z-bias)
visibility = 0.0f;
}
return visibility;
}
I am following the shadow tutorial on http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/ and I can view the depth value in the depth texture when rendered to a screen aligned quad. The problem is when I sample from this depth texture I get only one value.
This is how I setup the depth texture FBO; the size of the texture is set to the window size. I'm not sure if this is part of the problem, but if I half the dimensions of the depth texture and try to view that, I end up seeing a corner quarter of the view. I thought textures are always accessed from [0,1]?
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0,
GL_DEPTH_COMPONENT,
fbWidth,
fbHeight,
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderedTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
assert(false && "framebuffer NOT OK");
1st pass vertex shader
#version 150 core
in vec3 position;
uniform mat4 model;
void main(){
gl_Position = model * vec4(position,1.0);
}
1st pass fragment shader
#version 150 core
void main(){ //letting the default gl_FragDepth assignment happen
}
2nd pass vertex shader
#version 150 core
in vec3 position;
out vec4 shadowCoord;
uniform mat4 model;
uniform mat4 camera;
uniform mat4 DepthBiasMVP;
void main() {
gl_Position = camera * model * vec4(position, 1.0);
shadowCoord = DepthBiasMVP * vec4(position, 1.0);
}
2nd pass fragment shader: the stuck at 1 or 0 problems are in the comments, along with the variations I've tried
#version 150 core
in vec4 shadowCoord;
uniform mat4 model;
out vec4 outColor;
//tried both types
//uniform sampler2D shadowMap;
uniform sampler2DShadow shadowMap;
void main() {
vec3 finalColor = ...
float visibility = 1.0;
vec3 P = shadowCoord.xyz / shadowCoord.w; //doesn't work
// vec3 P =vec3(shadowCoord.x, shadowCoord.y, shadowCoord.z); //no difference
// vec3 P = vec3(shadowCoord.xy, shadowCoord.z / shadowCoord.w); //also no difference
visibility = texture( shadowMap, P); // always 1
// //when shadowMap is set to sampler2D
// vec3 textureCoord = shadowCoord.xyz/ shadowCoord.w;
// if (texture(shadowMap, shadowCoord.xy).z ==0) //always 0
// if (texture(shadowMap, shadowCoord.xy).x ==0) //always 1
// if (shadowCoord.z == 0) //always 0
// visibility = 0.06; //
finalColor *= visibility;
outColor = vec4(finalColor, 1.0);
}
This is how I call the passes, the object I am looking at is located at the origin
glm::vec3 srcPerspective(0,0,-4);
glm::mat4 depthProjectionMatrix = glm::ortho<float>(-1,1,-1,1,-10,10);
glm::mat4 depthViewMatrix = glm::lookAt(srcPerspective, glm::vec3(0,0,0), glm::vec3(0,1,0));
//pass 1
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shadowMap.shaderProgram);
depthMVP = depthProjectionMatrix * depthViewMatrix * modelMatrix;
shadowMap.drawIndexed(world, camera, depthMVP, shapes[shipIdx].mesh.indices.data());
//pass 2
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glm::mat4 biasMatrix(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);
glm::mat4 depthBiasMVP = biasMatrix * depthMVP;
glUniformMatrix4fv(loc, 1, GL_FALSE, &depthBiasMVP[0][0]);
ship.drawIndexed(world, camera, lightPos, mvp, shipColor, shapes[shipIdx].mesh.indices.data());
In GLSL version 110 i can get coordinate in gl_TexCoord[] but it's deprecated in 150.
OpenGL code:
shader.setupShaderFromFile(GL_VERTEX_SHADER, "t.vert");
shader.setupShaderFromFile(GL_FRAGMENT_SHADER, "t.frag");
shader.linkProgram();
glGetFloatv(GL_MODELVIEW_MATRIX, modelview_mat_);
glGetFloatv(GL_PROJECTION_MATRIX, projectionview_mat_);
shader.begin();
glUniformMatrix4fv( glGetUniformLocation(shader.getProgram(), "MVMatrix"), 1, GL_FALSE, modelview_mat_);
glUniformMatrix4fv( glGetUniformLocation(shader.getProgram(), "MPMatrix"), 1, GL_FALSE, projectionview_mat_);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);glVertex2f(0, 0);
glTexCoord2f(1, 0);glVertex2f(100, 0);
glTexCoord2f(1, 1);glVertex2f(100, 100);
glTexCoord2f(0, 1);glVertex2f(0, 100);
glEnd();
shader.end();
Shader Code:
VERTEX-
#version 150
in vec3 in_vertex;
in vec2 in_coord;
uniform mat4 MVMatrix;
uniform mat4 MPMatrix;
out vec2 tex_coord;
void main()
{
vec4 v = vec4( in_vertex, 1.0 );
tex_coord = in_coord;
gl_Position = MPMatrix * MVMatrix * v;
}
FRAGMENT:
#version 150
in vec2 tex_coord;
out vec4 frgcolor;
void main()
{
frgcolor = vec4( tex_coord, 0.0, 1.0);
}
final screen is a red quad.
How to pass texture coordinate to shader? or my code is wrong?
If you don't want to use the deprecated methods, you'll have to stop using glTexCoord2f, and use a custom attribute.
If you want to stay with immediate mode, you'll use glVertexAttrib2f.
You pair this up with your new variable 'in_coord' by quering the index after shader linking:
int program = glCreateProgram();
//create shader as normal
int texcoord_index = glGetAttribLocation(program, "in_coord");
glBegin(GL_QUADS);
glVertexAttrib2f(texcoord_index, 0, 0); ...
If you want to use VA/VBO instead, the functions you use instead is glEnableVertexAttribArray/glVertexAttribPointer
in your case just look into gl_TexCoord[0] in your vertex shader. Definitely works with shader model 1.5
in C++:
glActiveTexture(GL_TEXTURE0 );
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);glVertex2f(0, 0);
glTexCoord2f(1, 0);glVertex2f(100, 0);
glTexCoord2f(1, 1);glVertex2f(100, 100);
glTexCoord2f(0, 1);glVertex2f(0, 100);
glEnd();
in vertex shader:
gl_TexCoord[0]=gl_MultiTexCoord0;
in fragment shader:
vec4 c = texture2D(texSampler, gl_TexCoord[0].st );