简体   繁体   中英

OpenGL 3.3 texture mapping triangle

I have had little luck simply texturing a triangle in Opengl 3.3 (core) over the last few days. I can successfully render the vertices and colors, but texturing seems to be problematic. My current task/goal is vertices and texture coordinates only (no colors).

Since I create the test texture by hand, it should show up as a 16x16 white/red checkered triangle.

Strange behavior: If I use GL_CLAMP_TO_EDGE, it's all WHITE. If I use GL_REPEAT, it comes out pink (white + red)...

vertex shader:

#version 330
layout (location = 0) in vec3 vertPos;
layout (location = 1) in vec2 texCoord;
out vec2 tex;
uniform mat4 viewMatrix, projMatrix;
void main()
{
  gl_Position = projMatrix * viewMatrix * vec4(vertPos,1.0);
  tex = texCoord;
};

fragment shader:

#version 330
out vec4 Color;
in vec2 tex;
uniform sampler2D texsampler;
void main() {
  Color = texture(texsampler, tex);
};

state initialization code (these are in order as shown):

  glPixelStorei(GL_UNPACK_ALIGNMENT,1);
  //glPixelStorei(GL_PACK_ALIGNMENT,1);

  glFrontFace(GL_CW);  // clockwise oriented polys are front faces
  glCullFace(GL_BACK); // cull out the inner polygons... Set Culling property appropriately

  glLineWidth(1.0f); // for any wireframe

  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // color 1.0f is fully opaque, 0.0f is transparent

  glDepthFunc(GL_LEQUAL);
  glDepthRange(0,1); // default

  glDisable(GL_CULL_FACE);

  glClearColor(0.0f,0.0f,0.0f,1.0f); // set clear color to black

  glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); // filled polys

texture initialization:

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

  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_BASE_LEVEL, 0);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 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);

    uint32 buf[16*16];
    uint32 x;
    for (x=0;x<16*16;) {
      buf[x++] = 0xFFFFFFFF;
      buf[x++] = 0xFFFF0000;
    }

    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8 , 16, 16, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)buf);

  glBindTexture (GL_TEXTURE_2D, 0);

shader initialization:

  shader1 = new_gl_shader_program(vert_src,frag_src);
  if (shader1) {
    if (link_gl_shader_program(shader1)) {

      projMatrixLoc = glGetUniformLocation(shader1, "projMatrix");
      viewMatrixLoc = glGetUniformLocation(shader1, "viewMatrix");

      sampler2dLoc = glGetUniformLocation(shader1, "texsampler");

      glBindFragDataLocation( shader1, 0, "Color" ); // ADDED.

    }
    else {
      print("LINK ERROR: %s\n",get_gl_shader_msg());
      delete_gl_shader_program(shader1);
      shader1 = 0;
    }
  }
  else
    print("COMPILE/MISC ERROR: %s\n",get_gl_shader_msg());

  if (!shader1)
    return;

buffer data initialization:

typedef struct MESH_VERT_3D {
  float x,y,z;
  float u,v;
}MESH_VERT_3D;

MESH_VERT_3D meshbuf[3]; // total of 15 floats

    meshbuf[0].x = 0.0f;
    meshbuf[0].y = 0.0f;
    meshbuf[0].z = 0.0f;

    meshbuf[1].x = 1.0f;
    meshbuf[1].y = 0.0f;
    meshbuf[1].z = 0.0f;

    meshbuf[2].x = 1.0f;
    meshbuf[2].y = 0.0f;
    meshbuf[2].z = 1.0f;

    meshbuf[0].u = 0.0f;
    meshbuf[0].v = 1.0f;
    meshbuf[1].u = 1.0f;
    meshbuf[1].v = 1.0f;
    meshbuf[2].u = 1.0f;
    meshbuf[2].v = 0.0f;

    glGenBuffers(1, &vboid);
    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glBufferData(GL_ARRAY_BUFFER, sizeof(meshbuf), meshbuf, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

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

    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float)*5, null);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(float)*5, (void*)(sizeof(float)*3));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

render:

  gls_begin_3d(&glscene);
  use_gl_shader_program(shader1);

  glUniformMatrix4fv(projMatrixLoc,  1, GL_FALSE, gls_get_projection_matrix());
  glUniformMatrix4fv(viewMatrixLoc,  1, GL_FALSE, gls_get_modelview_matrix());

  glActiveTexture(GL_TEXTURE0);
  glBindTexture (GL_TEXTURE_2D, texid1);
  glUniform1i(sampler2dLoc, 0);

  glBindVertexArray(vaoHandle);

  glDrawArrays(GL_TRIANGLES, 0, 3 );

  glBindTexture (GL_TEXTURE_2D, 0);

  use_gl_shader_program(0);
  gls_end_3d(&glscene);

Issue 1:

You should bind your fragment shader output variable Color to a fragment data location:

glBindFragDataLocation( shader1, 0, "Color" );

Otherwise OpenGL does not know where the results of your shader program are located.

Issue 2:

You create a second buffer object for your texture coordinates: glGenBuffers(1, &tboid); However, everything should be put into a single VBO.

Issue 3:

You pass null to glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(float)*5, null); However, the beginning of texture coordinates is not 0. It is sizeof(float)*3 .

Issue 4:

In the vertex shader, you have out vec2 texCoordOut; . However, in the fragment shader, you use in vec2 tex; . The names should match.

In the vertex shader, you have

out vec2 texCoordOut;

but in the fragment shader, you use

in vec2 tex;

This is not going to work, since you are required to use the same name so the GL can match it up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM