# Mariusz Pilipczuk

Member

40

174 Neutral

• Rank
Member

• Interests
Programming

## Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

1. ## Normal mapping: tangents vectors clearly incorrect

The commented-out last parts of the fragment shader show how the data is mapped to colors. So for example the texture coordinates have all blue set to full. uvec and vvec are the tangent and bitangent.

Bump?
3. ## OpenGL Normal mapping: tangents vectors clearly incorrect

Hello. I'm trying to implement normal mapping. I've been following this: http://ogldev.atspace.co.uk/www/tutorial26/tutorial26.html The problem is that my tangent vectors appear rather obviously wrong. But only one of them, never both. Here's my code for calculating the tangents: this.makeTriangle = function(a, b, c) { var edge1 = VectorSub(b.pos, a.pos); var edge2 = VectorSub(c.pos, a.pos); var deltaU1 = b.texCoords[0] - a.texCoords[0]; var deltaV1 = b.texCoords[1] - a.texCoords[1]; var deltaU2 = c.texCoords[0] - a.texCoords[0]; var deltaV2 = c.texCoords[1] - a.texCoords[1]; var f = 1.0 / (deltaU1 * deltaV2 - deltaU2 * deltaV1); var vvec = VectorNormal([ f * (deltaV2 * edge1[0] - deltaV1 * edge2[0]), f * (deltaV2 * edge1[1] - deltaV1 * edge2[1]), f * (deltaV2 * edge1[2] - deltaV1 * edge2[2]), 0.0 ]); var uvec = VectorNormal([ f * (-deltaU2 * edge1[0] - deltaU1 * edge2[0]), f * (-deltaU2 * edge1[1] - deltaU1 * edge2[1]), f * (-deltaU2 * edge1[2] - deltaU1 * edge2[2]), 0.0 ]); if (VectorDot(VectorCross(a.normal, uvec), vvec) < 0.0) { uvec = VectorScale(uvec, -1.0); }; /* console.log("Normal: "); console.log(a.normal); console.log("UVec: "); console.log(uvec); console.log("VVec: "); console.log(vvec); */ this.emitVertex(a, uvec, vvec); this.emitVertex(b, uvec, vvec); this.emitVertex(c, uvec, vvec); }; My vertex shader: precision mediump float; uniform mat4 matProj; uniform mat4 matView; uniform mat4 matModel; in vec4 attrVertex; in vec2 attrTexCoords; in vec3 attrNormal; in vec3 attrUVec; in vec3 attrVVec; out vec2 fTexCoords; out vec4 fNormalCamera; out vec4 fWorldPos; out vec4 fWorldNormal; out vec4 fWorldUVec; out vec4 fWorldVVec; void main() { fTexCoords = attrTexCoords; fNormalCamera = matView * matModel * vec4(attrNormal, 0.0); vec3 uvec = attrUVec; vec3 vvec = attrVVec; fWorldPos = matModel * attrVertex; fWorldNormal = matModel * vec4(attrNormal, 0.0); fWorldUVec = matModel * vec4(uvec, 0.0); fWorldVVec = matModel * vec4(vvec, 0.0); gl_Position = matProj * matView * matModel * attrVertex; } And finally the fragment shader: precision mediump float; uniform sampler2D texImage; uniform sampler2D texNormal; uniform float sunFactor; uniform mat4 matView; in vec2 fTexCoords; in vec4 fNormalCamera; in vec4 fWorldPos; in vec4 fWorldNormal; in vec4 fWorldUVec; in vec4 fWorldVVec; out vec4 outColor; vec4 calcPointLight(in vec4 normal, in vec4 source, in vec4 color, in float intensity) { vec4 lightVec = source - fWorldPos; float sqdist = dot(lightVec, lightVec); vec4 lightDir = normalize(lightVec); return color * dot(normal, lightDir) * (1.0 / sqdist) * intensity; } vec4 calcLights(vec4 pNormal) { vec4 result = vec4(0.0, 0.0, 0.0, 0.0); \${CALC_LIGHTS} return result; } void main() { vec4 surfNormal = vec4(cross(vec3(fWorldUVec), vec3(fWorldVVec)), 0.0); vec2 bumpCoords = fTexCoords; vec4 bumpNormal = texture(texNormal, bumpCoords); bumpNormal = (2.0 * bumpNormal - vec4(1.0, 1.0, 1.0, 0.0)) * vec4(1.0, 1.0, 1.0, 1.0); bumpNormal.w = 0.0; mat4 bumpMat = mat4(fWorldUVec, fWorldVVec, fWorldNormal, vec4(0.0, 0.0, 0.0, 1.0)); vec4 realNormal = normalize(bumpMat * bumpNormal); vec4 realCameraNormal = matView * realNormal; float intensitySun = clamp(dot(normalize(realCameraNormal.xyz), normalize(vec3(0.0, 0.0, 1.0))), 0.0, 1.0) * sunFactor; float intensity = clamp(intensitySun + 0.2, 0.0, 1.0); outColor = texture(texImage, fTexCoords) * (vec4(intensity, intensity, intensity, 1.0) + calcLights(realNormal)); //outColor = texture(texNormal, fTexCoords); //outColor = 0.5 * (fWorldUVec + vec4(1.0, 1.0, 1.0, 0.0)); //outColor = vec4(fTexCoords, 1.0, 1.0); outColor.w = 1.0; } Here is the result of rendering an object, showing its normal render, the uvec, vvec, and texture coordinates (each commented out in the fragment shader code): Normal map itself: The uvec, as far as I can tell, should not be all over the place like it is; either this, or some other mistake, causes the normal vectors to be all wrong, so you can see on the normal render that for example there is a random dent on the left side which should not be there. As far as I can tell, my code follows the math from that tutorial. I use right-handed corodinates. So what could be wrong?

5. ## OpenGL suddenly won't draw buffers?

I think so too, but that shouldn't stop the model from being rendered.
6. ## OpenGL suddenly won't draw buffers?

I have changed it now and it still does not work. I'm sure the matrices are correct because it worked before.
7. ## OpenGL OpenGL suddenly won't draw buffers?

Hello, I was trying to solve this problem for the past 2 days and I really don't understand what's going on.   I have a Model class, which loads a list of vertices including their positions, texture coordinates, and normals (the normals are not used yet). The constructor for the class is as follows: Model::Model(const Model::Vertex *vertices, const int count) : vertexCount(count) { if (count == 0) { ApocFail("Empty model specified!"); }; if ((count % 3) != 0) { ApocFail("The specified model is not triangulated!"); }; GLint attrVertex, attrTexCoords, attrNormal; apocRenderHandler->getAttrLocations(attrVertex, attrTexCoords, attrNormal); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(Model::Vertex)*count, vertices, GL_DYNAMIC_DRAW); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(attrVertex); glEnableVertexAttribArray(attrTexCoords); //glEnableVertexAttribArray(attrNormal); glVertexAttribPointer(attrVertex, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Model::Vertex, pos)); glVertexAttribPointer(attrTexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Model::Vertex, texCoords)); //glVertexAttribPointer(attrNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Model::Vertex, normal)); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); cout << "GL error: " << glGetError() << endl; }; It also has a draw() function, which looks like this: void Model::draw() { glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, vertexCount); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); }; When the class is constructed, "GL error" is GL_NO_ERROR, but if i uncomment the line that loads normals, it is GL_INVALID_VALUE (I don't know if that should happen). Drawing also generates no error. However, the model (which is of a cube), does not appear on the screen. It has worked before, but stopped after I tried implementing an entity system, and I'm not sure why.   draw() is called between a glClear(), a texture binding, and a glFlush() (followed by swap windows). The context is created with SDL and GLEW.   The vertex shader: #version 150 uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjectionMatrix; in vec4 inVertex; in vec2 inTexCoords; in vec3 inNormal; out vec2 passTexCoords; out vec3 passNormal; void main() { passTexCoords = inTexCoords; passNormal = inNormal; gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * inVertex; }; The fragment shader: #version 150 uniform sampler2D uSampler; in vec2 passTexCoords; in vec3 passNormal; out vec4 outColor; void main() { outColor = texture(uSampler, passTexCoords); //outColor = vec4(1.0, 0.0, 0.0, 1.0); }; I am completely confused. All help appreciated :)
8. ## OpenGL doesn't draw triangle

Thank you, that answers everything   EDIT: Do I have to bind both the VBO and VAO before calling glDrawArray()? Or do I just need to bind the VAO?
9. ## OpenGL doesn't draw triangle

Thanks for the replies. I don't fully understand this though. If I create a VAO, and set up the vertex attributes with glVertexAttribPointer(), it tkaes the data from the currently-bound VBO, right? And before I call glDrawArrays(), do I have to bind into the VAO, or the VBO as well? And if I update the VBO, using glBufferData() or OpenCL, do those changes automatically affect the VAO, or do I have to create the VAO again?

11. ## GLSL 1.5 and Sending Vertices

I'm sorry, I tried upvoting your post and accidentally clicked the wrong thing and now i don't know how to reverse it -.- Unfortunately, votes are final immediately. I would definitely like to see some grace period though so silly mistakes like that can be corrected. I'll bump him up a step so the post doesn't show a -1 at least.   You use custom out variables in the fragment shader, just like the inputs to the vertex shader are custom in variables. The variable on location 0 goes to the primary render target, the variable on location 1 goes to the second render target, and so on. If you're not working with multiple render targets, then just define an out variable in the fragment shader and write to it.   Aaah, thanks, that makes sense. Thank you to everyone who helped :)
12. ## GLSL 1.5 and Sending Vertices

Thanks. That solved the problem.   I'm sorry, I tried upvoting your post and accidentally clicked the wrong thing and now i don't know how to reverse it -.-   If gl_FragColor is deprecated, then how do I tell the GPU what color the pixel should be??
13. ## GLSL 1.5 and Sending Vertices

I know about the coordinates. I just wanted to see if I'm sending more than one attribute properly.   I changed the last argument of glDrawArrays() to 3, but it still draws nothing :(
14. ## GLSL 1.5 and Sending Vertices

Thank you for helping guys. I attempted to use VBOs, but something doesn't work. I was attempting to (for now) draw a red triangle in orthographic mode on the screen. Here's the buffer creating code: int xValues[3] = {100, 40, 140}; int yValues[3] = {50, 70, 70}; GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo[2]; glGenBuffers(2, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(int), xValues, GL_STATIC_DRAW); glVertexAttribPointer((GLuint)0, 1, GL_INT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(int), yValues, GL_STATIC_DRAW); glVertexAttribPointer((GLuint)1, 1, GL_INT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glBindVertexArray(0); Then I draw as follows: glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 1); glBindVertexArray(0); My vertex shader: // gui.vert // The GUI vertex shader. // This software, including the source code, is release under the terms of // the License. #version 150 // vertex input in int in_x; in int in_y; void main() { float x = (float(in_x) / 320) - 1; float y = (float(in_y) / 240) - 1; gl_Position = vec4(x, y, 0.0, 1.0); }; My fragment shader: // gui.frag // The GUI fragment shader. // This software, including the source code, is release under the terms of // the License. #version 150 void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }; But the only thing I get is a black screen. Does anyone know what I'm doing wrong here?
15. ## GLSL 1.5 and Sending Vertices

Thank you, but I cannot seem to find any tutorial which shows how to use VBOs (yes, I'm trying to completely migrate to the new API). I did see somewhere on this forum that a person made a struct for holding each vertex and I believe this struct was treated as the only attribute. If I want to use this approach, can someone please post some example code for how I would create a VBO with this data and then draw? Thank you.